[Unity] Input Action에서 IsPressed()와 started 이벤트 사용하기

박민주·2022년 1월 25일
0

Unity

목록 보기
15/40
post-thumbnail

유니티의 Input 클래스를 대신 Input Action 클래스를 사용해보려 한다

현재 사용하는 리듬게임 에셋에서는
입력 이벤트가 Input Action Asset을 통해 맵핑되어 있는데
내 플레이어 입력 처리 코드에서는 유니티의 Input 클래스를 썼었다

그랬더니 에셋에 맵핑된 키를 바꿀 때마다 코드를 수정해야 하는 문제가 있었다

Input Action : IsPressed()

처음에는 아래 코드와 같이 입력 이벤트에 대해 Input Action 클래스에서 지원하는 IsPressed()를 조건으로 썼다

// 유니티 예제 코드
var up = playerInput.actions["up"];
if (up.IsPressed())
   transform.Translate(0, 10 * Time.deltaTime, 0);

이전에 사용했던 Input.GetKeyDown()은 Update에서 사용하면 한 번 콜백되고 마는데
IsPressed()는 잠깐 눌렀는데도 한 동안 계속 true인 거 같았다,,

내 코드는 눌렀을 때 한 번만 콜백되어야 하므로 다른 방법을 찾아보았다

그러다가 인풋의 start, perform, cancel 시점에 이벤트를 등록할 수 있는 방법을 알게 되었다

Input Action : started

started / performed / canceled 라는 InputAction.CallbackContext 이다

https://docs.unity3d.com/Packages/com.unity.inputsystem@1.1/api/UnityEngine.InputSystem.InputAction.html

아래는 유니티 예제이다

action.started += context => Debug.Log($"{context.action} started");
action.performed += context => Debug.Log($"{context.action} performed");
action.canceled += context => Debug.Log($"{context.action} canceled");

위랑 똑같지만 나는 이런 식으로 사용했다

private InputAction inputAction_track1;
void Start()
{
	inputAction_track1 = inputHandlerInTrack.keyMapping[0].action; // 리듬게임 에셋에서 InputAction 받아옴
	inputAction_track1.started += context => { Attack(); }; // 콜백 이벤트 등록
}


(*참고용 사진: 리듬게임 에셋에서 지원하는 Input Action List)

Input Action Asset이 기존의 Input Class보다는 번거롭고 익숙치 않은 건 사실이지만
현재 게임에서 사용되는 Input을 관리하기에는 더 좋을 것 같기도 하다

특히 콜백을 등록할 수 있어서 어떤 키를 눌렀을 때 무슨 일이 일어나는지 파악하기에도 더 좋아보인다

그리고 예전에 Input Class 사용할 때에는 두 개 키 동시에 입력받는 걸 구현하기 번거로웠는데,
Input Action Asset 사용하면 더 깔끔해진다

두 개 키 동시에 입력받기

Input Class 버전

사실 상 사람이 한 프레임 안에 두 개 키를 정확히 동시에 누르는게 어렵기 때문에
아래와 같이 GetKey()와 GetKeyDown()을 사용하는 걸로도 모자라서
더 러프함을 주기 위해 else if 까지 해야했다

    void Update()
    {
        if(Input.GetKey(KeyCode.LeftArrow) && Input.GetKeyDown(KeyCode.RightArrow))
        {
            ComboAttack();
        }
        else if(Input.GetKeyDown(KeyCode.LeftArrow) && Input.GetKey(KeyCode.RightArrow))
        {
            ComboAttack();
        }
    }

Input Action Asset 버전

코드 자체는 더 길어졌다고 생각될 수도 있지만, if-elseif가 하나의 if문으로 줄었고,
ComboAttack()도 한 번만 호출하면 되고, 실제 코드 보기에도 훨씬 깔끔해졌다

    private bool isPressed_Track1 = false;
    private bool isPressed_Track2 = false;

    void Start()
    {
        inputAction_track1.started += context => { isPressed_Track1 = true; };
        inputAction_track2.started += context => { isPressed_Track2 = true; };
    };
    
    void Update()
    {
        // Track 1 & 2
        if (isPressed_Track1 && isPressed_Track2)
        {
            isPressed_Track1 = false;
            isPressed_Track2 = false;
            ComboAttack();
        }        
    };
    

참고

profile
Game Programmer

0개의 댓글