Unity-Input System新输入系统插件学习

1.键盘、鼠标操作

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class NewInputSystem : MonoBehaviour
{
    public float SpaceKeyValue;
    public float RightMouseValue;
    public Image Icon;
    public Vector2 MousePos;
    public Vector2 MouseScroll;

    void Update()
    {
        if(Keyboard.current != null)        //判断是否有键盘外设接入
        {
            if(Keyboard.current.spaceKey.wasPressedThisFrame)       //判断是否按下
            {
                Debug.Log("Space Pressed - New");
            }
            else if(Keyboard.current.spaceKey.wasReleasedThisFrame) //判断是否抬起
            {
                Debug.Log("Space Released - New");
            }
            //值为0表示没有按住,值为1表示正在按住
            SpaceKeyValue = Keyboard.current.spaceKey.ReadValue();
            if(SpaceKeyValue > 0)
                Debug.Log("Space");
        }

        if(Mouse.current != null)       //判断是否有鼠标外设接入
        {
            if(Mouse.current.rightButton.wasPressedThisFrame)       //判断鼠标邮件是否按下
                Debug.Log("RightMouse Released - New");

            //值为0表示没有按住,值为1表示正在按住
            RightMouseValue = Mouse.current.rightButton.ReadValue();

            //鼠标右键按住
            if(Mouse.current.rightButton.ReadValue() == 1)
                Debug.Log("RightMouse");

            //获取鼠标位置
            Icon.rectTransform.anchoredPosition = Mouse.current.position.ReadValue();
            MousePos = Mouse.current.position.ReadValue();
            //获取鼠标滚轮值
            MouseScroll = Mouse.current.scroll.ReadValue();
        }

        //手柄
        if(Gamepad.current != null)
        {

        }
    }
}

2.Input Action

Action Maps---动作表(一般分为两个表1.GamePlay-游戏时用的表,2.UI)

Action---动作

配置:

(1)Action Maps(方案):点击右侧加号新建一个方案,输入方案名称,然后选中该方案在Action与Action Properties设置该方案具体内容。

(2)Action(输入行为):点击"+"添加一个action,选中添加的action在右侧Action Properties内配置Action Type(value---通过值判断,提供一种连续状态变化事件,如果设置了多个输入,就会切换到最主要的一个。用它进行模拟控制,比如移动;Button---通过按钮,默认设置,包括按钮或者按键触发的一次性动作;Pass Through---和Value很相似,但它不会像Value一样(如果有多个输入时,不会只选择最主要的那个,而把其他的输入忽略,适用于一台机器有多人进行游戏)。在使用Value或者Pass Through Types时,你会看到一个额外的选项 Control Type为该Value的返回值类型)。

(3)然后点击添加的Action右侧的"+",有下列4项选择:

Add Binding:添加普通绑定

Add Up\Down\Left\Right Composite:添加上下左右绑定,Action中的Control Type为Vector2时存在此选项

Add Binding With One Modifier:添加组合按钮(1+1组合按键)

Add Binding With Two Modifiers:添加组合按键(1+2组合按键)

(4)点击添加的绑定,在右侧Binding PropertiesàBindingàPath内选择要绑定的按键(可以是键盘、手柄、鼠标等输入设备),也可以点击搜索框左侧的"Listen"按钮,然后按下要绑定的按键,然后选择对应按键即可完成绑定。

(5)配置Interactions:设置Action中的Interactions,该设置会影响Action下所有Binding,设置Binding的Interactions只会影响该Binding。

详细请看【Unity_Input System】Input System新输入系统(二)_铃兰148的博客-CSDN博客的第5节

(6)配置Processors:详细请看【Unity_Input System】Input System新输入系统(二)_铃兰148的博客-CSDN博客的第6节

(7)然后点击"Save Asset"即可保存该InputAction

(8)然后单击创建的InputAction在Inspector面板勾选"Generate C# Class"并配置文件路径,类名,命名空间名称,点击Apply即可生成C#类代码文件。

(9)最后就是编写代码脚本进行使用,示例代码如下

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.InputSystem;

public class InputSystemBall : MonoBehaviour
{
    /// <summary>
    /// 移动的值,范围为-1到1,类似旧版系统中GetAxis获取到的值
    /// </summary>
    public Vector2 Movement;
    /// <summary>
    /// 移动速度
    /// </summary>
    public float MoveSpeed = 5f;

    /// <summary>
    /// 横向偏移值(-1,1),模拟旧版GetAxis("Horizontal")的值
    /// </summary>
    public float Horizontal;

    /// <summary>
    /// 创建的InputAction
    /// </summary>
    private MyInputAction myInputAction;
    private Rigidbody rigidbody;

    private void Awake()
    {
        myInputAction = new MyInputAction();
        //启用InputAction
        myInputAction.Enable();
        rigidbody = GetComponent<Rigidbody>();

        //给InputAction中的Jump添加监听,分为3个阶段Started->Performed->Canceld
        //myInputAction.GamePlay.Jump.performed += OnJump;
    }

