유니티의 Input 클래스를 대신 Input Action 클래스를 사용해보려 한다
현재 사용하는 리듬게임 에셋에서는
입력 이벤트가 Input Action Asset을 통해 맵핑되어 있는데
내 플레이어 입력 처리 코드에서는 유니티의 Input 클래스를 썼었다
그랬더니 에셋에 맵핑된 키를 바꿀 때마다 코드를 수정해야 하는 문제가 있었다
처음에는 아래 코드와 같이 입력 이벤트에 대해 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 시점에 이벤트를 등록할 수 있는 방법을 알게 되었다
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 사용하면 더 깔끔해진다
사실 상 사람이 한 프레임 안에 두 개 키를 정확히 동시에 누르는게 어렵기 때문에
아래와 같이 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();
}
}
코드 자체는 더 길어졌다고 생각될 수도 있지만, 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();
}
};