输入绑定(InputBinding)表示动作(Action)与一个或多个由控制路径(Control path)标识的控制(Control)之间的连接。一个动作可以有任意数量的绑定指向它。多个绑定可以引用相同的控制。
每个绑定具有以下属性:
属性 描述
path 识别动作应从中接收输入的控制的控制路径。
overridePath 通过控制路径来覆盖path。与path不同,overridePath不是持久性的,因此可以用于非破坏性地覆盖path。
action 绑定应触发的动作的名称或ID。注意,这可以是null或空的(例如,对于复合绑定)。不区分大小写。
groups 绑定所属的绑定组的用分号分隔的列表。可以是null或空的。绑定组可以是任何东西,但主要用于控制方案。
interactions 应用到此绑定输入的交互的用分号分隔的列表。注意,Unity会将应用于动作本身的交互(如果有)附加到此列表中。
processors 应用到此绑定输入的处理器的用分号分隔的列表。注意,Unity会将应用于动作本身的处理器(如果有)附加到此列表中。
id 绑定的唯一ID。您可以在用户设置中存储绑定覆盖时使用它。
name 绑定的可选名称。标识复合绑定中的部分名称。
isComposite 绑定是否作为复合绑定存在。
isPartOfComposite 绑定是否是复合绑定的一部分。
要查询特定动作的绑定,可以使用 InputAction.bindings
。要查询动作映射中所有动作的平面绑定列表,可以使用 InputActionMap.bindings
。
复合绑定(Composite Bindings)
有时,您可能希望有多个控制一起工作以模拟不同类型的控制。最常见的例子是使用键盘上的W、A、S和D键来形成一个与鼠标增量或游戏手柄摇杆等效的2D向量控制。另一个例子是使用两个键来形成一个1D轴,等效于鼠标滚动轴。
用普通绑定很难实现这一点。您可以将一个 ButtonControl
绑定到一个期望 Vector2
的动作上,但这样会在输入系统尝试从一个只能提供float的控制读取 Vector2
时导致运行时异常。
复合绑定(即由其他绑定组成的绑定)解决了这个问题。复合绑定本身不会直接绑定到控制上;而是从其他绑定中获取值,然后动态合成输入。
要在编辑器UI中查看如何创建复合绑定,请参阅有关编辑复合绑定的文档。
要在代码中创建复合绑定,可以使用 AddCompositeBinding
语法。
每个复合绑定由一个 InputBinding.isComposite
属性设置为 true
的绑定组成,接着是一个或多个 InputBinding.isPartOfComposite
属性设置为 true
的绑定。换句话说,InputActionMap.bindings
或 InputAction.bindings
中的多个连续条目一起形成一个复合绑定。
注意,每个复合部分可以绑定任意多次。
复合绑定可以像交互和处理器一样具有参数。
系统中目前有五种内置的复合类型:1D-Axis、2D-Vector、3D-Vector、One Modifier 和 Two Modifiers。此外,您还可以添加自己的复合类型。
1D轴(1D Axis)
1D轴复合绑定有两个部分绑定:
部分 类型 描述
positive Button 控制拉动正方向(向最大值)。
negative Button 控制拉动负方向(向最小值)。
可以在轴复合绑定上设置以下参数:
参数 描述
whichSideWins 如果正方向和负方向同时被激活,轴复合绑定的结果取决于该参数的设置。
minValue 如果负方向被激活,返回的值。默认是 -1。
maxValue 如果正方向被激活,返回的值。默认是 1。
2D向量(2D Vector)
2D向量复合绑定有四个部分绑定:
部分 类型 描述
up Button 控制表示 (0,1) (+Y)。
down Button 控制表示 (0,-1) (-Y)。
left Button 控制表示 (-1,0) (-X)。
right Button 控制表示 (1,0) (+X)。
此外,您可以在2D向量复合绑定上设置以下参数:
参数描述mode是否将输入视为数字控制或模拟控制。
3D向量(3D Vector)
3D向量复合绑定有六个部分绑定:
部分 类型 描述
up Button 控制表示 (0,1,0) (+Y)。
down Button 控制表示 (0,-1,0) (-Y)。
left Button 控制表示 (-1,0,0) (-X)。
right Button 控制表示 (1,0,0) (+X)。
forward Button 控制表示 (0,0,1) (+Z)。
backward Button 控制表示 (0,0,-1) (-Z)。
此外,您可以在3D向量复合绑定上设置以下参数:
参数 描述
mode 是否将输入视为数字控制或模拟控制。
一个修饰符(One Modifier)
一个修饰符复合绑定有两个部分绑定:
部分 类型 描述
modifier Button 必须按住的修饰符。
binding Any 当用户按住修饰符按钮时,复合绑定的值来源于此控制。
该复合绑定没有参数。
两个修饰符
两个修饰符复合绑定
这是一个复合绑定,要求用户同时按住两个“修饰符”按钮以及一个决定实际值的其他控制。比如,"SHIFT+CTRL+1"。它由 TwoModifiersComposite
类实现。这些按钮可以位于任何设备上,可以是切换按钮或全范围按钮,例如游戏手柄的扳机。
结果是与绑定部分的控制类型相同的值。
具有两个修饰符的按钮复合绑定包含三个部分:
modifier1:用户必须按住的第一个修饰符按钮。如果用户没有按下与modifier1绑定的任何按钮,则复合绑定保持默认值。
modifier2:用户必须按住的第二个修饰符按钮。如果用户没有按下与modifier2绑定的任何按钮,则复合绑定保持默认值。
binding:当用户同时按下modifier1和modifier2时,复合绑定的控制值。
该复合绑定没有参数。
编写自定义复合绑定
你可以定义新的复合绑定类型并使用API进行注册。Unity会像对待预定义类型一样处理这些类型。
要定义新的复合绑定类型,请创建一个基于 InputBindingComposite<TValue>
的类。
重要提示:复合绑定必须是无状态的。这意味着不能存储根据输入处理变化的本地状态。对于有状态的绑定处理,请参见交互(interactions)。
现在,当你在编辑器中添加绑定时,复合绑定将显示,并且可以在脚本中使用。
要为复合绑定定义自定义参数编辑器,你可以从 InputParameterEditor<TObject>
继承。
处理绑定
查找绑定
可以使用 InputAction.bindings
属性检索动作的绑定,该属性返回 InputBinding
结构的只读数组。
所有动作的绑定都可以通过 InputActionMap.bindings
属性获取。绑定通过 InputBinding.action
属性与动作相关联。
你也可以通过 InputActionRebindingExtensions.GetBindingIndex
方法查找特定绑定的索引。
最后,你可以通过 GetBindingIndexForControl
查找对应于特定控制的绑定。
更改绑定
通常,你可以通过 InputActionSetupExtensions.ChangeBinding
方法更改现有绑定。这会返回一个访问器,可以用来修改目标 InputBinding
的属性。大多数写操作都是破坏性的。有关非破坏性更改绑定,请参见应用覆盖。
csharp
复制代码
var accessor = playerInput.actions['fire'].ChangeBinding(1); accessor = playerInput.actions.FindActionMap("gameplay").ChangeBinding(2);
你可以使用结果访问器通过 WithPath
或 WithProcessors
等方法修改属性。
你还可以使用访问器遍历绑定,使用 PreviousBinding
和 NextBinding
。
如果给定的绑定是复合绑定,你可以通过其名称而不是索引进行访问。
应用覆盖
你可以在运行时非破坏性地覆盖绑定的某些方面。特定的 InputBinding
属性有一个覆盖变体,如果设置了它,将优先于它们所遮盖的属性。所有覆盖属性的类型都是字符串。
属性 覆盖 说明:
path:overridePath
替换确定哪个控制器被引用的控制路径。如果 overridePath
设置为空字符串,则绑定实际上被禁用。
processors:overrideProcessors
替换应用于绑定的处理器。
interactions:overrideInteractions
替换应用于绑定的交互。
这些覆盖属性的值不会与动作一起保存(例如,调用 InputActionAsset.ToJson()
时)。有关如何持久化用户重新绑定的详细信息,请参见保存和加载重新绑定。
要设置各种覆盖属性,你可以使用 ApplyBindingOverride
API。
通常,最好使用像 GetBindingIndexForControl
这样的API来定位特定的绑定,然后将覆盖应用到该特定绑定。
可以通过调用 Erase
方法来删除绑定。例如:
删除“fire”动作的第一个绑定:
删除“move”动作的“2DVector”复合绑定(包括复合绑定的部分绑定):
通过复合绑定的名称删除绑定:
删除“gameplay”动作图中的第一个绑定:
可以通过 AddBinding
或 AddCompositeBinding
方法来添加新的绑定。例如:
为“fire”动作添加左键绑定:
为“move”动作添加WASD复合绑定:
可以通过绑定属性视图或API配置参数的默认值。例如:
创建一个具有“Hold”交互的动作并设置“duration”参数为4秒:
查询“duration”参数的当前值:
仅查询“Hold”交互的“duration”参数:
使用表达式参数获取“TapInteraction”交互的“duration”值:
可以在单个 InputAction
、InputActionMap
或整个 InputActionAsset
层级应用参数覆盖。例如:
为所有绑定的“duration”参数设置为4秒:
为“tap”交互设置“duration”参数:
为“Gamepad”组中的“tap”交互设置“duration”参数:
使用 InputActionRebindingExtensions.RebindingOperation
类可以让用户在运行时设置自己的绑定。例如:
开始交互式重新绑定:
可以将绑定覆盖属性序列化为JSON字符串并从中恢复。例如:
存储玩家重新绑定:
从PlayerPrefs恢复绑定:
使用 RemoveBindingOverride
或 RemoveAllBindingOverrides
方法删除绑定覆盖。例如:
删除“fire”动作的第一个绑定覆盖:
删除“fire”动作的所有绑定覆盖:
可以使用 InputActionRebindingExtensions.GetBindingDisplayString
方法获取动作的绑定字符串。例如:
获取动作的绑定字符串:
获取特定绑定的显示字符串:
绑定可以属于任意数量的绑定组。可以使用 InputActionMap.bindingMask
或 InputActionAsset.bindingMask
属性启用不同的控件方案。例如:
限制动作图到特定的设备:
当Input System首次访问动作绑定的控件时,会解析这些绑定。例如:
查询动作解析的控件:
监听绑定解析事件:
可以通过 InputActionMap.devices
限制动作图使用特定的设备。例如:
将动作图限制为第一个游戏手柄:
输入冲突
处理输入冲突的机制包括:
多个控件同时提供输入。
输入序列的多个可能选项。
例如,当动作绑定到游戏手柄的两个触发器时,触发器的输入会根据“actuation”级别决定哪个控件“驱动”动作。
可以手动启用按钮和通过类型的动作的初始状态检查,以响应启用时的非默认状态。例如:
启用初始状态检查(仅适用于值类型动作,按钮和通过类型动作默认不开启):
这是对Unity Input System的详细介绍和操作方法,希望对你有所帮助。