    public void OnJump(InputAction.CallbackContext context)
    {
        //Started->Performed->Canceld
        //context.ReadValueAsButton()获取按键是按下(true),还是抬起(false)
        Debug.Log($"Jump!:{context.ReadValueAsButton()}");
        rigidbody.AddForce(Vector3.up * 5f, ForceMode.Impulse);
    }

    private void OnDestroy()
    {
        //禁用InputAction
        myInputAction.Disable();
    }

    void Update()
    {
        //获取InputAction中Movement的值
        Movement = myInputAction.GamePlay.Movement.ReadValue<Vector2>();
        //获取InputAction中Horizontal的值
        Horizontal = myInputAction.GamePlay.Horizontal.ReadValue<float>();
        rigidbody.AddForce(new Vector3(Movement.x, 0, Movement.y) * MoveSpeed * Time.deltaTime, ForceMode.Impulse);

        //if (myInputAction.GamePlay.Jump.IsPressed())
        //    Debug.Log("Press");
    }
}

3.多设备支持与手柄震动实现

注意创建InputAction的Action时需要选择Action Type为Pass Through,否则多设备连接使用时存在问题。

代码示例---多设备管理器

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

/// <summary>
/// 输入设备数据
/// </summary>
[System.Serializable]
public class InputSystemMultiData
{
    public int Index;               //0
    public InputDevice Device;      //输入设备
    public Action OnJump;           //jump事件
    public Vector2 MoveMentData;    //移动值

    public InputSystemMultiData(int index, InputDevice device)
    {
        Index = index;
        Device = device;
    }
}

/// <summary>
/// 多人手柄
/// </summary>
public class InputSystemMultiManager : MonoBehaviour
{
    /// <summary>
    /// 单例
    /// </summary>
    public static InputSystemMultiManager Instance;

    /// <summary>
    /// 存储已接入的输入设备
    /// </summary>
    public List<InputSystemMultiData> InputSystem_MultiDatas = new List<InputSystemMultiData>();

    /// <summary>
    /// 创建的InputAction
    /// </summary>
    private MyInputAction myInputAction;

    private void Awake()
    {
        Instance = this;

        myInputAction = new MyInputAction();

        //将InputAction中的Movement和Jump添加监听
        myInputAction.GamePlay.Movement.performed += OnMovement;
        myInputAction.GamePlay.Jump.performed += OnJump;
        myInputAction.Enable();
    }

    /// <summary>
    /// 通过index获取设备数据
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public InputSystemMultiData GetDataByIndex(int index)
    {
        //查找存储设备中满足条件的设备数据
        var data = InputSystem_MultiDatas.Find(a => a.Index == index);

        return data;
    }

    /// <summary>
    /// 获取设备Index
    /// </summary>
    /// <param name="device">原设备</param>
    /// <returns></returns>
    public int GetIndex(InputDevice device)
    {
        //查找设备是否已存储
        var data = InputSystem_MultiDatas.Find(a =>a.Device.deviceId == device.deviceId);

        if(data != null) 
            return data.Index;

        //新建设备并存储
        InputSystemMultiData multiData = new InputSystemMultiData(InputSystem_MultiDatas.Count, device);
        InputSystem_MultiDatas.Add(multiData);
        return multiData.Index;
    }

    /// <summary>
    /// 跳跃的监听
    /// </summary>
    /// <param name="context"></param>
    private void OnJump(InputAction.CallbackContext context)
    {
        //获取输入设备
        InputDevice device = context.control.device;
        //获取设备id
        int index = GetIndex(device);
        //执行设备(自定义)中的跳跃方法
        InputSystem_MultiDatas[index].OnJump?.Invoke();
    }

    /// <summary>
    /// 移动的监听
    /// </summary>
    /// <param name="context"></param>
    private void OnMovement(InputAction.CallbackContext context)
    {
        //获取输入设备
        InputDevice device = context.control.device;
        //获取设备id
        int index = GetIndex(device);
        //给设备(自定义)中的移动数据赋值
        InputSystem_MultiDatas[index].MoveMentData = context.ReadValue<Vector2>();
    }

    private void OnDestroy()
    {
        myInputAction.Disable();
    }
}

使用示例

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Rendering.LookDev;
using UnityEngine;
using UnityEngine.InputSystem;

public class InputSystemMultiBall : MonoBehaviour
{
    public int Index = -1;

    private InputSystemMultiData Data = null;

    private Rigidbody rigidbody;

    private void Awake()
    {
        rigidbody = GetComponent<Rigidbody>();
        Data = null;
    }

