<InputManager>
Unity 작업시 기존부터 사용되어왔던 입력처리 패키지로 비교적 쉽게 사용가능하다는 장점이 있다.
*Inspect를 통한 간단한 키매핑
public KeyCode Up;
public KeyCode Down;
void Update()
{
movement = 0f;
if(Input.GetKey(Up)) { movement += 1f; }
if(Input.GetKey(Down)) { movement -= 1f; }
rigidbody.velocity = new Vector2(0, movement * speed);
}
InputManager를 이용하여 키 맵핑과 오브젝트 조작까지 동작하게하는 코드이다.
<InputManager 를 지양하게 된이유>
1.다양한 입력 장비 대응 : 현 게임시장은 다양한 플랫폼이 제공되고 있고 , 키맵핑도 매우 자유롭다.
하지만 InputManager는 해당 문제를 대응하기 부적절하다.
2.입력 처리와 실제 로직 실행주체의 분리의 목적
InputManager의 자체 문제는 아니지만, 기능 별로 class를 나누는 작업을 해야 유지 보수 및 확장성이 많이 상승한다.
-> OPP(객체지향프로그래밍) 에서 이런 설계 원칙을 단일책임원칙(SRP)라고 부름
위에 이렇게 단점이 있지만 실제로도 간단한 프로젝트를 만들때는 아직도 많이 사용된다.
<InputSystem>
위에 말한 InputManager의 단점을 극복하기 위해 새로 나온 패키지이다.
해당 패키지는 Unity 패키지에 포함되어있지 않기에 ProjectManager를 통해서 설치해야한다.
Input Action : 해당 동작에 대한 키를 맵핑 데이터를 모아두는 파일
Player Input 컴포넌트 : 자동으로 입력 행동을 처리하고 해당 게임 오브젝트에 메시지를 보내는 역할
Player Input의 Behaviour은 무엇인가?
해당 Input 입력 발생시 해당 게임 오브젝트에 메시지 보내는 여러 방식중 하나 라고 생각하면 된다.
해당 글음 참고하여 작성하였음
이름 | 특징 |
SendMessages | PlayerInput을 컴포넌트로 가지고있는 GameObject에 코드내용을 전달 MonoBehaviour 의 update,start와 같은 이벤트함수처럼 사용이 가능해짐 |
BroadCastMessages | PlayerInput을 컴포넌트로 가지고있는 GameObject와 그 자식들에게 코드내용을 전달 성능적인 면에서 하자가 있기에 잘 사용되진 않음 |
InvokeUnityEvents | UI의 button 컴포넌트처럼 Inspector 에서 Onclick() 이벤트 함수처럼 메서드를 추가해서 사용하는것 |
Invoke CSharp Events | 위의 기능과 비슷하지만 PlayerInput API에서 코드를 호출하여 사용이 가능하고 , inspector 표시되지 않고 오직 스크립트 코드로 동작한다. onActionTriggered (collective event for all actions on the player) onDeviceLost onDeviceRegained 해당 메서드들이 API에 등록되있다고 함 |
<InputSystem 사용>
Action Type 이름 : 입력을 어떻게 받을 것인지 | 설명 |
Value | 일반적인 상태에 사용함 , 눌렀을 때, 누르고 있을때, 뗄 떼 등 다양한 상황에 대응이 가능해짐 |
Button | 눌렀을때 발생하는 액션에 활용 되며 , Control 타입이 Button으로 고정 됨 |
Pass-Through | 명확화(Disambiguation)을 거치지 않은 Value. Value 쓰시면 됩니다. 입력이 들어오면 그 즉시 처리 되기에 중복 입력에 대한 필터링이 없음(액션 상태에 따른 시작,중지)가 이루어지지 않음 연속적인 입력 처리가 필요할때 주로 사용,동일한 입력에서 여러 프레임에 걸쳐 이벤트를 받을 수 있음 언제 사용하면 됨?? 축(axis)기반 입력이나 마우스의 움직임 , 복잡한 키 조합 : 축적된 입력을 매 프레임마다 처리해야 하는 경우 ex)조이스틱 축, 마우스 이동 -> 연속적인 입력으로 매 프레임마다 값을 처리해야함 ex2) 멀티 터치 입력 -> 여러 입력을 동시에 수집하고 처리해야됨, 중복입력 필터링이 없기에 모든 입력을 받음 |
<InputSystem 예제>
using UnityEngine.InputSystem;
public void OnMove(InputValue value)
{
Debug.Log("OnMove" + value.ToString());
Vector2 moveInput = value.Get<Vector2>().normalized;
CallMoveEvent(moveInput);
//실제 움직이는 처리는 여기서 작업하는게 아님
//PlayerMovement에서 작업을 하는것
}
public void OnLook(InputValue value)
{
//Debug.Log("OnLook" + value.ToString());
Vector2 newAim = value.Get<Vector2>();
//마우스 위치를 정규화 해버리면 제대로된 좌표가 반환되지 않음
Vector2 worldPos = _camera.ScreenToWorldPoint(newAim);//화면 좌표계에 있기에 월드 좌표로 변환
//벡터의 뺼셈으로 원하는 방향벡터를 계산
newAim = (worldPos - (Vector2)transform.position).normalized;
if (newAim.magnitude >= .9f)
{
CallLookeEvent(newAim);
}
}
수업 듣는 InputController의 구조를 살짝 떼왔다. Event Action으로 각 기능의 함수를 동작시키는 형태인데,
InputValue 타입의 변수 인자값을 받아 해당 동작에서 사용하는 간단한 예시이다.
하지만 게임 프로젝트 규모가 커질수록 Input Map들도 많아지게되며, map에 직접 접근해서 사용해야되는 경우가 존재한다.
ChatGPT - 참고 코드 : 사용시 꼭 읽어보고 사용할것
using UnityEngine;
using UnityEngine.InputSystem;
public class ActionMapSwitcher : MonoBehaviour
{
// InputActionAsset은 Unity의 Input Actions Asset 파일을 연결할 때 사용됩니다.
public InputActionAsset inputActions;
// Action Maps
private InputActionMap playerActionMap;
private InputActionMap uiActionMap;
private void Awake()
{
// InputActionAsset에서 각 Action Map을 가져옴
playerActionMap = inputActions.FindActionMap("Player");
uiActionMap = inputActions.FindActionMap("UI");
// Player Action Map에서 'Move' 액션을 가져와 이벤트 등록
InputAction moveAction = playerActionMap.FindAction("Move");
moveAction.started += OnMoveStarted;
moveAction.performed += OnMovePerformed;
moveAction.canceled += OnMoveCanceled;
// UI Action Map에서 'Navigate' 액션을 가져와 이벤트 등록
InputAction navigateAction = uiActionMap.FindAction("Navigate");
navigateAction.started += OnNavigateStarted;
navigateAction.performed += OnNavigatePerformed;
navigateAction.canceled += OnNavigateCanceled;
}
private void OnEnable()
{
// 기본적으로 Player Action Map 활성화
playerActionMap.Enable();
}
private void OnDisable()
{
// 비활성화 시 모든 액션맵을 비활성화
playerActionMap.Disable();
uiActionMap.Disable();
}
// 'Move' 액션 관련 콜백 함수들
private void OnMoveStarted(InputAction.CallbackContext context)
{
Debug.Log("Move started");
}
private void OnMovePerformed(InputAction.CallbackContext context)
{
Vector2 moveInput = context.ReadValue<Vector2>();
Debug.Log($"Move performed: {moveInput}");
}
private void OnMoveCanceled(InputAction.CallbackContext context)
{
Debug.Log("Move canceled");
}
// 'Navigate' 액션 관련 콜백 함수들
private void OnNavigateStarted(InputAction.CallbackContext context)
{
Debug.Log("Navigate started");
}
private void OnNavigatePerformed(InputAction.CallbackContext context)
{
Vector2 navigateInput = context.ReadValue<Vector2>();
Debug.Log($"Navigate performed: {navigateInput}");
}
private void OnNavigateCanceled(InputAction.CallbackContext context)
{
Debug.Log("Navigate canceled");
}
// Action Map 전환 예시
public void SwitchToUI()
{
// Player Action Map 비활성화
playerActionMap.Disable();
// UI Action Map 활성화
uiActionMap.Enable();
Debug.Log("Switched to UI Action Map");
}
public void SwitchToPlayer()
{
// UI Action Map 비활성화
uiActionMap.Disable();
// Player Action Map 활성화
playerActionMap.Enable();
Debug.Log("Switched to Player Action Map");
}
private void Update()
{
// 예시: Escape 키를 누르면 UI로 전환, 다시 누르면 Player로 전환
if (Keyboard.current.escapeKey.wasPressedThisFrame)
{
if (playerActionMap.enabled)
{
SwitchToUI(); // UI로 전환
}
else
{
SwitchToPlayer(); // Player로 전환
}
}
}
}
해당 코드는 게임내에서의 Player와 UI창의 키 맵핑을 다르게 하고 사용하는 모습이다.
Esc 키를 누르면 UI로 전환 한번 더 누르면 Player로 전환하는 방식이다.
결론 :
1.InputManager는 간단한 프로젝트 진행시 사용하기 좋다.
2.InputSystem은 규모가 커지고 다양한 플랫폼에 제공 및 키 맵핑 변경을 한다면 좋은 선택지이다.
3.InputSystem의 핵심 개념은 , InputAction , Input Action Asset , Player Input 컴포넌트 이 세가지이다.
InputAction : 프로젝트 창에서 생성 가능한 Input 맵핑 데이터가 있는 파일
Input Action Asset : 여러 개의 입력 행동을 그룹화하는 방법, InputAction을 열면 설정창에서 ActionMaps,Actions,AcitonProperites를 수정할 수 있다.
Player Input 컴포넌트 : 입력 행동을 받아 해당 게임오브젝트에 메시지로 전달해주는 역할
'Unity' 카테고리의 다른 글
Unity :: StringToHash 메서드 사용하기(애니메이터 컨트롤러) (0) | 2024.10.14 |
---|---|
Unity :: 스크립트에서 InputSystem을 사용하기 위해 InputActionAsset을 호출시 주의할 점 (0) | 2024.10.10 |
Unity :: ScriptableObject(스크립타블오브젝트) (0) | 2024.10.09 |
Unity :: 오일러각 vs 쿼터니언 , 쿼터니언과 벡터 곱셈 (0) | 2024.10.08 |
Unity :: 충돌 처리,OnCollison~() , OnTrigger~()의 인자값 차이 (0) | 2024.10.07 |