はじめに
新しいInputSystemへの移行をReactivePropertyを用いて行います
新しいInputSystemそのままだと使いにくすぎる…
環境
Unity2020.2
従来のUnityEngine.Inputからの移行
InputAction自体がInputすべての汎用クラスなので
旧InputのInput.GetButton/Input.GetAxisと同様に使えるよう
3パターンに分けてReactivePropertyへ変換を行います。
- Button 旧:Input.GetButton(Down/Up)
- Delta 旧:Input.GetAxis(MouseX) マウスの移動量
- Axis 旧:Input.GetAxis 例Joystick,Horizontal
変換には今回作成した拡張メソッドを使用しています。
InputActionの設定
- Button
こちらはデフォルトで大丈夫ですがButtonにしておくとBindingがボタンのみ表示されます
Bindingには押したいボタンを
TriggerBehabiorにはPressAndReleaseを設定します
- Delta
こちらはデフォルトで大丈夫ですがAxisにしておくとBindingがAxisのみ表示されます
- Axis
ジョイスティックの場合はドリフトするのでDeadZoneを設定すると良いです。
キーボードからAxisを作成する場合1DAxisを行うと作成できます。
InputActionをReactivePropertyに変換する拡張メソッド
InputSystemExtension.cs
usingSystem.Collections;usingSystem.Collections.Generic;usingUniRx;usingUnityEngine;usingUnityEngine.InputSystem;publicstaticclassInputSystemExtension{publicstaticReadOnlyReactiveProperty<bool>GetButtonProperty(thisInputActioninputAction){returnObservable.FromEvent<InputAction.CallbackContext>(h=>inputAction.performed+=h,h=>inputAction.performed-=h).Select(x=>x.ReadValueAsButton()).ToReadOnlyReactiveProperty(false);}publicstaticReadOnlyReactiveProperty<float>GetAxisProperty(thisInputActioninputAction){returnObservable.FromEvent<InputAction.CallbackContext>(h=>inputAction.performed+=h,h=>inputAction.performed-=h).Select(x=>x.ReadValue<float>()).ToReadOnlyReactiveProperty(0);}//Delta入力はUpdate基準なのでUpdate基準に変換(主にマウスで使用)publicstaticReadOnlyReactiveProperty<float>GetDeltaAxisProperty(thisInputActioninputAction){returnObservable.EveryUpdate().Select(_=>inputAction.ReadValue<float>()).ToReadOnlyReactiveProperty(0);}}
テストコード
TestInput.cs
usingSystem;usingUnityEngine;usingUnityEngine.InputSystem;usingUniRx;publicclassTestInput:MonoBehaviour,IDisposable{[SerializeField]privateInputActionMapinputAction;privateReadOnlyReactiveProperty<bool>attack=default;//ボタンに変換したIReactivePropertyを公開publicIReadOnlyReactiveProperty<bool>Attack=>attack;privateReadOnlyReactiveProperty<float>mouseX=default;//Mouseの移動量に変換したIReactivePropertyを公開publicIReadOnlyReactiveProperty<float>MouseX=>mouseX;/// <summary>/// 2ボタンで-1 0 1出力/// </summary>privateReadOnlyReactiveProperty<float>horizontal=default;//Mouseの移動量に変換したIReactivePropertyを公開publicIReadOnlyReactiveProperty<float>Horizontal=>horizontal;privatevoidOnEnable(){inputAction.Enable();}privatevoidOnDisable(){inputAction.Disable();}privatevoidAwake(){attack=inputAction.FindAction("Attack").GetButtonProperty();mouseX=inputAction.FindAction("MouseX").GetDeltaAxisProperty();horizontal=inputAction.FindAction("Horizontal").GetAxisProperty();}privatevoidOnDestroy(){Dispose();}publicvoidDispose(){inputAction?.Dispose();attack?.Dispose();mouseX?.Dispose();horizontal?.Dispose();}}
Test.cs
usingUnityEngine;usingUniRx;usingUniRx.Triggers;publicclassTest:MonoBehaviour{[SerializeField]privateTestInputinput;privatevoidStart(){input.Attack.Subscribe(x=>{if(x){Debug.Log("GetButtonDown");}else{Debug.Log("GetButtonUp");}}).AddTo(this);this.UpdateAsObservable().Subscribe(_=>{Debug.Log("GetButton:"+input.Attack.Value);Debug.Log("Horizontal"+input.Horizontal);Debug.Log("MouseX"+input.MouseX);}).AddTo(this);}}
最後に
InputSystemPackageをそのまま使用するよりは楽に使えるようになったと思います。