    private void Update()
    {
        if(Data == null)
        {
            //获取设备数据
            Data = InputSystemMultiManager.Instance.GetDataByIndex(Index);

            if (Data != null)
            {
                //添加跳跃方法
                Data.OnJump += OnBallJump;
            }
            else
                return;
        }
        //移动
        rigidbody.AddForce(new Vector3(Data.MoveMentData.x, 0, Data.MoveMentData.y) * 5 * Time.deltaTime, ForceMode.Impulse);
    }

    /// <summary>
    /// 跳跃
    /// </summary>
    private void OnBallJump()
    {
        rigidbody.AddForce(Vector3.up * 5f, ForceMode.Impulse);
        //开启协程-让手柄震动
        StartCoroutine(StartShockCoroutine());
    }

    /// <summary>
    /// 手柄震动
    /// </summary>
    /// <returns></returns>
    private IEnumerator StartShockCoroutine()
    {
        //判断是否为手柄输入设备
        if (Data.Device is Gamepad == false)
            yield break;

        Gamepad gamepad = Data.Device as Gamepad;
        //设置手柄马达转速(低频,高频)
        gamepad.SetMotorSpeeds(0.3f, 0.9f);
        //持续时间
        yield return new WaitForSeconds(1);
        //时间到设置手柄马达停止
        gamepad.SetMotorSpeeds(0, 0);
    }
}

4.修改绑定按键并保存

代码

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class InputSystemRebindBall : MonoBehaviour
{
    /// <summary>
    /// 跳跃的Action
    /// </summary>
    public InputActionReference JumpAction;
    /// <summary>
    /// 显示文本
    /// </summary>
    public Text RebindText;
    /// <summary>
    /// 玩家输入
    /// </summary>
    private PlayerInput playerInput;
    private Rigidbody rigidbody;
    public Button rebindBtn;

    private void Awake()
    {
        rigidbody = GetComponent<Rigidbody>();
        playerInput = GetComponent<PlayerInput>();
    }

    void Start()
    {
        //读取保存的按键输入数据
        string json =  PlayerPrefs.GetString("InputActions", null);

        //加载保存的按键输入数据并应用
        if (!string.IsNullOrEmpty(json))
            playerInput.actions.LoadBindingOverridesFromJson(json);

        //显示当前绑定的按键名称,InputControlPath.HumanReadableStringOptions.OmitDevice表示去除设备名称
        RebindText.text = InputControlPath.ToHumanReadableString(JumpAction.action.bindings[0].effectivePath,InputControlPath.HumanReadableStringOptions.OmitDevice);

        rebindBtn.onClick.AddListener(RebindKey);
    }

    /// <summary>
    /// 跳跃,使用PlayerInput添加event进行绑定
    /// </summary>
    public void OnJump()
    {
        rigidbody.AddForce(Vector3.up * 5f, ForceMode.Impulse);
    }

    /// <summary>
    /// 修改绑定的按钮
    /// </summary>
    public void RebindKey()
    {
        //先切换到其他行为方案
        playerInput.SwitchCurrentActionMap("UI");

        RebindText.text = "请输入新键...";

        //PerformInteractiveRebinding进行改键
        //WithControlsExcluding剔除鼠标操作
        //OnComplete改建完成执行
        //Start开始改键
        JumpAction.action.PerformInteractiveRebinding().WithControlsExcluding("Mouse").OnComplete(operation =>
        {
            Debug.Log("Change Key");
            //显示改键后按键名称
            RebindText.text = InputControlPath.ToHumanReadableString(JumpAction.action.bindings[0].effectivePath, InputControlPath.HumanReadableStringOptions.OmitDevice);
            //将operation释放
            operation.Dispose();
            //切换为原行为方案
            playerInput.SwitchCurrentActionMap("GamePlay");

            //保存改键信息
            string json = playerInput.actions.SaveBindingOverridesAsJson();
            PlayerPrefs.SetString("InputActions", json );

        }).Start();
    }
}
相关推荐
Lyqfor2 分钟前
云原生学习
java·分布式·学习·阿里云·云原生
大懒的猫猫虫40 分钟前
Upload-Labs-Linux1学习笔迹 (图文介绍)
学习
ctrey_1 小时前
2024-11-13 学习人工智能的Day26 sklearn(2)
人工智能·学习·sklearn
Allen zhu2 小时前
【PowerHarmony】电鸿蒙学习记录-编写helloworld!
学习·华为·harmonyos
Dr.long2 小时前
unity老猿随笔
unity·游戏引擎
Json____2 小时前
学法减分交管12123模拟练习小程序源码前端和后端和搭建教程
前端·后端·学习·小程序·uni-app·学法减分·驾考题库
五味香2 小时前
Linux学习,ip 命令
linux·服务器·c语言·开发语言·git·学习·tcp/ip
Chef_Chen2 小时前
从0开始学习机器学习--Day22--优化总结以及误差作业(上)
人工智能·学习·机器学习
虾球xz3 小时前
游戏引擎学习第11天
stm32·学习·游戏引擎