본문 바로가기
유니티 공부

RigidBody를 이용한 이동 AddForce와 Velocity (GetAxis)

by g-builder 2024. 10. 29.

유니티에서 오브젝트를 이동시키는데는 대표적으로 Transform을 사용하는것과 RigidBody를 사용하는것 2가지가 있다.

이번 포스트에서는 RigidBody에 대해 중점적으로 다룰 예정이므로 가볍게 Transform을 서술하자면

Transform 컴포넌트를 사용하여 오브젝트의 위치를 직접 수정하는 방식이다. Translate 메서드를 사용하거나 position 값을 직접 설정할 수 있다.

이 방식은 물리적인 계산을 고려하지 않고 위치를 단순히 이동시키기 때문에, 아주 간단한 이동이나 UI 오브젝트 이동 등에 유리하다. 하지만 충돌 판정이나 물리적인 효과는 반영되지 않는다.

 

그럼 이제 RigidBody를 사용해 이동하는것에 설명하자면 자주 쓰이는 방식으로는 AddForce로 힘을 주는것과 Velocity가 있다.

(예제에 들어가는 키값입력에는 InputSystem과 GetAxis가 있지만 InputSystem은 패키지를 받고 설정해줘야 하므로 GetAxis를 예시로 든다.)

AddForce

AddForce는 Unity의 Rigidbody에 힘을 가해 물체를 이동시키는 방법이다. 물리적인 힘을 통해 이동하기 때문에, 속도가 점진적으로 변화하고, 관성이나 마찰 등 물리적 요소가 반영되어 자연스러운 움직임을 제공한다.

ForceMode 옵션

AddForce에는 힘의 종류를 설정할 수 있는 네 가지 ForceMode 옵션이 있다. 각각 물체에 힘이 어떻게 작용할지 설정하는데, 이를 적절히 활용하면 더 다채로운 움직임을 구현할 수 있다.

  • ForceMode.Force: 지속적인 힘을 가해 일정 시간 동안 점진적으로 가속하도록 한다. 기본 설정이며 Time.deltaTime을 곱해 주어야 물체의 속도가 일정하게 변화한다.
  • ForceMode.Acceleration: ForceMode.Force와 비슷하지만, 질량을 무시하고 속도를 조절한다. 가볍게 반응해야 하는 물체나 질량에 관계없이 속도를 변화시키고 싶을 때 사용한다.
  • ForceMode.Impulse: 순간적으로 강한 힘을 가해 즉각적인 속도 변화를 일으킨다. 점프나 폭발 효과처럼 순간적으로 가해지는 충격을 구현할 때 유용하다.
  • ForceMode.VelocityChange: 현재 속도를 직접 변화시키며, 질량과 관계없이 즉각적으로 속도에 영향을 준다. 방향 전환이나 순간 이동 등에서 사용하기 좋다.

AddForce와 AddRelativeForce의 차이

  • AddForce는 월드 좌표계를 기준으로 힘을 적용한다. 즉, 항상 고정된 방향으로 힘이 가해진다.
  • AddRelativeForce는 로컬 좌표계를 기준으로 힘을 가한다. 캐릭터의 회전 방향에 따라 앞뒤, 좌우로 힘이 적용되므로, 자전거가 전진할 때나 캐릭터가 바라보는 방향으로 힘을 가할 때 유용하다.

사용예제

1
2
3
4
5
6
Rigidbody rb = GetComponent<Rigidbody>();
float forcePower = 10f;
 
// ForceMode 옵션에 따라 다른 이동 구현 가능
rb.AddForce(Vector3.forward * forcePower, ForceMode.Impulse); // 순간적인 힘으로 이동
 
cs
1
2
3
// 전진 방향으로 로컬 좌표계를 기준으로 힘을 가함
rb.AddRelativeForce(Vector3.forward * forcePower, ForceMode.Impulse);
 
cs

 

 

물론 키보드 입력을 받아 이동시킬 수 도 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using UnityEngine;
 
public class PlayerMovement : MonoBehaviour
{
    private Rigidbody rb;
    public float forcePower = 10f; // 힘의 크기 설정
 
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }
 
    void FixedUpdate()
    {
        // 키 입력 받기
        float horizontal = Input.GetAxis("Horizontal"); // 좌우 입력
        float vertical = Input.GetAxis("Vertical"); // 상하 입력
 
        // 입력에 따라 힘을 가할 방향 계산
        Vector3 moveDirection = new Vector3(horizontal, 0, vertical).normalized;
 
        // 방향에 따라 힘을 가함
        rb.AddForce(moveDirection * forcePower, ForceMode.Force);
    }
}
 
cs

 

장점

  • 현실적인 속도와 감속 구현
    AddForce는 물리적인 힘을 통해 움직이므로, 현실적인 감속 및 속도 변화가 가능하다. 캐릭터가 움직이다 멈추거나 방향을 바꿀 때 자연스러운 감속 효과를 제공한다.
  • 관성과 마찰 효과 반영
    Rigidbody의 drag(공기 저항)과 angularDrag(회전 저항) 같은 물리적 요소가 적용되어 관성과 마찰 효과가 반영된다. 이를 통해 캐릭터가 움직일 때 실제 환경과 유사한 움직임을 구현할 수 있다.
  • 질량과 중력의 영향
    AddForce는 Rigidbody에 적용된 질량과 중력의 영향을 받으므로, 더 무거운 물체일수록 속도 변화가 느리고 가벼운 물체일수록 더 민첩하게 반응한다. 이런 물리적 속성 덕분에 더욱 현실적인 움직임이 가능하다.

 

