Unity 1 - PlayerMovement
unity에서 object를 움직이는데는 크게 두 가지 방법이 있다. 해당 Rigidbody2D의 position을 직접 설정한 값 만큼 추가, 변경하는 것과 물리 엔진을 이용해 해당 Rigidbody2D의 속도 등을 조절하여 움직이는 방법이다.
1. MovePosition (해당 오브젝트의 좌표자체를 변경하여 이동)
Public class PlayerMovement : Monobehaviour{
public float movespeed=5f;
public Rigidbody2D rb;
Vector2 movement;
void Update(){
movement.x=Input.GetAxisRaw("Horizontal");
movement.x=Input.GetAxisRaw("Horizontal");
}
void FixedUpdate(){
rb.MovePosition(rb.position+movement*movespeed*Time.fixedDeltaTime);
}
}
첫 번째 방법인 해당 오브젝트의 좌표 자체를 바꾸는 방법이다. 매 프레임마다 wasd 혹은 방향키의 값을 받아 Vector2에 저장한다. 이후 그 값과 속도를 곱한 만큼을 매 정해진 프레임마다 원래 위치에 더해 이동을 실행한다.
2. rb.velocity=movespeed*dir; (해당 오브젝트의 물리 엔진을 통해 이동)
public class PlayerMovement : MonoBehaviour{
public float movespeed=5f;
public Rigidbody2D rb;
private void Update() // processing inputs -> Time.deltaTime
{
Vector2 dir = Vector2.zero;
if (Input.GetKey(KeyCode.A))
{
dir.x = -1;
animator.SetInteger("Direction", 3);
}
else if (Input.GetKey(KeyCode.D))
{
dir.x = 1;
animator.SetInteger("Direction", 2);
}
if (Input.GetKey(KeyCode.W))
{
dir.y = 1;
animator.SetInteger("Direction", 1);
}
else if (Input.GetKey(KeyCode.S))
{
dir.y = -1;
animator.SetInteger("Direction", 0);
}
dir.Normalize();
rb.velocity = movespeed * dir;
}
}
두 번째 방법인 해당 오브젝트의 속도를 바꿔 이동하는 방법이다. wasd 입력에 따라 Vector2 dir의 x,y값을 변경하고, 해당 값과 속도를 곱한 벡터를 속도 벡터로 설정하는 방법이다.
두 방법은 오브젝트의 Rigidbody2D의 Body Type을 무엇으로 설정했느냐에 따라 동작한다. unity Rigidbody2D의 Body Type은 Static과 Kinematic, Dynamic의 세 종류가 있다. Static은 말 그대로 고정된 배경에 사용하며 할당된 실제 rigidbody가 없는 것과 비슷하다. 따라서 물리엔진은 해당 오브젝트를 움직이지 않는 것으로 취급한다. 때문에 onTrigger나 OnCollision 등은 작동하지 않는다. Kinematic은 Script를 통해 조정할 수 있는 오브젝트이다. 다른 kinematic이나 dynamic object와 충돌한다. Dynamic은 온전히 게임 엔진(물리 엔진)에 의해 움직인다. 따라서 힘이나 속도 등의 값에 의해 이동하며 엔진이 자동으로 다른 dynamic 및 kinematic, static object와의 충돌 등을 계산한다.
따라서 moveposition을 이용한 이동 방법은 kinematic, dynamic 모두에 사용 가능하지만, velocity를 이용하는 방법은 kinematic 오브젝트에 대해 사용 불가능하다.(아무런 영향이 없다) 다만 moveposition 방법 역시 dynamic 오브젝트의 엔진 값과 script에서 설정한 값이 서로 다를 경우 충돌이 발생할 수 있다.
* Update(){}와 FixedUpdate(){}의 차이점 : Update() 함수는 해당 기기의 프레임 레이트에 따라 실행되므로 기기 성능에 따라 결과가 차이날 수 있다. FixedUpdate()는 정해진 프레임(기본값 50)마다 함수를 실행하므로 일정한 텀으로 실행된다는 차이점이 있다.
따라서 Update() 함수는 일반적으로 input을 받고, FixedUpdate() 함수에서 받은 input을 physically 처리하는데 사용한다.
*GetAxisRaw와 GetKey : GetAxisRaw는 해당 프로젝트에 저장된 키바인드를 사용하여 눌린 값을 -1,0,1로 반환해준다. 기본값은 wasd와 방향키이다. (edit - projectsetting - inputmanager) Getkey는 반대로 해당 키 값이 눌렸는지 반환한다. 따라서 내가 해당 키가 눌렸을 경우 원하는 vector값을 어떻게 설정해줄 것인지 추가로 작성하여야 한다.
*script에서 public으로 설정한 값은 unity 내부의 inspector에서 변경가능하다. 특히, 위의 스크립트를 실행하려면 Rigidbody2D rb에 해당 오브젝트의 rigidbody를 드래그로 넣어주어야 작동한다. 이렇게 하지 않고 해당 오브젝트가 가지는 Rigidbody2D를 GetComponent로 바로 받아올 수도 있다.
*Top-down view 2d의 경우 Gravity scale은 0으로 설정해야 아래로 떨어지지 않으며, 충돌 시의 회전을 막기 위해 constraint의 freeze rotation of z는 항상 체크해야 한다.
댓글
댓글 쓰기