Unity

Unity 2D 캐릭터 움직임 주기

박도치 2023. 11. 27. 21:08

InputSystem 에 이어 캐릭터에게 움직임을 주도록 하자. 

 

일단 기본적으로 이벤트를 설정할 DungeonCharacterController 와 이를 new InputSystem과 연결하여 움직일 때 값을 받아 이벤트에 전달할 PlayerInputController 스크립트, 그리고 이벤트가 실행됐을 때 값을 넣어줄 DungeonMovement 세 가지 cs를 사용할 예정이다.

 

https://dochistory.tistory.com/93

 

New Input System

1. 개요 unity에서는 게임 플랫폼 환경마다 입력방식이 다른것을 고려해 New Input System이라는 것이 생겼다고 한다. 그래서 이번 포스트에서는 사용법과 세팅 방법에 대해 알아보도록 하자. 2. New Inpu

dochistory.tistory.com

 

newInputSystem에서 wsad로 방향키를 설정한 상태로 시작하도록 하자.

 

1. DungeonCharacterController 

최상위의 이벤트를 요청받아올 스크립트를 작성한다. public event Action으로 OnMoveEvent를 선언하여 함수가 작동할 때 불러오는 식이다.

 

public class DungeonCharacterController : MonoBehaviour
{
    public event Action<Vector2> OnMoveEvent; // OnMoveEvent시에 구독한 이벤트들을 불러옴
    public event Action<Vector2> OnLookEvent;
    public event Action OnJumpEvent;

    public void CallMoveEvent(Vector2 direction) //CallMoveEvent 메서드가 호출될 시에 작동
    {
        OnMoveEvent?.Invoke(direction);
    }

    public void CallLookEvent(Vector2 direction)
    {
        OnLookEvent?.Invoke(direction);
    }

    public void CallJumpEvent()
    {
        OnJumpEvent?.Invoke();
    }

}

 

이전 inputSystem에서 value값을 Vector2로 설정했기 때문에 Vector2를 파라미터로 받는다.

 

2. PlayerInputController

 

InputSystem의 경우 Sendmessage를 이용하면 Action의 이름앞에 On을 붙여 호출할 수 있다.

 

이전에 Move라는 Action의 이름으로 생성했기 때문에 OnMove를 사용하면 버튼을 누를 때 마다 OnMove가 호출되는 식으로 사용할 수 있다.

 

public class PlayerInputController : DungeonCharacterController
{
    private Camera _camera;

    private void Awake()
    {
        _camera = Camera.main;
    }

    public void OnMove(InputValue value)
    {
        Vector2 moveInput = value.Get<Vector2>().normalized;
        CallMoveEvent(moveInput);
    }
    
    //OnLook, OnJump 등은 생략
    
}

 

moveInput에 nomalized를 주는 이유는 위 아래 좌 우 값이 다 1인데 대각선의 경우 루트 2의 값이 나오기 때문에 더 빠른 속도가 되어버린다. 그래서 이를 같은 속도로 주기위해 nomalized 를 붙여주도록 한다.

 

그리고 해당 값을 CallMoveEvent에 전달하게 되면, OnMove가 작동할 때 마다 즉, 방향키를 누를 때 마다 CallMoveEvent가 호출되어 그 호출된 메서드가 작동하면 구독된 이벤트들이 작동하게된다. 이렇게하면 움직임을 주는 어떠한 행동들 모두 구독을 걸어놓으면 움직일 때 다양한 것들을 한곳에 모을 수 있다는 장점이 있다.

 

3. DungeonMovement

 

위와 같이 다 했다면 이제 움직일 때 이동속도와 값을 주어 캐릭터를 움직이게 해줘야한다. 그 코드들은 아래와 같다.

 

public class DungeonMovement : MonoBehaviour
{
    private DungeonCharacterController _controller;
    
    [SerializeField] private float speed = 5f;

    private Vector2 _movementDirection = Vector2.zero;

    private Rigidbody2D _rigidbody;
    
    private void Awake()
    {
    	// 해당 컴포넌트를 가져온다.
        _controller = GetComponent<DungeonCharacterController>();
        _rigidbody = GetComponent<Rigidbody2D>();
       
    }

    private void Start()
    {
    	// OnMoveEvent가 작동하면 Move함수를 전달
        _controller.OnMoveEvent += Move;
    }

    private void FixedUpdate()
    {
        ApplyMovement(_movementDirection);
    }

	//direction값을 _movementDirection 에 담는다.
    private void Move(Vector2 direction)
    {
        _movementDirection = direction;
    }

	// 스피드 값과 가져온 값을 곱한 후, 그 값을 rigidbody 에 velocity 에 준다. 
    private void ApplyMovement(Vector2 direction)
    {   
        direction = direction * speed;
        _rigidbody.velocity = direction;
    }

}

 

이벤트가 발생하게 되면 Move메서드가 작동하고, OnMoveEvent에서 받아온 값을 _movementDirection에 담아주고 ApplyMovement() 메서드에 전달한다. 받아온 값을 지정해둔 speed와 곱하여 _rigidbody.velocity를 설정해준다.

 

여기서  _rigidbody.velocity 값을 주게된다면 관성이나 질량 등 방해받는 속도를 무시하고 오로지 입력받은 속도로 설정이 된다. 만약 설정을 하지않게 된다면 약간 묵직하면서 멈출때도 미끄러지듯이 멈추기 때문에 특이한 경우가 아니고서는 값을 담아주도록 하자.

 

스크립트를 다 완료되었다면 Add Component를 자신의 Player에 전달해주면 캐릭터가 잘 움직이게 된다.

 

4. 몰랐던 내용

공부하면서 _rigidbody.velocity의 역할을 잘 몰랐는데 정리하면서 찾아보고는 이해가 되었다. 그리고 흐름도에 대해 어려움을 느꼈지만, 어느정도는 흐름이 보이기 시작한듯하다. 완벽하게 알기위해 열심히 노력하도록 하자.

 

'Unity' 카테고리의 다른 글

[Unity] 벡터 및 계산  (0) 2023.11.29
[Unity] GameManager 를 통해 Scene 아이디 주고받기 (TextMeshPro)  (4) 2023.11.28
New Input System  (3) 2023.11.24
[C#] 알고리즘 약수의 개수와 덧셈  (2) 2023.11.24
[C#] base 생성자  (0) 2023.11.17