단점

  • 즉각적인 속도 변화 어려움
    AddForce는 물리적인 힘을 가해 점진적으로 속도를 변화시키기 때문에, 순간적으로 빠른 반응을 요구하는 경우에는 적용하기 어렵다. 힘이 가해질 때 속도가 서서히 증가하므로 반응이 느리게 느껴질 수 있다.
  • 예상치 못한 속도 증가 가능성
    AddForce는 힘을 지속적으로 가할 때 속도가 점점 누적되기 때문에, 반복적인 이동 명령 시 예상보다 빠른 속도 증가가 발생할 수 있다. 이를 관리하지 않으면 의도하지 않은 가속이 나타날 수 있다.
  • 부드러운 제어의 어려움
    이동 중 방향 전환이나 정밀한 조작을 요구하는 경우 AddForce는 다소 부드럽지 않게 느껴질 수 있다. 순간적인 방향 전환보다는 힘의 누적을 기반으로 하기 때문에 신속한 제어가 어려운 경우가 많다.

 

 

 

Velocity

 

Velocity는 Rigidbody의 현재 이동 속도를 나타내는 벡터 값이다. rb.velocity를 직접 설정하면 즉각적인 속도 변화를 줄 수 있어, 물리적인 힘보다 반응이 빠르고 제어가 용이하다. 이동 방향과 크기를 동시에 설정할 수 있어, 특정한 방향으로 캐릭터를 빠르게 이동시키는 데 자주 사용된다.

 

Velocity를 이용한 이동 특징

  • 직접적인 속도 제어: rb.velocity는 현재 속도를 설정하므로, 캐릭터가 즉각적으로 원하는 속도로 움직인다.
  • 지속적인 유지 필요: 속도는 계속 적용되어야 하며, 특정 상황(예: 중력)에서 유지되지 않는 경우도 있어 수동으로 반복 적용해야 한다.
  • 방향과 크기 조절 가능: rb.velocity는 이동 방향(벡터)과 크기(속도)를 동시에 설정하므로 이동을 직관적으로 제어하기 쉽다.


사용예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using UnityEngine;
 
public class PlayerMovement : MonoBehaviour
{
    private Rigidbody rb;
    public float speed = 5f;
 
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }
 
    void FixedUpdate()
    {
        // 오른쪽 방향으로 지속적인 속도 유지
        rb.velocity = Vector3.right * speed;
    }
}
 
cs

 

키보드 입력을 받는 사용예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using UnityEngine;
 
public class PlayerMovement : MonoBehaviour
{
    private Rigidbody rb;
    public float forcePower = 10f; // 힘의 크기 설정
 
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }
 
    void FixedUpdate()
    {
        // 키 입력 받기
        float horizontal = Input.GetAxis("Horizontal"); // 좌우 입력
        float vertical = Input.GetAxis("Vertical"); // 상하 입력
 
        // 입력에 따라 힘을 가할 방향 계산
        Vector3 moveDirection = new Vector3(horizontal, 0, vertical).normalized;
 
        // 방향에 따라 힘을 가함
        rb.AddForce(moveDirection * forcePower, ForceMode.Force);
    }
}
 
cs

 

장점

  • 즉각적인 반응성 제공
    velocity는 설정한 순간 바로 속도에 반영되므로, 반응 속도가 빠르다. 즉각적인 움직임이 필요한 상황에 유용하다.
  • 정밀한 이동 방향 및 속도 제어
    물리적인 힘 없이 정확하게 원하는 속도와 방향을 설정할 수 있어, 캐릭터의 움직임을 세밀하게 조절할 수 있다.
  • 쉬운 속도 조절
    물리 계산 없이 단순히 속도 벡터를 설정하므로, 다양한 속도와 방향을 코드로 쉽게 구현할 수 있다.

단점

  • 물리적 감속 및 관성의 부족
    물리적 힘이나 마찰 없이 속도를 조절하므로, 자연스러운 감속 효과나 관성을 구현하기 어렵다. 부드러운 물리적 움직임을 구현하기에는 부족하다.
  • 외부 힘과의 충돌
    다른 물리적 힘(예: 충돌이나 중력)과 함께 사용할 때 일관성을 유지하기 어려울 수 있다. velocity가 지속적으로 설정되면 외부 요인에 의한 속도 변화가 무시되기 때문에 물리적 충돌을 의도적으로 반영해야 하는 경우 관리가 복잡해질 수 있다.
  • 수동 감속 관리 필요
    이동 후 정지나 감속이 필요한 경우, 별도로 velocity 값을 줄이거나 추가 계산을 통해 감속 효과를 관리해야 한다.

 

 

결론.

AddForce는 물리적 사실감과 관성, 감속이 필요한 경우에 적합한 반면, 즉각적인 반응성과 세밀한 속도 제어에는 velocity가 더 적합하다.