[Unity XR] XRI Input Action Custom Binding
by Sugar0810XR Interaction Toolkit을 공부하면서, Action-Based와 Device-Based의 차이점 등을 공부하다 보니, Action-Based가 전반적으로 범용성이 크고 XRI 개발자들도 추천하고 있었다.
그래서 현재 진행 중인 프로젝트도 Action-Based Controller로 변경했다. 하지만 잘 사용하던 XRInputManager.cs에서 액션 컨트롤러가 매핑되지 않던 것이다.
알고 보니 XRController 클래스는 Device-Based에서만 사용이 가능했던 것이었다.. 당연히 XRStatics.GetFeature 메서드를 사용하는 부분도 문제가 있을 것이므로 버튼 매핑하는 부분을 Action-Based가 바인딩하는 방법인 Input System으로 바꿔준다.
기존 바인딩 방법
Device-based를 사용할 때 사용하던 코드이다.
이 제작자의 바인딩 코드 모듈을 사용했었다.
using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.XR;
using UnityEngine.XR.Interaction.Toolkit;
public class XRInputManager : MonoBehaviour
{
[SerializeField] XRController controller;
[SerializeField] XRBinding[] bindings;
private void Update()
{
foreach (var binding in bindings)
binding.Update(controller.inputDevice);
}
}
[Serializable]
public class XRBinding
{
[SerializeField] XRButton button;
[SerializeField] PressType pressType;
[SerializeField] UnityEvent OnActive;
bool isPressed;
bool wasPressed;
public void Update(InputDevice device)
{
device.TryGetFeatureValue(XRStatics.GetFeature(button), out isPressed);
bool active = false;
switch (pressType)
{
case PressType.Continuous: active = isPressed; break;
case PressType.Begin: active = isPressed && !wasPressed; break;
case PressType.End: active = !isPressed && wasPressed; break;
}
if (active) OnActive.Invoke();
wasPressed = isPressed;
}
}
public enum XRButton
{
Trigger,
Grip,
Primary,
PrimaryTouch,
Secondary,
SecondaryTouch,
Primary2DAxisClick,
Primary2DAxisTouch
}
public enum PressType
{
Begin,
End,
Continuous
}
public static class XRStatics
{
public static InputFeatureUsage<bool> GetFeature(XRButton button)
{
switch (button)
{
case XRButton.Trigger: return CommonUsages.triggerButton;
case XRButton.Grip: return CommonUsages.gripButton;
case XRButton.Primary: return CommonUsages.primaryButton;
case XRButton.PrimaryTouch: return CommonUsages.primaryTouch;
case XRButton.Secondary: return CommonUsages.secondaryButton;
case XRButton.SecondaryTouch: return CommonUsages.secondaryTouch;
case XRButton.Primary2DAxisClick: return CommonUsages.primary2DAxisClick;
case XRButton.Primary2DAxisTouch: return CommonUsages.primary2DAxisTouch;
default: Debug.LogError("button " + button + " not found"); return CommonUsages.triggerButton;
}
}
}
Action-Based
먼저 XRI 기본 세팅 에셋의 'XRI Default Input Actions' 오브젝트를 살펴보자. InputActionReference 클래스 구조로 Input System을 이용하는 것으로 보인다.
새로운 Action Map을 만들어 준다. 이름은 Game이다. 그리고 하위의 액션으로 Pause라는 이름을 만들고 + 버튼을 눌러 바인딩을 추가한다.
나는 오큘러스 퀘스트 2 기준으로 A, X 버튼과 키보드 'P'로 바인딩을 추가했다.
이제 이벤트 핸들러로 스크립트를 구성한다.
나의 경우 기존에 GameManager.cs에서 인풋 바인드로 일시정지 함수를 실행했으므로 이번에도 게임 매니저에서 스크립팅한다.
/// 필드에 선언
[Header("[InputActionReference]")]
public InputActionReference gamePause = null;
...
// [Onclick] 로비 ---> 인게임
public void BtnPlay()
{
if (!TutorialManager.instance.isTutorial)
{
isStart = true;
isRayState = false;
/// 여기서 XRI_InGamePause() 이벤트 핸들러를 켜준다.
gamePause.action.started += XRI_InGamePause;
}
}
...
/// 콜백 함수는 여기, 실행 전 조건을 걸어둠으로 인게임 중에만 작동한다.
// [XRI Input Action Binding(Primary Buuton)] 인게임 ---> 일시정지
public void XRI_InGamePause(InputAction.CallbackContext context)
{
if (isStart && !isPause && !TutorialManager.instance.isTutorial)
{
isPause = true;
isRayState = true;
// Music Paused UI On
uiPause.SetActive(true);
// 플레이 중 노래 일시 정지
Time.timeScale = 0;
musicPlayed.Pause();
}
}
...
/// 콜백 함수 종료 시점 1
// [Onclick] 일시정지 ---> 메인
public void BtnPauseBackLobby()
{
if (isStart && isPause)
{
[중략...]
gamePause.action.started -= XRI_InGamePause;
}
/// 콜백 함수 종료 시점 2
// [Event] 인게임 종료
public void InGameEnd()
{
[중략...]
gamePause.action.started -= XRI_InGamePause;
}
게임 매니저에 만들어 둔 InputActionReference 잊지 않고 맵핑하기~
결과
참고 사이트
'⚙️ Programming > C# & Unity' 카테고리의 다른 글
[Unity] Arduino Serial(유니티 아두이노 시리얼 통신) (0) | 2023.08.14 |
---|---|
[Unity XR] Android Build Setting(유니티 XR 안드로이드 최적화) (0) | 2023.08.14 |
[Unity] Firebase Error(유니티 파이어베이스 컴파일 에러) (0) | 2023.08.14 |
[Unity] Firebase Setting(유니티 파이어베이스 연동하기) (0) | 2023.08.14 |
[Unity] Event 2 - Action (0) | 2023.08.14 |
블로그의 정보
Sugar
Sugar0810