1.键盘、鼠标操作
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)最后就是编写代码脚本进行使用,示例代码如下
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();//启用InputActionmyInputAction.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(){//禁用InputActionmyInputAction.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,否则多设备连接使用时存在问题。
代码示例---多设备管理器
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;/// <summary>
/// 输入设备数据
/// </summary>
[System.Serializable]
public class InputSystemMultiData
{public int Index; //0public 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;//获取设备idint 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;//获取设备idint index = GetIndex(device);//给设备(自定义)中的移动数据赋值InputSystem_MultiDatas[index].MoveMentData = context.ReadValue<Vector2>();}private void OnDestroy(){myInputAction.Disable();}
}
使用示例
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;}elsereturn;}//移动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.修改绑定按键并保存
代码
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();}
}