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


    1.键盘、鼠标操作

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.InputSystem;
    5. using UnityEngine.UI;
    6. public class NewInputSystem : MonoBehaviour
    7. {
    8. public float SpaceKeyValue;
    9. public float RightMouseValue;
    10. public Image Icon;
    11. public Vector2 MousePos;
    12. public Vector2 MouseScroll;
    13. void Update()
    14. {
    15. if(Keyboard.current != null) //判断是否有键盘外设接入
    16. {
    17. if(Keyboard.current.spaceKey.wasPressedThisFrame) //判断是否按下
    18. {
    19. Debug.Log("Space Pressed - New");
    20. }
    21. else if(Keyboard.current.spaceKey.wasReleasedThisFrame) //判断是否抬起
    22. {
    23. Debug.Log("Space Released - New");
    24. }
    25. //值为0表示没有按住,值为1表示正在按住
    26. SpaceKeyValue = Keyboard.current.spaceKey.ReadValue();
    27. if(SpaceKeyValue > 0)
    28. Debug.Log("Space");
    29. }
    30. if(Mouse.current != null) //判断是否有鼠标外设接入
    31. {
    32. if(Mouse.current.rightButton.wasPressedThisFrame) //判断鼠标邮件是否按下
    33. Debug.Log("RightMouse Released - New");
    34. //值为0表示没有按住,值为1表示正在按住
    35. RightMouseValue = Mouse.current.rightButton.ReadValue();
    36. //鼠标右键按住
    37. if(Mouse.current.rightButton.ReadValue() == 1)
    38. Debug.Log("RightMouse");
    39. //获取鼠标位置
    40. Icon.rectTransform.anchoredPosition = Mouse.current.position.ReadValue();
    41. MousePos = Mouse.current.position.ReadValue();
    42. //获取鼠标滚轮值
    43. MouseScroll = Mouse.current.scroll.ReadValue();
    44. }
    45. //手柄
    46. if(Gamepad.current != null)
    47. {
    48. }
    49. }
    50. }

    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)最后就是编写代码脚本进行使用,示例代码如下

    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.Animations;
    6. using UnityEngine.InputSystem;
    7. public class InputSystemBall : MonoBehaviour
    8. {
    9. ///
    10. /// 移动的值,范围为-1到1,类似旧版系统中GetAxis获取到的值
    11. ///
    12. public Vector2 Movement;
    13. ///
    14. /// 移动速度
    15. ///
    16. public float MoveSpeed = 5f;
    17. ///
    18. /// 横向偏移值(-1,1),模拟旧版GetAxis(“Horizontal”)的值
    19. ///
    20. public float Horizontal;
    21. ///
    22. /// 创建的InputAction
    23. ///
    24. private MyInputAction myInputAction;
    25. private Rigidbody rigidbody;
    26. private void Awake()
    27. {
    28. myInputAction = new MyInputAction();
    29. //启用InputAction
    30. myInputAction.Enable();
    31. rigidbody = GetComponent();
    32. //给InputAction中的Jump添加监听,分为3个阶段Started->Performed->Canceld
    33. //myInputAction.GamePlay.Jump.performed += OnJump;
    34. }
    35. public void OnJump(InputAction.CallbackContext context)
    36. {
    37. //Started->Performed->Canceld
    38. //context.ReadValueAsButton()获取按键是按下(true),还是抬起(false)
    39. Debug.Log($"Jump!:{context.ReadValueAsButton()}");
    40. rigidbody.AddForce(Vector3.up * 5f, ForceMode.Impulse);
    41. }
    42. private void OnDestroy()
    43. {
    44. //禁用InputAction
    45. myInputAction.Disable();
    46. }
    47. void Update()
    48. {
    49. //获取InputAction中Movement的值
    50. Movement = myInputAction.GamePlay.Movement.ReadValue();
    51. //获取InputAction中Horizontal的值
    52. Horizontal = myInputAction.GamePlay.Horizontal.ReadValue<float>();
    53. rigidbody.AddForce(new Vector3(Movement.x, 0, Movement.y) * MoveSpeed * Time.deltaTime, ForceMode.Impulse);
    54. //if (myInputAction.GamePlay.Jump.IsPressed())
    55. // Debug.Log("Press");
    56. }
    57. }

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

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

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

    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.InputSystem;
    6. ///
    7. /// 输入设备数据
    8. ///
    9. [System.Serializable]
    10. public class InputSystemMultiData
    11. {
    12. public int Index; //0
    13. public InputDevice Device; //输入设备
    14. public Action OnJump; //jump事件
    15. public Vector2 MoveMentData; //移动值
    16. public InputSystemMultiData(int index, InputDevice device)
    17. {
    18. Index = index;
    19. Device = device;
    20. }
    21. }
    22. ///
    23. /// 多人手柄
    24. ///
    25. public class InputSystemMultiManager : MonoBehaviour
    26. {
    27. ///
    28. /// 单例
    29. ///
    30. public static InputSystemMultiManager Instance;
    31. ///
    32. /// 存储已接入的输入设备
    33. ///
    34. public List InputSystem_MultiDatas = new List();
    35. ///
    36. /// 创建的InputAction
    37. ///
    38. private MyInputAction myInputAction;
    39. private void Awake()
    40. {
    41. Instance = this;
    42. myInputAction = new MyInputAction();
    43. //将InputAction中的Movement和Jump添加监听
    44. myInputAction.GamePlay.Movement.performed += OnMovement;
    45. myInputAction.GamePlay.Jump.performed += OnJump;
    46. myInputAction.Enable();
    47. }
    48. ///
    49. /// 通过index获取设备数据
    50. ///
    51. ///
    52. ///
    53. public InputSystemMultiData GetDataByIndex(int index)
    54. {
    55. //查找存储设备中满足条件的设备数据
    56. var data = InputSystem_MultiDatas.Find(a => a.Index == index);
    57. return data;
    58. }
    59. ///
    60. /// 获取设备Index
    61. ///
    62. /// 原设备
    63. ///
    64. public int GetIndex(InputDevice device)
    65. {
    66. //查找设备是否已存储
    67. var data = InputSystem_MultiDatas.Find(a =>a.Device.deviceId == device.deviceId);
    68. if(data != null)
    69. return data.Index;
    70. //新建设备并存储
    71. InputSystemMultiData multiData = new InputSystemMultiData(InputSystem_MultiDatas.Count, device);
    72. InputSystem_MultiDatas.Add(multiData);
    73. return multiData.Index;
    74. }
    75. ///
    76. /// 跳跃的监听
    77. ///
    78. ///
    79. private void OnJump(InputAction.CallbackContext context)
    80. {
    81. //获取输入设备
    82. InputDevice device = context.control.device;
    83. //获取设备id
    84. int index = GetIndex(device);
    85. //执行设备(自定义)中的跳跃方法
    86. InputSystem_MultiDatas[index].OnJump?.Invoke();
    87. }
    88. ///
    89. /// 移动的监听
    90. ///
    91. ///
    92. private void OnMovement(InputAction.CallbackContext context)
    93. {
    94. //获取输入设备
    95. InputDevice device = context.control.device;
    96. //获取设备id
    97. int index = GetIndex(device);
    98. //给设备(自定义)中的移动数据赋值
    99. InputSystem_MultiDatas[index].MoveMentData = context.ReadValue();
    100. }
    101. private void OnDestroy()
    102. {
    103. myInputAction.Disable();
    104. }
    105. }

    使用示例

    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEditor.Rendering.LookDev;
    5. using UnityEngine;
    6. using UnityEngine.InputSystem;
    7. public class InputSystemMultiBall : MonoBehaviour
    8. {
    9. public int Index = -1;
    10. private InputSystemMultiData Data = null;
    11. private Rigidbody rigidbody;
    12. private void Awake()
    13. {
    14. rigidbody = GetComponent();
    15. Data = null;
    16. }
    17. private void Update()
    18. {
    19. if(Data == null)
    20. {
    21. //获取设备数据
    22. Data = InputSystemMultiManager.Instance.GetDataByIndex(Index);
    23. if (Data != null)
    24. {
    25. //添加跳跃方法
    26. Data.OnJump += OnBallJump;
    27. }
    28. else
    29. return;
    30. }
    31. //移动
    32. rigidbody.AddForce(new Vector3(Data.MoveMentData.x, 0, Data.MoveMentData.y) * 5 * Time.deltaTime, ForceMode.Impulse);
    33. }
    34. ///
    35. /// 跳跃
    36. ///
    37. private void OnBallJump()
    38. {
    39. rigidbody.AddForce(Vector3.up * 5f, ForceMode.Impulse);
    40. //开启协程-让手柄震动
    41. StartCoroutine(StartShockCoroutine());
    42. }
    43. ///
    44. /// 手柄震动
    45. ///
    46. ///
    47. private IEnumerator StartShockCoroutine()
    48. {
    49. //判断是否为手柄输入设备
    50. if (Data.Device is Gamepad == false)
    51. yield break;
    52. Gamepad gamepad = Data.Device as Gamepad;
    53. //设置手柄马达转速(低频,高频)
    54. gamepad.SetMotorSpeeds(0.3f, 0.9f);
    55. //持续时间
    56. yield return new WaitForSeconds(1);
    57. //时间到设置手柄马达停止
    58. gamepad.SetMotorSpeeds(0, 0);
    59. }
    60. }

    4.修改绑定按键并保存

    代码

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using TMPro;
    4. using UnityEngine;
    5. using UnityEngine.InputSystem;
    6. using UnityEngine.UI;
    7. public class InputSystemRebindBall : MonoBehaviour
    8. {
    9. ///
    10. /// 跳跃的Action
    11. ///
    12. public InputActionReference JumpAction;
    13. ///
    14. /// 显示文本
    15. ///
    16. public Text RebindText;
    17. ///
    18. /// 玩家输入
    19. ///
    20. private PlayerInput playerInput;
    21. private Rigidbody rigidbody;
    22. public Button rebindBtn;
    23. private void Awake()
    24. {
    25. rigidbody = GetComponent();
    26. playerInput = GetComponent();
    27. }
    28. void Start()
    29. {
    30. //读取保存的按键输入数据
    31. string json = PlayerPrefs.GetString("InputActions", null);
    32. //加载保存的按键输入数据并应用
    33. if (!string.IsNullOrEmpty(json))
    34. playerInput.actions.LoadBindingOverridesFromJson(json);
    35. //显示当前绑定的按键名称,InputControlPath.HumanReadableStringOptions.OmitDevice表示去除设备名称
    36. RebindText.text = InputControlPath.ToHumanReadableString(JumpAction.action.bindings[0].effectivePath,InputControlPath.HumanReadableStringOptions.OmitDevice);
    37. rebindBtn.onClick.AddListener(RebindKey);
    38. }
    39. ///
    40. /// 跳跃,使用PlayerInput添加event进行绑定
    41. ///
    42. public void OnJump()
    43. {
    44. rigidbody.AddForce(Vector3.up * 5f, ForceMode.Impulse);
    45. }
    46. ///
    47. /// 修改绑定的按钮
    48. ///
    49. public void RebindKey()
    50. {
    51. //先切换到其他行为方案
    52. playerInput.SwitchCurrentActionMap("UI");
    53. RebindText.text = "请输入新键...";
    54. //PerformInteractiveRebinding进行改键
    55. //WithControlsExcluding剔除鼠标操作
    56. //OnComplete改建完成执行
    57. //Start开始改键
    58. JumpAction.action.PerformInteractiveRebinding().WithControlsExcluding("Mouse").OnComplete(operation =>
    59. {
    60. Debug.Log("Change Key");
    61. //显示改键后按键名称
    62. RebindText.text = InputControlPath.ToHumanReadableString(JumpAction.action.bindings[0].effectivePath, InputControlPath.HumanReadableStringOptions.OmitDevice);
    63. //将operation释放
    64. operation.Dispose();
    65. //切换为原行为方案
    66. playerInput.SwitchCurrentActionMap("GamePlay");
    67. //保存改键信息
    68. string json = playerInput.actions.SaveBindingOverridesAsJson();
    69. PlayerPrefs.SetString("InputActions", json );
    70. }).Start();
    71. }
    72. }

  • 相关阅读:
    egg(二十):fs读取本地的txt文件
    Go编程语言变量赋值教程
    ECharts实现数据可视化入门教程(超详细)
    2022.11.06 洛谷 P6587 超超的序列
    上传本地文件到github
    Socket通信
    WinHex(三)
    Ubuntu安装SVN服务并结合内网穿透实现公网访问本地存储文件
    【JS笔记】JS中的DOM对象以及通过JS获取DOM结点,操作DOM属性
    数据在内存中的存储
  • 原文地址:https://blog.csdn.net/qq_42720695/article/details/133067117