이번 포스트에서는 Unity의 PlayerInput 컴포넌트를 사용하여
Input System을 사용하는 4가지 방법 중에서 3번째인 Invoke Unity Events를 알아보겠습니다.
기존의 프로젝트에서 사용하던 옵션을 Invoke Unity Events로 변경하도록 하겠습니다.
변경하면 기본적으로 다음과 같이 나타나는 것을 볼 수 있습니다.
이런 상황에서 현재 사용중인 Action Asset에서 기본적으로 사용하는 Action Map이
InGround이므로, InGround 패널을 열어보겠습니다.
이 경우에 Action Map에 정의된 Input Action들도 나타나는 것을 볼 수 있습니다.
정리하자면 다음과 같이 정리할 수 있습니다.
- Invoke Unity Events에 관련한 간단한 정리
Invoke Unity Events를 선택하면
설정한 Action Asset의 Action Map에 연결된 Input Action들을 볼 수 있고,
연결된 Input Action에 영향을 받을 GameObject를 선택하고 호출할 함수를 설정할 수 있습니다.
위와 같이 정리하였으므로 실제 실습을 진행해보겠습니다.
1) 컴포넌트로 사용할 스크립트
public class InvokeUnityEvents : MonoBehaviour
{
[SerializeField]
private float speed;
private Rigidbody2D rigidbody2D;
private Vector2 direction;
private void Awake()
{
rigidbody2D = GetComponent<Rigidbody2D>();
}
private void FixedUpdate()
{
rigidbody2D.velocity = new Vector2(direction.x * speed, rigidbody2D.velocity.y);
}
public void Press(InputAction.CallbackContext value)
{
Debug.Log("Doing Press");
}
public void MoveHorizontal(InputAction.CallbackContext value)
{
direction.x = value.ReadValue<float>();
}
}
위와 같이 스크립트를 구성하였습니다.
이때 입력 이벤트에 연결되어 호출될 콜백 함수가 기존의 방식과 약간의 차이가 있는 것을 볼 수 있습니다.
이 차이점을 정리하면 다음과 같습니다.
- Invoke Unity Events 또는 Invoke C# Events 방식의 콜백 함수 규약
- 입력값이 InputValue가 아닌 InputAction.Callbackcontext로 전달된다
- 입력값을 Get이 아닌 ReadValue로 가져온다
- 함수는 반드시 public으로 선언되야 한다
해당 컴포넌트를 게임오브젝트에 전달하고 마저 설정을 진행해보겠습니다.
위와 같이 설정한 후 실행결과를 확인해보겠습니다.
잘 실행된 것처럼 보이지만, 뭔가 이상한 점이 눈에 보입니다.
이동은 문제없이 처리된것처럼 보이지만, 로그가 한번에 3개 남겨진 것이 눈에 띕니다.
그 이유는 Invoke Unity Events 방식이 기본적으로 따로 설정하지 않는 이상,
Started / Performed / Canceled의 3가지 입력을 전부 처리하기 때문입니다.
따라서 입력이 기본적으로 3번 수행됩니다.
그러므로 기존의 코드를 조금 수정해보도록 하겠습니다.
2) 기존의 스크립트를 수정
public class InvokeUnityEvents : MonoBehaviour
{
[SerializeField]
private float speed;
private Rigidbody2D rigidbody2D;
private Vector2 direction;
private void Awake()
{
rigidbody2D = GetComponent<Rigidbody2D>();
}
private void FixedUpdate()
{
rigidbody2D.velocity = new Vector2(direction.x * speed, rigidbody2D.velocity.y);
}
public void Press(InputAction.CallbackContext value)
{
if (value.started == true)
Debug.Log("Press Started");
if (value.performed == true)
Debug.Log("Press Performed");
if (value.canceled == true)
Debug.Log("Press Canceled");
}
public void MoveHorizontal(InputAction.CallbackContext value)
{
direction.x = value.ReadValue<float>();
}
}
스크립트를 수정하여 위와 같이 고쳐보았습니다.
입력의 3가지 방식인 started / performed / canceled로 분기하여 로그를 남기게 됩니다.
이제 실행 결과를 살펴보겠습니다.
한번의 클릭 이후에 분기별로 로그가 찍힌 것을 확인할 수 있습니다.
3) Invoke Unity Events 방식의 유연함
마지막으로 보여드릴 예제는 매우 특이한 예제입니다.
Invoke Unity Events 방식을 사용하는 경우,
Input Component가 없는 오브젝트의 컴포넌트의 함수도 수행이 가능하다는 장점이 있습니다.
기존의 Broadcast Messages와 다르게
부모-자식 관계가 될 필요가 없다는 점에서 매우 유연하다는 장점을 지니고 있습니다.
구성을 다음과 같이 변경해보겠습니다.
public class Test : MonoBehaviour
{
public void Print()
{
Debug.Log("I am Capsule!!!");
}
}
간단한 로그를 찍는 코드를 준비하여 다음과 같이 구성해보도록 하겠습니다.
PlayerInput 컴포넌트가 없는 Capsule 오브젝트를 생성하고,
Press 입력을 수행하는 경우, Capsule의 Test 컴포넌트에서 Print를 수행하도록 설정하겠습니다.
실행결과는 다음과 같습니다.
PlayerInput 컴포넌트가 없는 오브젝트의 콜백 함수도 문제없이 수행하는 것을 확인할 수 있습니다.
'유니티 > 유니티 C#' 카테고리의 다른 글
유니티 입력 처리 심화 - (12) UI 입력 (0) | 2025.01.08 |
---|---|
유니티 입력 처리 심화 - (11) Player Input 컴포넌트 - Invoke C# Events (0) | 2025.01.05 |
유니티 입력 처리 심화 - (9) Player Input 컴포넌트 - Broadcast Messages (0) | 2025.01.02 |
유니티 입력 처리 심화 - (8) Player Input 컴포넌트 - Send Messages (0) | 2025.01.02 |
유니티 입력 처리 심화 - (7) Player Input 컴포넌트를 통한 입력 처리 (0) | 2025.01.01 |