PlayerInput
InputSystem提供专门用来处理玩家输入的组件,通过关联配置输入文件,可以不需要编写设备输入的相关逻辑,专注于编写输入触发后的逻辑。
如何添加
创建一个Cube,点击Add Component,搜索Player Input即可添加。
界面信息
Actions
用于关联输入配置文件,输入配置文件可以在Project窗口自主创建,然后进行关联。也可以直接点击Create Actions,会直接创建一个自带相关设置的输入配置文件。(我这里使用的Create Actions)
创建过后会出现这样的文件,双击打开。
ActionMaps 行动地图窗口
多个Action的集合
Actions 输入动作窗口
和Inspector窗口里一样,只不过在右键出现的菜单中删除Action。
Action Properties
之前介绍过了
All Control Schemes
设置编辑器中显示哪些控制方案,需要自己手动添加,也可以自定义。
Gamepad:手柄
Joystick:摇杆
KeyboardMouse:键盘鼠标
Touch:触屏
XR:VR/AR等
All Devices:设备选择
筛选设备
Save Asset
保存配置
Auto-Save
自动保存配置
搜索栏
可以搜索对应动作行为
关联后会出现三个选项
Default Scheme
默认启用哪一种方案,键鼠、手柄等。
Auto-Switch
自带切换输入。比如一开始你使用键鼠输入,然后插上了手柄,则会自动变为手柄输入。
Default Map
默认使用的Action方案。
UI Input Module
UI输入模块。如果你想通过UI来控制,则可以创建并关联。
Camera
关联摄像机,需要分屏时才需修改。
Behavior
通知游戏对象执行对应逻辑。
SendMessage
在脚本中申明“On加行为名的”的函数,无参或者参数类型为Input Value,将此脚本挂载在Player Input挂载的对象上,当触发对应输入时,会通过SendMessage通知执行对应函数。
BroadcastMessage
和Send Message规则基本一致,但脚本也可以挂载在子物体上,通过BroadcastMessage通知执行对应函数。
Invoke UnityEvent Actions
通过拖拽脚本关联函数指明想要执行的函数逻辑,但函数参数类型需要改为Input Action.CallbackContext。
Invoke CSharp Events
通过C#事件监听处理对应逻辑,通过获取PlayerInput进行事件监听。
首先需要获取Player Input组件,然后获取对应的事件进行委托函数添加,输入触发时自动调用函数。
public event Action<InputAction.CallbackContext> onActionTriggered,通常来说给这个事件添加委托函数。
三个默认的事件
设备丢失
玩家失去了一个设备,例如,手柄耗尽电池时
OnDeviceLost(PlayerInput input)
设备注册
当设备丢失,重新连接并再次运行时会触发,例如,重新连接手柄
OnDeviceRegained(PlayerInput input)
控制器切换
切换操作设备时
OnControlsChanged(PlayerInput input)
使用Invoke CSharp Events完成移动,跳跃功能。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class NewBehaviourScript1 : MonoBehaviour
{
public PlayerInput playerInput;
public Rigidbody rigi;
Vector3 dir;
void Start()
{
playerInput.onActionTriggered += PlayerInput_onActionTriggered;
}
private void PlayerInput_onActionTriggered(InputAction.CallbackContext obj)
{
switch (obj.action.name)
{
case "Move":
if(obj.phase == InputActionPhase.Performed)
{
dir = new Vector3(obj.ReadValue<Vector2>().x, 0, obj.ReadValue<Vector2>().y);
}
else if (obj.phase == InputActionPhase.Canceled)
{
dir = Vector3.zero;
}
break;
case "Jump":
rigi.AddForce(Vector3.up * 100);
break;
}
}
// Update is called once per frame
void Update()
{
rigi.AddForce (dir * 10);
}
}