InputAction 의 세 가지 이벤트
Unity의 새로운 Input System에서 InputAction은 아래 세 가지 주요 이벤트를 제공합니다
• started : 키를 누르기 시작한 순간 호출됨. 키가 눌렸다는 의지를 감지한 시점으로, 실제 입력값이 0일 수도 있음
• performed : 입력이 의미 있는 값으로 들어왔을 때 호출됨. 보통 키가 완전히 눌렸을 때, 혹은 스틱이 어느 정도 이상 움직였을 때 발생
• canceled : 입력이 취소되었을 때 호출됨 (예: 키를 뗀 순간, 스틱을 원점으로 되돌린 경우 등)
일반 키보드에서는 started 이후 거의 동시에 performed 로 이어지지만, 스틱처럼 아날로그 장치에서는 미묘한 차이가 발생합니다. 따라서 만약 키보드만 다룬다면 둘 간의 구분은 거의 무의미합니다.
[SerializeField]
private InputAction rotateAction;
private void OnEnable()
{
// 이벤트 함수 등록
rotateAction.started += OnRotateStarted;
rotateAction.performed += OnRotatePerformed;
rotateAction.canceled += OnRotateCanceled;
// InputAction 활성화
rotateAction.Enable();
}
private void OnDisable()
{
// InputAction 비활성화
rotateAction.Disable();
}
private void OnRotateStarted(InputAction.CallbackContext context)
{
// 최초 1회만 호출됨
if (context.started)
Debug.Log("Rotate started");
}
private void OnRotatePerformed(InputAction.CallbackContext context)
{
// 최초 1회만 호출됨
if (context.performed)
Debug.Log("Rotate performed");
}
private void OnRotateCanceled(InputAction.CallbackContext context)
{
// 최초 1회만 호출됨
if (context.canceled)
Debug.Log("Rotate canceled");
}
위 방식은 Player Input 컴포너트를 사용하지 않고 직접 코드로 제어하는 방식입니다.
먼저, InputAction 을 [SerializedField] 로 직렬화한 후, 유니티 Inspector 창에서 적절한 입력을 Binding 시키면 해당 입력의 상태에 따라 이벤트가 호출되는 구조입니다. 또한 사용자가 직접 이벤트를 등록하고, 활성 / 비활성 처리를 해주어야 합니다. 이 때 각 이벤트는 최초 1회만 호출됩니다. 따라서 키가 "계속 눌리는 동안" 에 대한 이벤트를 받고 싶을 때는 별도의 처리를 해야 합니다.
지속적인 입력 (Pressed 상태) 처리 방법
키가 눌렸는지에 대한 처리는 IsPressed() 함수로 간단히 체크할 수 있습니다.
[SerializeField]
InputAction trustAction;
void OnEnable()
{
trustAction.Enable();
}
void OnDisable()
{
trustAction.Disable();
}
private void Update()
{
// trustAction 에 매핑된 입력이 눌리고 있는 동안은 "참"
if (trustAction.IsPressed())
{
Debug.Log("Trust action Pressed");
}
}
입력 값 처리 방법
입력 값은 ReadValue<T>() 함수를 사용합니다.
이 때 <T> 값은 유니티 Inspector 창에서 어떤 값으로 binding 했는지에 따라 달라집니다.
• AddBinding
- 단순한 버튼 입력 등에 사용되며, 별도의 값 없이 이벤트 발생 여부만 감지합니다.
• Add Positive / Negative Binding
- float 으로 값을 저장합니다.
• Add Up / Down / Left / Right
- Vector2 로 값을 저장합니다.
만약, Binding 된 상태와 코드에서 읽어오는 타입이 다르다면, 런타임 에러가 발생하기 때문에 주의가 필요합니다.
다음은 Binding 된 입력의 상태와 값을 처리하는 전 코드입니다. ( 이벤트 등록, 해제 및 콜백 함수 포함 )
using UnityEngine;
using UnityEngine.InputSystem;
public class Movement : MonoBehaviour
{
[SerializeField]
InputAction trustAction;
[SerializeField]
InputAction rotateAction;
[SerializeField]
private float trustStrength = 1000.0f;
[SerializeField]
private float rotateSpeed = 30.0f;
private Rigidbody rb;
void OnEnable()
{
// trust 이벤트 등록
trustAction.started += OnTrustStarted;
trustAction.performed += OnTrustPerformed;
trustAction.canceled += OnTrustCanceled;
// rotate 이벤트 등록
rotateAction.started += OnRotateStarted;
rotateAction.performed += OnRotatePerformed;
rotateAction.canceled += OnRotateCanceled;
trustAction.Enable();
rotateAction.Enable();
}
void OnDisable()
{
// trust 이벤트 해제
trustAction.started -= OnTrustStarted;
trustAction.performed -= OnTrustPerformed;
trustAction.canceled -= OnTrustCanceled;
// rotate 이벤트 해제
rotateAction.started -= OnRotateStarted;
rotateAction.performed -= OnRotatePerformed;
rotateAction.canceled -= OnRotateCanceled;
trustAction.Disable();
rotateAction.Disable();
}
private void Start()
{
rb = GetComponent<Rigidbody>();
if (rb == null)
{
Debug.LogError("Rigidbody component is missing");
}
}
private void Update()
{
ProcessInput();
}
private void ProcessInput()
{
if (trustAction.IsPressed())
{
rb.AddForce( transform.up * ( trustStrength * Time.deltaTime ) );
Debug.Log("Trust action Pressed");
}
if (rotateAction.IsPressed())
{
float inputValue = rotateAction.ReadValue<float>();
inputValue *= -1.0f;
transform.Rotate(Vector3.forward, inputValue * rotateSpeed * Time.deltaTime);
Debug.Log($"Rotate action Pressed : {inputValue}");
}
}
// Trust Event Callback 함수
private void OnTrustStarted(InputAction.CallbackContext context)
{
Debug.Log("Trust started");
}
private void OnTrustPerformed(InputAction.CallbackContext context)
{
Debug.Log("Trust performed");
}
private void OnTrustCanceled(InputAction.CallbackContext context)
{
Debug.Log("Trust canceled");
}
// Rotate Event Callback 함수
private void OnRotateStarted(InputAction.CallbackContext context)
{
Debug.Log("Rotate started");
}
private void OnRotatePerformed(InputAction.CallbackContext context)
{
Debug.Log("Rotate performed");
}
private void OnRotateCanceled(InputAction.CallbackContext context)
{
Debug.Log("Rotate canceled");
}
}
정리
• 순간 입력 (점프, 클릭) 은 performed 이벤트에서 처리합니다.
• 지속 입력 (이동, 조준) 은 IsPressed() 함수를 사용합니다.
• 입력 값이 필요한 경우라면 ReadValue<T>() 함수를 사용합니다.
• ReadValue<T>() 함수는 바인딩 방식에 따라 정확한 타입 (float, Vector2 등) 으로 읽어야 합니다.
Unity의 InputAction은 다양한 입력 상황을 유연하게 처리할 수 있도록 설계되어 있으며, 이벤트 기반 처리와 상태 기반 처리를 함께 조합하면 보다 안정적이고 직관적인 입력 로직을 만들 수 있습니다.
'Unity' 카테고리의 다른 글
물리 공간과 오브젝트 공간에서의 물체 이동 (0) | 2025.07.14 |
---|---|
Player Input 컴포넌트를 꼭 써야할까? (0) | 2025.07.13 |
Unity 패키지(.unitypackage) 파일 다루는 방법과 주의할 점 (0) | 2025.07.12 |
Unity 에서 Serializable 사용 예 (0) | 2025.07.03 |
오브젝트를 태그로 찾고자 할 때 : FindWithTag() (0) | 2025.07.02 |