Unity InputSystem自定义InputDevice及一个Button的示例:

1、声明一个 MyInputDevice

cs 复制代码
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.LowLevel;
using UnityEngine.InputSystem.Utilities;

[InputControlLayout(stateType = typeof(MyInputDeviceState))] //关联上 MyInputDeviceState
public class MyInputDevice : InputDevice
{

}
public struct MyInputDeviceState : IInputStateTypeInfo //写一个继承自"IInputStateTypeInfo接口"的结构体
{
    public FourCC format => new FourCC('T', 'E', 'S', 'T'); //这里的四个字符可以自定义,表示设备识别符(ID)
    [InputControl(name = "button", layout = "Button")] //这里的layout = 是必填项,表示是个按钮
    public bool button;
}

2、通过按键盘的空格键,模拟MyInputDevice的按钮的输入

cs 复制代码
using UnityEngine;
using UnityEngine.InputSystem;

/// <summary>
/// 通过键盘的空格键,模拟MyInputDevice的按钮的输入
/// </summary>
public class MyInputDevice_MoNi : MonoBehaviour
{
    private MyInputDevice myInputDevice;

    private void Start()
    {
        //注册 + 增加,这两步是必须的
        InputSystem.RegisterLayout<MyInputDevice>();
        myInputDevice = InputSystem.AddDevice<MyInputDevice>();
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            //按下空格键,模拟设备按钮的按下
            InputSystem.QueueStateEvent(myInputDevice, new MyInputDeviceState() { button = true });
        }
        else if (Input.GetKeyUp(KeyCode.Space))
        {
            //松开空格键,模拟设备按钮的松开
            InputSystem.QueueStateEvent(myInputDevice, new MyInputDeviceState() { button = false });
        }
    }
}

3、构造相关的 InputAction,测试:

① 新建一个UnityActions的Asset文件,(Action Type是Button),Binding的Path填入:<MyInputDevice>/button ,按回车键确认

② 写测试代码:

cs 复制代码
using UnityEngine;
using UnityEngine.InputSystem;

public class InputAction_Funner : MonoBehaviour
{
    public InputActionReference inputActionReference;
    private InputAction inputAction;

    void Start()
    {
        inputAction = inputActionReference.action;
        inputAction.Enable();

        inputAction.started += (v) =>
        {
            Debug.LogError("start");
        };
        inputAction.performed += (v) =>
        {
            Debug.LogError("performed");
        };
        inputAction.canceled += (v) =>
        {
            Debug.LogError("cancel");
        };
    }
}

运行,按空格键,即可看到效果:

在第一次运行后,下次绑定Path,可直接找到Path的 Other 选项中的 MyInputDevice:




方式二:

cs 复制代码
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Layouts;


public class MyInputDevice : InputDevice
{
    [InputControl]
    public ButtonControl button { get; private set; }

    protected override void FinishSetup()
    {
        base.FinishSetup();
        button = GetChildControl<ButtonControl>(nameof(button));
    }
}
cs 复制代码
using UnityEngine;
using UnityEngine.InputSystem;

/// <summary>
/// 通过键盘的空格键,模拟MyInputDevice的按钮的输入
/// </summary>
public class MyInputDevice_MoNi : MonoBehaviour
{
    private MyInputDevice myInputDevice;

    private void Start()
    {
        //注册 + 增加,这两步是必须的
        InputSystem.RegisterLayout<MyInputDevice>();
        myInputDevice = InputSystem.AddDevice<MyInputDevice>();
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            //按下空格键,模拟设备按钮的按下
            //InputSystem.QueueStateEvent(myInputDevice, new MyInputDeviceState() { button = true });
            InputSystem.QueueDeltaStateEvent(myInputDevice.button, true);
        }
        else if (Input.GetKeyUp(KeyCode.Space))
        {
            //松开空格键,模拟设备按钮的松开
            //InputSystem.QueueStateEvent(myInputDevice, new MyInputDeviceState() { button = false });
            InputSystem.QueueDeltaStateEvent(myInputDevice.button, false);
        }
    }
}
cs 复制代码
using UnityEngine;
using UnityEngine.InputSystem;

public class InputAction_Funner : MonoBehaviour
{
    public InputActionReference inputActionReference;
    private InputAction inputAction;

    void Start()
    {
        inputAction = inputActionReference.action;
        inputAction.Enable();

        inputAction.started += (v) =>
        {
            Debug.LogError("start");
        };
        inputAction.performed += (v) =>
        {
            Debug.LogError("performed");
        };
        inputAction.canceled += (v) =>
        {
            Debug.LogError("cancel");
        };
    }
}
相关推荐
云上空17 小时前
腾讯云使用对象存储托管并分享WebGL小游戏(unity3d)(需要域名)
unity·腾讯云·webgl·游戏开发·对象存储·网页托管
小贺儿开发19 小时前
Unity3D VR党史主题展馆
unity·人机交互·vr·urp·展馆·党史
TopGames19 小时前
Unity实现10万人同屏动态避障和导航寻路系统 支持3D地形
unity·性能优化·游戏引擎
在路上看风景1 天前
01. GUIContent
unity
托洛夫斯基扎沙耶1 天前
Unity中状态机与行为树的简单实现
unity·游戏引擎
TrudgeCarrot1 天前
unity打包使用SPB管线出现 DontSava错误解决
unity·游戏引擎·dontsave
3D霸霸1 天前
unity 创建URP新场景
unity·游戏引擎
玉梅小洋2 天前
Unity 2D游戏开发 Ruby‘s Adventure 1:课程介绍和资源导入
游戏·unity·游戏引擎·游戏程序·ruby
托洛夫斯基扎沙耶2 天前
Unity可视化工具链基础
unity·编辑器·游戏引擎
浅陌sss2 天前
检查Unity对象要始终使用 != null而不是?.
unity