kizumi_header_banner_img

Hello! Beautiful Kizumi!

加载中

文章导读

Unity进阶之InputSystem


avatar
Yuyas 2025年12月19日 18

需要先导包

手动切换新老输入系统,也可以同时启用

File -> Build Setting -> Player Setting -> Other -> Active Input Handling

键盘

先获取当前输入设备(键盘)

Keyboard keyBoard = Keyboard.current;

按下

keyBoard.enterKey.wasPressedThisFrame

抬起

keyBoard.dKey.wasReleasedThisFrame

长按

keyBoard.spaceKey.isPressed

任意键同理keyBoard.anyKey

通过给keyboard对象中的 文本输入事件 添加委托函数,本质Event订阅 便可以获得每次输入的内容

鼠标

获取鼠标

Mouse mouse = Mouse.current

鼠标左键 mouse.leftButton 鼠标右键 mouse.rightButton 鼠标中键 mouse.middleButton 鼠标(侧键) 向前向后键 mouse.forwardButton; mouse.backButton;

位置相关:

//获取当前鼠标位置 mouse.position.ReadValue();

//得到鼠标两帧之间的一个偏移向量 mouse.delta.ReadValue();

//鼠标中间 滚轮的方向向量 mouse.scroll.ReadValue();

触屏

获取设备

Touchscreen ts = Touchscreen.current;

得到触屏手指数量

ts.touches.Count

获取指定索引手指 TouchControl tc = ts.touches[0]

按下

tc.press.wasPressedThisFrame

相较于其他多的功能

点击手势

tc.tap.isPressed

连续点击次数

tc.tapCount

手指位置等相关信息

//位置 tc.position.ReadValue(); //第一次接触时位置 tc.startPosition.ReadValue(); //接触区域大小 tc.radius.ReadValue(); //偏移位置 tc.delta.ReadValue();

//得到当前手指的 状态(阶段)
UnityEngine.InputSystem.TouchPhase tp = tc.phase.ReadValue();
switch (tp)
{
   //无
   case UnityEngine.InputSystem.TouchPhase.None:
       break;
   //开始接触
   case UnityEngine.InputSystem.TouchPhase.Began:
       break;
   //移动
   case UnityEngine.InputSystem.TouchPhase.Moved:
       break;
   //结束
   case UnityEngine.InputSystem.TouchPhase.Ended:
       break;
   //取消
   case UnityEngine.InputSystem.TouchPhase.Canceled:
       break;
   //静止
   case UnityEngine.InputSystem.TouchPhase.Stationary:
       break;
   default:
       break;
}

InputAction

为区分,一般加上[Header(“name”)]特性

必须在开始时执行action.Enable( );

Actions

选择动作/控制类型,用于筛选后续按键输入设备

Interactions

特殊交互,存在三个事件

开始started

触发performed

结束canceled

可以订阅参数为InputAction.CallbackContext的函数

触发类型有

Hold

适用于需要输入设备保持一段时间的操作。当按钮按下会触发started,若在松开按钮前,按住时间大于等于Hold Time则会触发performed(时间一到就触发),否则触发canceled。

Tap

和Hold相反,需要在一段时间内按下松开来触发。当按钮按下会触发started,若在Max Tap Duriation时间内(小于)松开按钮,触发performed,否则触发canceled。

SlowTap

类似Hold,但是它在按住时间大于等于Max Tap Duriation的时候,并不会立刻触发performed,而是会在松开的时候才触发performed

MultiTap

用作于多次点击,例如双击或者三连击。Tap Count为点击次数,Max Tap Spacing为每次点击之间的间隔(默认值为 2 * Max Tap Duration)。Max Tap Duration为每次点击的持续时间,即按下和松开按钮的这段时间。当每次点击时间小于Max Tap Duration,且点击间隔时间小于Max Tap Spacing,点击Tap Count次,触发performed。

Press

可以实现类似按钮的操作

Press Only:按下的时候触发started和performed。不触发canceled

Release Only: 按下的时候触发started,松开的时候触发performed

Press And Release: 按下的时候触发started和performed,松开的时候会再次触发started和performed。不触发canceled

Press Point:在Input System中,每个按钮都有对应的浮点值,例如普通的按钮,将会在0(未按下)和1(按下)之间。因此我们可以利用这个值(Press Point)来进行区分,当大于等于这个值则认为按钮按下了。

