LoginSignup
7
10

More than 1 year has passed since last update.

Unityの新しいInputSystemをReactivePropertyに変換し使用する

Last updated at Posted at 2021-01-08

はじめに

新しい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

image.png
image.png
こちらはデフォルトで大丈夫ですがButtonにしておくとBindingがボタンのみ表示されます
image.png
Bindingには押したいボタンを
TriggerBehabiorにはPressAndReleaseを設定します

  • Delta

image.png
image.png
こちらはデフォルトで大丈夫ですがAxisにしておくとBindingがAxisのみ表示されます
image.png

  • Axis

image.png
ジョイスティックの場合はドリフトするのでDeadZoneを設定すると良いです。
image.png
キーボードからAxisを作成する場合1DAxisを行うと作成できます。

InputActionをReactivePropertyに変換する拡張メソッド

InputSystemExtension.cs
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEngine;
using UnityEngine.InputSystem;

public static class InputSystemExtension
{
        public static ReadOnlyReactiveProperty<bool> GetButtonProperty(this InputAction inputAction)
        {
            return Observable.FromEvent<InputAction.CallbackContext>(
                    h => inputAction.performed += h,
                    h => inputAction.performed -= h)
                .Select(x => x.ReadValueAsButton())
                .ToReadOnlyReactiveProperty(false);
        }

        //Axis入力だと0等が反応しないためGetDeltaAxisPropertyのみの使用でもよさそうです
        public static ReadOnlyReactiveProperty<float> GetAxisProperty(this InputAction inputAction)
        {
            return Observable.FromEvent<InputAction.CallbackContext>(
                    h => inputAction.performed += h,
                    h => inputAction.performed -= h)
                .Select(x => x.ReadValue<float>())
                .ToReadOnlyReactiveProperty(0);
        }

        //Delta入力はUpdate基準なのでUpdate基準に変換(主にマウスで使用)
        public static ReadOnlyReactiveProperty<float> GetDeltaAxisProperty(this InputAction inputAction)
        {
            return Observable.EveryUpdate().Select(_ => inputAction.ReadValue<float>()).ToReadOnlyReactiveProperty(0);
        }

}

テストコード

TestInput.cs
using System;
using UnityEngine;
using UnityEngine.InputSystem;
using UniRx;

public class TestInput : MonoBehaviour,IDisposable
{

    [SerializeField]
    private InputActionMap inputAction;

    private ReadOnlyReactiveProperty<bool> attack = default;
    //ボタンに変換したIReactivePropertyを公開
    public IReadOnlyReactiveProperty<bool> Attack => attack;

    private ReadOnlyReactiveProperty<float> mouseX = default;
    //Mouseの移動量に変換したIReactivePropertyを公開
    public IReadOnlyReactiveProperty<float> MouseX => mouseX;

    /// <summary>
    /// 2ボタンで-1 0 1出力
    /// </summary>
    private ReadOnlyReactiveProperty<float> horizontal = default;
    //Mouseの移動量に変換したIReactivePropertyを公開
    public IReadOnlyReactiveProperty<float> Horizontal => horizontal;

    private void OnEnable()
    {
        inputAction.Enable();
    }

    private void OnDisable()
    {
        inputAction.Disable();
    }

    private void Awake()
    {
        attack =inputAction.FindAction("Attack").GetButtonProperty();
        mouseX = inputAction.FindAction("MouseX").GetDeltaAxisProperty();
        horizontal = inputAction.FindAction("Horizontal").GetAxisProperty();
    }

    private void OnDestroy()
    {
        Dispose();
    }

    public void Dispose()
    {
        inputAction?.Dispose();
        attack?.Dispose();
        mouseX?.Dispose();
        horizontal?.Dispose();
    }
}
Test.cs
using UnityEngine;
using UniRx;
using UniRx.Triggers;

public class Test : MonoBehaviour
{
    [SerializeField]
    private TestInput input;

    private void Start()
    {
        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をそのまま使用するよりは楽に使えるようになったと思います。

7
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10