본문 바로가기
스파르타 내배캠

스파르타 내배캠 Unity 3기 29일차

by LemongO 2024. 2. 1.

그런거였어???

 

 

오늘 특강 내용 중 일부는 예전에 독학할 땐 영상을 몇 번을 돌려봐도 이해가 안 됐던 것들...

이번 특강에서 이해 해버렸다. 그 강의도 다시 봐야겠는걸?

 

 

 


InputSystem... 근데 Unity Events 를 곁들인

 

저번에 TIL로 작성을 했던 주제이지만 이번엔 강의에서 이벤트를 호출하는 방식이 

SendMessage 방식에서 InvokeUnityEvents 로 바뀌어서 다시 쓴다.

사실 SendMessage가 성능면에서 많이 안 좋다고 들었기 때문에 배우면서도 찜찜했는데 잘 됐다.

 

 

뭔가 좀 많아졌지만 아무튼 액션 이름 정하고 키 바인딩 했을 뿐 맥락은 똑같다.

 

Behavior 가 Invoke Unity Events 로 바꼈다!

이번엔 Player의 움직임을 PlayerController 로 모두 해결한다.

 

코드가 조금 기니 기능별로 잘라서 보도록 하자.

 

using UnityEngine.InputSystem;

먼저 InputSystem을 사용하기 위해 using 선언을 하도록 하자.

 

[Header("Movement")]
public float _moveSpeed;    
public float _jumpForce;
public LayerMask _groundLayerMask;

private Vector2 _curMovementInput;

움직임에 쓰일 변수들이다.

 

이동속도, 점프파워, 땅임을 감지할 LayerMask 가 있다. 

오늘 TIL에선 이동만 다룰 것이다.

 

그리고 현재 움직이는 방향을 받을 Vector2 가 있다.

 

private Rigidbody _rigidbody;

public static PlayerController Instance;

private void Awake()
{
    Instance = this;
    _rigidbody = GetComponent<Rigidbody>();
}

velocity 로 이동을 할 것이기 때문에 Rigidbody를 가지고 있고

외부에서 바로 접근할 수 있도록 PlayerController 를 static 으로 가지고 있도록하자.

 

private void FixedUpdate()
{
    Move();
}

private void Move()
{
    Vector3 dir = transform.forward * _curMovementInput.y + transform.right * _curMovementInput.x;
    dir *= _moveSpeed;
    dir.y = _rigidbody.velocity.y;

    _rigidbody.velocity = dir;
}

FixedUpdate 에서 Move 함수를 호출해주고

Move 함수에선 실제로 움직여질 로직을 작성해준다.

 

transform.forward 는 (0, 0, 1) 과 같다.

 

전역변수 Vector2 _curMovementInput 의 y 값을 곱한다.

(Vector2 로 받기때문에 w키 입력시 Vector2 의 y 좌표가 반환되는 액션이므로 y값을 곱해준다.)

 

transform.right 는 (1, 0, 0) 과 같다.전역변수 Vector2 _curMovementInput 의 x 값을 곱한다.

 

방향 (dir) 을 알았으니 _moveSpeed 를 곱하여 이동속도를 적용한다.

 

dir.y = _rigidbody.velocity.y 를 하는 이유는 위의 계산을 했을 때 나오는 결과값이 (x, 0, z) 이다.저대로만 계산하면 점프를 해도 y 축 이동은 0으로 고정되어 점프가 정상적으로 작동하지 않는다.

 

velocity = dir 로 속도를 준다.

 

 

이동 로직은 작성했으니 이제 방향인 _curMovementInput 을 받아야 한다.

어디서 받을까?

 

public void OnMoveInput(InputAction.CallbackContext context)
{
    if(context.phase == InputActionPhase.Performed)
    {
        _curMovementInput = context.ReadValue<Vector2>();
    }
    else if(context.phase == InputActionPhase.Canceled)
    {
        _curMovementInput = Vector2.zero;
    }
}

public으로 OnMoveInput 함수를 작성한다. 이 함수가 InputSystem 으로 호출할 함수다.

여기서 저번과 다른 점은 입력값을 받을 때 매개변수로 InputAction.CallbackContext 를 받는다는 것이다.

그리고 Key Down & Up 등을 조건으로 나뉘어 받을 수 있다.

 

입력값을 받을 매개변수 InputAction.CallbackContext

 

context.phase 로 입력 상태를 조건별로 나눌 수 있다. Debug.Log 로 확인 결과 다음과 같다.

Performed 는 KeyDown 이다.

Cancled 는 KeyUp 이다.

위 정보는 틀렸다. 다음 포스팅을 확인해보자.

https://lemongo.tistory.com/30

 

입력값을 받아오는 방법은 ReadValue<타입>() 을 사용하여 받아올 수 있었다.

 

Performed 일 때, 키 입력값을 받아 방향을 _curMovementInput에 할당한다.Canceled 일 때, 방향을 Vector2.zero 로 없애준다.

 

 

코드는 작성을 다 했다. 그럼 이걸 어디서 호출할까?

 

Move 외에도 지정했던 Action들이 다수 보인다.

 

이번엔 코드에서 다 처리하는 방식이 아닌 Inspector 에 이벤트들을 드래그 드롭으로 등록하는 방식을 썼다.

코드로도 하는 방법이 있을 듯한데...

너무 코드가 길어지고 비효율적 이었던 걸까?

다음에 한 번 찾아봐야겠다.

 

암튼 잘 된다