Path:从哪个控件接受输入 Usages:常用用法 GamePad:游戏手柄 Joystick:操纵杆 Keyboard:键盘 Mouse:鼠标 Pen:笔 Pointer:指针 Sensor:传感器 TouchScreen:触屏 Tracked Device:履带装置 XR Controller:XR 控制器 XR HMD:XR 头戴显示器 Other:其它

输入配置文件

右键创建Input Actions

……..

C# 代码使用配置文件

1.进入已有的Input Actions面板,选择创建C#文件

2.创建相应的对象,通过对象选择对应的Map映射进行操作

TestControls inputActions = new TestControls( );

inputActions.Action1.Enable( );

3.后续与变量Input Action一样,对Started等事件进行订阅

PlayerInput组件

省略了上述写代码的过程,直接通过组件来使用PlayerInput

可以自动生成一个InputAction文件,里面有写好的Player和UI操作

四种行为执行模式:

1.Send Messages

申明名为 “On+行为名” 的函数 没有参数 或者 参数类型为InputValue 将该自定义脚本挂载到PlayerInput依附的对象上 当触发对应输入时 会自动调用函数

并且还有默认的3个和设备相关的函数可以调用 设备注册(当控制器从设备丢失中恢复并再次运行时会触发):OnDeviceRegained(PlayerInput input) 设备丢失(玩家失去了分配给它的设备之一,例如,当无线设备耗尽电池时):OnDeviceLost(PlayerInput input) 控制器切换:OnControlsChanged(PlayerInput input)

2.Broadcast Messages

规则基本与1一致,但是脚本挂载在子物体上也可以被触发

3.Invoke Unity Events

该模式可以让我们在Inspector窗口上通过拖拽的形式关联响应函数 但是注意:响应函数的参数类型 需要改为 InputAction.CallbackContext

4.Invoke C Sharp Events

(1)获取PlayerInput组件 PlayerInput input = this.GetComponent<PlayerInput>(); (2)获取对应事件进行委托函数添加

input.actions[“Move”].performed += Move; // 通过字典得到对应Action

或者

input.onActionTriggered += OnActionTrigger; // 通过onActionTriggered得到context.action.name在对应输出

public void OnActionTrigger(InputAction.CallbackContext context)
{
   switch (context.action.name)
  {
       case "Fire":
           //输入阶段的判断 触发阶段 才去做逻辑
           if(context.phase == InputActionPhase.Performed)
               print("开火");
           break;
       case "Look":
           print("看向");
           print(context.ReadValue<Vector2>());
           break;
       case "Move":
           print("移动");
           print(context.ReadValue<Vector2>());
           break;
  }
}

关键参数InputValue和InputAction.CallbackContext

value.isPressed //是否按下

value.Get<Vector2>()

context.action.name

context.ReadValue<Vector2>()

if(context.phase == InputActionPhase.Performed) // 判断输入阶段

Player Input Manager组件

用于同屏多人游戏制作

Join Behavior:

新角色加入的条件,需勾选Joining Enabled By Default才能生效,加入后的角色会根据加入时触发的输入设备来自动选择对应的输入系统

其中Player Prefab上一定要有Player Input组件

Split – Screen 分屏操作

需要在Prefab上的Player Input中关联摄像机

新输入系统支持UGUI

在EventSystem中的Input System UI Input Module组件中设置

如果想要多玩家不同UI控制系统,需要将EventSystem组件换成MultiPlayer EventSystem

On-Screen Button组件

On-Screen Stick组件

在对应的UI上添加组件,以模拟摇杆和鼠标点击,结合Input System将对UI的操作模拟为设备的操作

Input Debugger

Window -> Analysis -> Input Debugger

InputSystem中专门用于任意键按下的方案

InputSystem.onAnyButtonPress.CallOnce((control) => { print(control.name); }); 委托参数为InputControl

通过普通InputAction的AnyKey的参数InputAction.CallbackContext的context.control.name只能得到AnyKey而不是具体按键

通过Json数据加载配置文件

先将json文件转成字符串

InputActionAsset asset = InputActionAsset.FromJson(jsonStr);

改键思路

将原本的json转化为txt方便读取成字符串,创建对应一个Map映射类,将加载出的字符串中绑定信息用replace替换成映射类中的信息,修改键位就是修改映射类,重新读取txt进行替换动态加载InputAction



评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字
插入代码

个人信息

avatar

24
文章
1
评论
1
用户

近期文章