search
LoginSignup
8
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

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

はじめに

新しい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をそのまま使用するよりは楽に使えるようになったと思います。

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
What you can do with signing up
8
Help us understand the problem. What are the problem?