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();
}
}