오늘 한 일
- 챌린지반 과제 풀이
- 팀 프로젝트 진행하기 ( 볼륨 슬라이더 구현, 더블탭 대쉬 구현 )
- Input System에 대해서 자세히 파고 들기
오늘은 입력의 처리를 받는 Input System에 대해서 알아보자.
유니티에서 기존 Input Manager의 단점을 해소하고 확장성 있게 개량한 입력 처리 기능이다.
장점
- Cross-Platform Compatibility
New Input System은 다양한 플랫폼과 입력 장치에 대해 일관된 방식으로 작동합니다.- Rebinding
플레이어가 게임 내에서 자신의 입력 설정을 변경할 수 있도록 지원합니다.- Multiplayer Support
여러 플레이어가 동일한 장치에서 게임을 플레이하거나, 각각의 장치에서 게임을 플레이할 때 입력을 쉽게 처리할수 있습니다.
- 설치 후 프로젝트를 재시작해줘야한다.
- 생성하고자 하는 곳에 오른쪽 클릭 후 Create -> Input Actions를눌러 추가한다.
3-1. Control Shceme
- 각종 입력 장치에 대한 종류를 구분하는 것으로 추가해두면 Action을 설정에서 사용한다.
- 필수적인 과정은 아니지만, 혹시나 컨트롤러에 대한 구분이 필요할 경우에는 해두는 것이 좋다
- 해당 컨트롤러 스킴을 설정해두면 Player Input에서 설정해줄 수 있다.
- Any로 설정해두면 컨트롤 스킴 상관없이 처리한다는 의미이다. 혹여나 다양한 컨트롤러를 지원하고 싶다면 Any로 설정해두고 Auto-Switch를 켜두는 게 좋다.
3-2. Action Map
- 특정 개체(Player 등)나 기능(UI)단위로 구별해둔 Action 리스트로 주로 관련된 것끼리 묶어줘서 컴포넌트에 전달할 때 사용된다.
- 아래 이미지를 보면 +를 통해서 Map을 추가해줄 수 있다.
- InputAction 컴포넌트로 가보면 구별해놓은 Action Map 설정들을 고를 수 있다.
- 여기서 None으로 설정해버리면 아무 액션도 받지 않겠다는 의미이다;
(근데 유니티에서 필요한 것을 알아서 찾아가는 것 같다.) //굳이 None으로 설정해두지는 말자
3-3. Action
- 특정 행동의 입력 처리를 설정하는 걸로 주로 처리받을 값과 입력 처리를 관리하는 곳이다.
- Move를 선택한 상태로 오른쪽을 보면 ActionType과 Control Type을 설정할 수 있다.
Action Type
입력에 따른 이벤트 트리거를 설정하는 곳으로 기능의 요구 사항에 맞게 설정해주면 좋다.
- Value - 기본적인 액션 타입으로 컨트롤의 상태가 지속적으로 변하는 모든 입력에 대해서는 이를 사용한다.
- Button - 주로 누를 때마다 한번씩 액션을 트리거하는 입력에 사용하는 것이 좋습니다.
- Pass-Through - 바인딩된 모든 컨트롤의 변경 사항이 해당 컨트롤의 값을 가진 콜백을 트리거합니다. 이는 컨트롤 세트로부터 모든 입력을 처리하려는 경우에 유용합니다.
Control Type
트리거한 이벤트에 전달할 매개변수 종류를 지정하는 곳이다.
- 아래 이미지가 해당하는 매개변수들의 종류이다.
3-4. Binding
- 해당 액션에게 키입력을 넣어주는 과정이다.
- 3-4-1. 해당 액션에 오른쪽 클릭을 눌러 추가하거나, +를 통해 추가해줄 수 있다.
- Value Any가 아니고서야는 오른쪽 클릭으로 추가해주는 게 편할 것이다.
- 3-4-2. 해당 Binding을 눌러서 Path에서 키를 추가해주면 된다.
- 왼쪽에 매우 작은 상단바를 눌러주면 입력을 감지해주는데 넣고 싶은 키를 입력하면 감지해줘서 선택 가능할 수 있다.
- Add Component에서 Player Input를 찾아 추가해주자
- Player Input에 만들어두었던 Input Action Asset을 넣어주자
Behavior 설정
- 주로 메시지의 범위나 메시지를 전달하는 방식을 정해주는 곳이다.
InputValue value
- Send Messages : 동일한 게임 오브젝트의 컴포넌트에 메시지를 날린다.
- BroadCast Messages : 같은 게임 오브젝트와 그 자식 게임 오브젝트의 컴포넌트에 메시지를 날린다.
(성능 문제 때문에 추천하지 않는다)
InputAction.CallbackContext context (더 자세한 이벤트 처리 가능)
- Invoke Unity Event : OnClick처럼 Unity Event형태로 관리된다. (매우 편리하다)
- Invoke C Sharp Events : PlayerInput.OnActionTriggered에 호출하고 싶은 이벤트 등록해서 어떤 이벤트인지 확인해서 쓸 수 있다.
- 요구되는 네임스페이스
using UnityEngine.InputSystem
SendMessages 또는 BroadCast Messages일 경우
- 아래 이미지에 적힌 함수를 적어서 호출해줘야한다.
private void OnMove(InputValue value) // 접근 제한자 제한이 없다. { Vector2 direction = value.Get<Vector2>(); // 값을 가지고 올 때는 .Get<>();을 활용한다. CallMoveEvent(direction); } // Value Any일 경우에는 (주로 bool값 매개변수 전달에 사용된다.) value.isPressed; // interaction이 없는 상태에서 키를 눌렀을 때 true 뗐을 때false를 반환한다.
Invoke Unity Event일 경우
- Events/ActionMap을 열어 거기에 해당하는 메서드를 추가해줘야한다.
public void OnDash(InputAction.CallbackContext context) // 사용을 위해서는 반드시 public 이상이어야 한다. { if (context.started) { // 입력 시작 시 (주로 키입력이 시작됐을 때 발동) } if (context.performed) { // 조건 충족 시 (인터랙션의 조건이 충족되었을 경우) } if (context.canceled) { // 조건 미충족 시 또는 취소 시 (조건 충족 후 키를 떼거나 조건이 충족되지 못했을 시) } } // 위와 같은 자세한 설정이 가능한데 해당 조건에 따라서 필요한 기능을 넣어주면 된다.
Invoke C Sharp Events는 사용한 적이 없기에 넘어간다..
키에 추가적인 조건을 걸어줘서 키를 누르고 일정 시간이 충족되고 나서 떼야 호출되는 경우나 연속으로 키를 눌러야 호출되는 등의 다양한 조건들을 걸어줄 수 있다.
공통된 설정
Press Point - 이벤트가 호출되기 위한 임계값으로 사실 키보드 같은 경우에는 키 입력이 들어오기만 하면 1로 판정이 되서(하나만 누르든 동시에 누르든 간에) 키보드에서 쓰이기보다는 조이스틱이나 게임 패드에 주로 사용된다.
Hold | 꾸욱 눌러줘야 호출하는 상호작용
Hold Time : 첫 활성화부터 얼마 이상의 활성화를 유지해야 호출되는 지를 설정한다.
Multi Tap | 여러번 눌러줘야 호출하는 상호작용
Tap Count : 몇 번까지 눌러줘야 호출되는 지를 설정
Max Tap Spacing : 키 입력이 시작되고 나서 비활성화 상태에서의 허용 시간
Max Tap Duration : 활성화 상태에서의 키 유지를 허락하는 시간 (넘어가면 취소된다.)
Press | 눌렀을 때, 뗐을 때 호출할 지의 상호작용
Press Only : 눌렀을 때 호출
Release Only : 뗐을 때 호출
Press & Release : Press + Release를 합친 것이다.
Slow Tap
Min Tap Duration : 키를 누르고 최소 유지 시간 이후 뗐을 때 호출되는 시간을 정한다.
Tap
Max Tap Duration : 키를 누르고 최대 유지 시간 이전에 뗐을 때 호출되는 시간을 정한다.
사실 오늘 작성하는 것보다 Input Action을 활용한 더블탭 대쉬를 넣으려고 하다가 MultiTap의 performed 조건이 Tap Count 충족에서 눌렀을 때가 아닌 누르고 뗐을 때라는 점에서 많이 난감했지만, 오히려 왜 굳이 InputAction에 의존해야하는 생각을 해서 코드로 하면 좀 더 쉽고 간단히 짤 수 있을 거라는 생각을 하게 되었다. 그래서 InputAction을 활용하지 않고 스크립트 내에서 그대로 처리했더니 도리어 InputAction을 활용했던 것보다 코드가 좀 더 간결해지고 빈틈 없이 작성할 수 있게 되었다. 이런 점을 생각해보면 이러한 기능들 이전에 결국 코드를 설계하고 짜는 그러한 기본 바탕들이 제일 중요하다는 걸 알게 되었다.