Unity 6 ) InputSystem

강성현
∙∙조회 3
Unity 6 ) InputSystem

1. 이전 InputSytem과 비교

기존 InputSystem

Unity 6버전 InputSystem

Update 에서 매 프레임 입력을 확인한다.

입력이 생기면 정해둔 메서드가 불린다.

 


2. Unity 6 에서의 InputSystem

입력의 이름을 담는 값 : 액션마다 값의 형태를 정하며 방향키 넷을 묶어 Vector2 하나로도 받음

이름을 묶는 단위 : Action Map 단위로 묶고, 묶음째 켜고 끔

설정이 있는 곳 : 패키지로 설치하고, 설정은 프로젝트의 에셋 파일로 둠

  • 패키지를 설치하지 않으면 Unity는 이전처럼 Input Manager로 동작합니다.

 

2-1) InputSystem 설정 방법

Project Settings -> Player -> Active Input Handling 설정에서

이전버전 (Input Manager) , 현재버전 (Input System Package) 혹은 둘다 (both) 선택하여 가능합니다.

 

2-2) Input Actions 에셋

칸

담기는 것

Action Maps

액션을 묶은 단위의 목록

Actions

왼쪽에서 고른 묶음에 들어 있는 액션과, 액션마다 묶인 키

Action Properties

가운데에서 고른 액션의 설정. 키를 고르면 제목이 Binding Properties로 바뀌고 그 키의 설정이 보입니다

 

2-3) Action Map, Action, Binding

단계

뜻

예

Action Map

액션을 묶은 단위. 묶음째 켜고 끕니다

Player, UI

Action

게임 안에서 하려는 일의 이름. 스크립트가 아는 것은 이 이름입니다

Move, Jump

Binding

액션에 실제 키를 묶은 것. 한 액션에 여럿을 묶을 수 있습니다

W·A·S·D, Space

 

  • Action Type 을 Value로, Control Type을 Vector2 로 놓게 된다면,
    Add Up₩Down₩.... Composite로 한번에 방향키 설정도 가능하다.
  • 정규화작업이 이미 Composite안에서 이루어져 있어, 따로 정규화작업을 하지 않아도 됩니다.

 

2-4) PlayerInput

항목

정하는 것

Actions

쓸 Input Actions 에셋. 생성한 Input Actions Asset을 드래그해 넣습니다.

Default Map

재생할 때 켜 둘 Action Map. 적용할 Map을 고릅니다.

Behavior

액션이 일어났을 때 스크립트에 알리는 방법

 

  • Behaviour 설정에 따라 액션 전달 방식이 다르기 때문에 어떤 방식을 채택하는 것이 적절한지 생각해보아야 한다.

Behavior

알리는 방법

Send Messages

같은 게임 오브젝트의 스크립트에서 이름이 맞는 메서드를 찾아 부릅니다.

Broadcast Messages

Send Messages와 같고, 자식 오브젝트의 스크립트까지 찾습니다.

Invoke Unity Events

액션마다 인스펙터에 이벤트 칸이 생기고, 거기 연결한 메서드를 부릅니다.

Invoke C# Events

코드에서 구독하는 C# 이벤트로 알립니다. 인스펙터에서는 연결할 수 없습니다.

 

2-4-1) Send Messages, Broadcast Messages 방식

==Behavior==를 ==Send Messages나 Broadcast Messages==로 두면 PlayerInput은 액션 이름 앞에 ==On==을 붙인 이름의 메서드를 찾아 부릅니다.

unity
using UnityEngine;  
using UnityEngine.InputSystem;

public class MoveTest : MonoBehaviour  
{  
    [SerializeField] private float _moveSpeed = 5f;

    private Vector2 _moveInput;

    private void Update()  
    {  
        Move();  
    }

    public void OnMove(InputValue value)  
    {  
        _moveInput = value.Get<Vector2>();  
    }

    public void OnJump()  
    {  
        Debug.Log("MoveTest : Jump 액션이 들어왔습니다.");  
    }

    private void Move()  
    {  
        Vector3 direction = new Vector3(_moveInput.x, 0f, _moveInput.y);  
        transform.Translate(direction * _moveSpeed * Time.deltaTime);  
    }  
}
  • OnMove는 InputValue를 받아 액션의 값을 담아 오는 상자이며, Get ()로 꺼냅니다.
  • OnJump는 값이 필요 없으므로 아무것도 받지 않습니다.
  • 메서드 이름은 On 뒤에 액션 이름을 대문자로 시작해 붙인 형태 그대로여야 불립니다.
    액션 이름이 Move인데 메서드를 Onmove나 OnMoving으로 쓰면 불리지 않습니다.
    키를 눌러도 반응이 없을 때 먼저 볼 곳이 이 이름입니다.
  • Send Messages는 Button 액션에서는 누를 때만 메서드를 부르고, Value 액션에서는 값이 바뀔 때마다 부릅니다.
    키를 다 떼면 OnMove가 (0, 0)을 받아 불리므로 캡슐이 멈춥니다.

 

2-4-2) Invoke Unity Events 방식

Behavior를 Invoke Unity Events로 바꾸면 인스펙터에 Events 항목이 생기고,

UnityEvent 칸에 메서드를 연결한 것과 같은 방법으로 연결합니다.

csharp
public void OnMove(InputAction.CallbackContext context)  
{  
    _moveInput = context.ReadValue<Vector2>();  
}

public void OnJump(InputAction.CallbackContext context)  
{  
    Debug.Log($"PlayerMover: Jump 단계는 {context.phase}입니다.");  
}
  • 이 상태로 재생하고 Space를 한 번 눌렀다 떼면 Console에 한 줄이 아니라 여러 줄이 찍힙니다.
unity
PlayerMover: Jump 단계는 Started입니다.  
PlayerMover: Jump 단계는 Performed입니다.  
PlayerMover: Jump 단계는 Canceled입니다.
단계Button 액션Value 액션
started누르기 시작함값이 0에서 벗어남
performed끝까지 눌림값이 바뀜. 바뀔 때마다 다시 옴
canceled손을 뗌값이 다시 0이 됨
  • InputManager의 GetKeyDown > performed, GetKeyUp > canceled과 비슷한 원리입니다.

 

 


번외) W를 누르고 있는 동시에 (S or D) 를 같이 눌렀다 떼었을때 어떻게 반응할까?

  • D를 눌렀을때

  • 왜 Started 한번만 호출되고, Performed는 3번이나 호출된 것일까?

앞서 적어놓은 내용을 보면 알 수 있듯이 InputAction 이 받는 값이 ==Value== 액션이라면

started는 값이 ==0==에서 벗어났을때 호출되고

performed는 값이 바뀔때마다 호출됩니다.

값이 변화하는 흐름을 확인해보면 (0,1) , (1,1) , (0,1) 총 값이 3번 바뀌게 됩니다.

 

  • S를 눌렀을 때

  • 왜 D키와 다르게 S키는 Started와 Performed 호출 횟수가 똑같은가?

started는 값이 ==0==에서 벗어났을때 호출된다는 점을 다시 리마인드해보자

W를 누르며 전진하고 있는 상태에서 S를 눌러 후진 입력을 하게 된다면

오브젝트는 전진,후진 둘다 못하는 정지상태가 되게 된다.

그 상태에서 S 입력을 해제하였을때 다시 전진상태로 전환되기 때문에 값이 0에서 벗어나게 된다.