본문 바로가기
유니티/기초

유니티 캐릭터 점프 [기초 6]

by 노튜 2020. 9. 13.
728x90

 

유니티에서 물리적인 힘을 적용하여 캐릭터 점프를 구현한다.

 

물리적인 힘은 Rigidbody를 통해 구현된다. 

물리적인 충돌 및 게임 오브젝트 간의 충돌 감지는 Collider를 통해 구현된다. 

 

1. 준비

대상 오브젝트에 Rigidbody와 Collider 컴포넌트를 추가한다. CharaterControl 클래스를 만들고 점프를 구현할 대상 오브젝트에 등록한다.

 

Plane을 추가하고 Scale *10으로 하여, 지면을 구현한다.  트랜스폼의 Scale 값은 (10, 0, 10)이다. 지면을 생성하지 않으면, 게임 오브젝트가 추락하게 된다. Plane은 대상 오브젝트보다 아래(Y축)에 위치하도록 한다. 트랜스폼의 Position 값은 (0, -1.0, 0)이다. 물리 충돌을 구현하기 위해서는 Plane도 Collider 컴포넌트가 추가된 상태여야 한다.   

2. 점프 구현

Space 키를 누르면 대상에 힘을 가하도록 구현한다. 

아래의 두 개의 코드는 동일한 역할을 한다. GetButtonDown()은 매개변수를 string 타입, GetKeyDown()은 매개변수를 Keycode 타입을 사용한다. 

Edit → Project Settings InputManager 에서 확인 및 수정할 수 있다.

1. Input.GetButtonDown("Jump") 
2. Input.GetKeyDown(KeyCode.Space)

 

시작하게 되면, 게임 오브젝트에 추가한 Rigidbody 컴포넌트의 인스턴스를 얻는다.

에디터 뷰에서 수정이 가능하도록 실수형 변수 force를 public으로 생성한다. 

사용자로부터 키 입력을 받으면, 대상 오브젝트에 Y축 방향으로 힘을 가하도록 구현한다.

Vector3(0, 1.0f, 0) * 100만큼 힘을 가한다.  

public class CharacterControl : MonoBehaviour
{
  // 물리
  Rigidbody rigidbody;
  
  public float force = 100.0f;  
  
  void Start()
  {
    // 힘을 가하기 위해 게임 오브젝트에 추가된 Rigidbody 컴포넌트의 인스턴스를 얻는다.
    rigidbody = GetComponent<Rigidbody>();    
  }
    
  void FixedUpdate()
  {
        
        if (Input.GetButtonDown("Jump"))
        {
            rigidbody.AddForce(new Vector3(0, 1.0f, 0) * force);
        }        
  }
}

 

3. AddForce()

오브젝트에 힘을 가할 때에는 Rigidbody의 AddForce()를 사용한다. 

Rigidbody.Addforce(force)
Rigidbody.Addforce(force, ForceMode)

 

Addforce()를 이용할 때 몇 가지 포스 모드를 사용해 대상 오브젝트에 물리적인 힘을 가할 수 있다.

AddForce의 기본 모드는 ForceMode.Force이다. Addforce()의 첫 번째 매개변수는 Force 값이다. 두 번째 매개변수로, 포스 모드를 설정할 수 있다. 두 번째 매개변수를 입력하지 않으면, ForceMode.Force이다.

FroceMode.Force는 현실세계의 물리 법칙을 적용할때에 주로 사용된다. ForceMode는 enum 클래스이며 Forcemode.Type을 대입한다.

 

ForceMode는 다음과 같다.

  • Force : 질량을 사용, 연속적인 힘을 가하는 경우
  • Acceleration : 질량을 무시, 가속력을 가하는 경우
  • Impulse : 질량을 사용, 짧은 순간 힘을 가하는 경우 
  • VelocityChange : 질량을 무시, 속도 변화를 짧은 순간에 적용하는 경우

순간적인 힘을 가하여, 게임 오브젝트를 +Y축으로 이동시킨다. 매개변수로 ForceMode.Impulse를 입력한다.

public class CharacterControl : MonoBehaviour
{
  // 물리
  Rigidbody rigidbody;
  
  public float force = 10.0f;  
  
  void Start()
  {
    // 힘을 가하기 위해 게임 오브젝트에 추가된 Rigidbody 컴포넌트의 인스턴스를 얻는다.
    rigidbody = GetComponent<Rigidbody>();    
  }
    
  void FixedUpdate()
  {
        rigidbody.velocity = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0)
        * moveSpeed * Time.fixedDeltaTime;
  
        if(Input.GetKeyDown(KeyCode.Space))
        {
          rigidbody.AddForce(Vector3.Up * force, ForceMode.Impulse);        
        }
  }
}

 

 

각 모드는 계산 공식이 다르다. Force와 Impulse를 예로 들어 점프를 구현하면, 질량 1인 오브젝트에 Impulse는 10의 힘을 가하면, 대상 오브젝트는 튀어 오른다. Force는 더 많은 힘을 가해야 대상 오브젝트를 위로 이동시킬 수 있다. 실제 이러한 차이는 대상 오브젝트에 물리를 가하는 계산 공식이 다르기 때문이다. 실제 현실과 같은 게임 월드를 구현하거나, 가상의 세계를 프로젝트에 맞게 구현하기도 한다. 각각의 프로젝트는 힘을 가하는 방식이 다를 수밖에 없다. 

 

각 모드의 계산 공식은,

  • Force : mass * distance / time^2  
  • Acceleration : distance / time ^2 
  • Impulse : mass* distance / time^2
  • VelocityChange : distance / time 

 

Forcemode 사용은 AddForce()에 포스 모드를 추가하면 된다.

AddForce()의 첫번째 매개변수(Parameter)는 힘의 크기(Vector3)이며, 두 번째 매개변수가 포스 모드이다. 

Rigidbody.AddForce(Vector3, ForceMode.Mode )

 

여기에 추가적으로 다음의 표를 확인하면 도움이 될 것이다. 

Impulse와 Force는 가하는 힘의 크기에 Mass를 사용한다. Mass가 커질수록 대상 오브젝트에 가하기 위해, 필요한 힘의 크기가 더 많이 요구된다. Impulse와 VelocityChange는 순간적으로 1 frame에 힘을 가한다. Force와 Acceleration은 1초 동안 지속적으로 가한다. 이러한 차이점은 각 포스 모드에 따라, 다른 결과를 도출한다.

 

차임점   (출처 : 아래 참조의 gillemp님의 Reply)

 

 

 

 

 

 

 

참조

 

 

https://docs.unity3d.com/ScriptReference/ForceMode.html

 

Unity - Scripting API: ForceMode

The AddForce function impacts how your GameObject moves by allowing you to define your own force vector, as well as choosing how to apply this force to the GameObject (this GameObject must have a Rigidbody component attached). ForceMode allows you to choos

docs.unity3d.com

 

 

https://answers.unity.com/questions/696068/difference-between-forcemodeforceaccelerationimpul.html

 

Difference between ForceMode.Force/Acceleration/Impulse/VelocityChange? - Unity Answers

 

answers.unity.com

 

728x90