本文最后更新于6 天前,其中的信息可能已经过时,如有错误请留言
为什么替代原来的InputManager
Input system将输入和动作逻辑之间用事件分割,这样方便扩展,比如:
“按下A键 = 攻击”,以后换手柄只要把“按下某个按钮”映射为“攻击”即可,然后将攻击事件与动作逻辑绑定
活动输入管理根据需求设置,如果旧版和新版需要同时使用就启用”两个“
基本信息
每个资源文件都可以存储多个映射列表(Action Maps)。Action Map是在不同场景下对应的动作方案,比如行走时,坐车时,UI/陆地上,水上依据不同的情况来回切换不同动作方案
每个映射列表中又有多个行为事件(Action)。事件的触发器就是输入绑定(Input Binding),绑定触发行为事件的外部输入,每个输入绑定还可以有多个输入绑定分量(composite Binding)
Action type
类型 | 用途 | 特点/适用场景 |
---|---|---|
1. Value | 值类型(用于连续变化的输入) | 如:鼠标移动、摇杆移动只会从一个设备接收输入 |
2. Button | 按钮类型(用于离散触发的动作) | 每次按下就触发一次,如:跳跃、攻击按钮 |
3. Pass Through | 直通类型(类似 Value) | 会同时接收多个设备的输入,例如多个手柄 |
实例
Chinese temple案例(使用playerInput组件)
public class StarterAssetsInputs : MonoBehaviour
{
[Header("Character Input Values")]
[SerializeField]private Vector2 move;
[SerializeField]private Vector2 look;
[SerializeField]private bool jump;
[SerializeField]private bool sprint;
[SerializeField]private bool pause;
[Header("Movement Settings")]
public bool analogMovement;
[Header("Mouse Cursor Settings")]
//[SerializeField] private bool cursorLocked = true;
public bool cursorInputForLook = true;
#if ENABLE_INPUT_SYSTEM
#region Get
public void OnMove(InputAction.CallbackContext value)
{
MoveInput(value.ReadValue<Vector2>());
}
public void OnLook(InputAction.CallbackContext value)
{
if(cursorInputForLook)
{
LookInput(value.ReadValue<Vector2>());
}
}
public void OnJump(InputAction.CallbackContext value)
{
JumpInput(value.action.triggered);
}
public void OnSprint(InputAction.CallbackContext value)
{
SprintInput(value.action.ReadValue<float>()==1);//如果是1返回true,伪triggar
}
public void OnPause(InputAction.CallbackContext value)
{
PauseInput(value.action.triggered);
}
#endregion
#endif
#region Set
public void MoveInput(Vector2 newMoveDirection)
{
move = newMoveDirection;
}
public void LookInput(Vector2 newLookDirection)
{
look = newLookDirection;
}
public void JumpInput(bool newJumpState)
{
jump = newJumpState;
}
public void SprintInput(bool newSprintState)
{
sprint = newSprintState;
}
public void PauseInput(bool newPauseState)
{
pause = newPauseState;
}
#endregion
# region encapsulation
public Vector2 MoveInput()
{
return move;
}
public Vector2 LookInput()
{
return look;
}
public bool JumpInput()
{
return jump;
}
public bool SprintInput()
{
return sprint;
}
public bool PauseInput()
{
return pause;
}
#endregion
// private void OnApplicationFocus(bool hasFocus)
//{
// SetCursorState(cursorLocked);
//}退出程序时将鼠标设置在中间锁定,我不需要这个功能
//private void SetCursorState(bool newState)
//{
// Cursor.lockState = newState ? CursorLockMode.Locked : CursorLockMode.None;
//}
}
使用:
private StarterAssetsInputs _input;
...
Vector2 move = _input.MoveInput();
...
Vector3 inputDirection = new Vector3(move.x, 0.0f, move.y).normalized;
不用playerInput组件
生成Input Actions并生成C#脚本文件后,在事件响应类中引用用new关键字生成该脚本文件的实例
需要在OnEnable、OnDisable生命周期函数中启用和禁用该脚本文件
public class InputService : MonoSingleton<InputService>
{
public InputMap inputMap;
protected override void Awake()
{
base.Awake();
if (inputMap == null)
{
inputMap = new InputMap();
}
inputMap.Enable();
}
private void OnDestroy()
{
inputMap.Disable();
}
/// <summary>
/// 封装走和跑以及PC和安卓的区别的移动量
/// </summary>
public Vector2 GetMoveHorizontalValue
{
get
{
//安卓
#if UNITY_ANDROID
return inputMap.Player.Move.ReadValue<Vector2>();
//非安卓
#elif !UNITY_ANDROID
Vector2 dir = inputMap.Player.Move.ReadValue<Vector2>();
bool isShift = inputMap.Player.Shift.ReadValue<float>()!=0;
if (dir != Vector2.zero && isShift)
{
dir.y = 0;
return dir.normalized;
}
else if (dir != Vector2.zero && !isShift)
{
dir.y = 0;
return dir.normalized;
}
else
{
return Vector2.zero;
}
#else
return 0f; // 默认值
#endif
}
}
public Vector2 GetMoveVerticalValue
{
get
{
Vector2 dir = inputMap.Player.Move.ReadValue<Vector2>();
if (dir != Vector2.zero)
{
dir.x = 0;
return dir.normalized;
}
else
{
return Vector2.zero;
}
}
}
public bool Interactive => inputMap.Player.Interactive.ReadValue<float>()!= 0;
public bool Shift
{
get
{
return inputMap.Player.Shift.ReadValue<float>() != 0;
}
}
public Vector2 Move
{
get
{
Vector2 vector2 = inputMap.Player.Move.ReadValue<Vector2>();
if (vector2.x > 0)
{
vector2.x = 1;
}
else if (vector2.x < 0)
{
vector2.x = -1;
}
else
{
vector2.x = 0;
}
if (vector2.y > 0)
{
vector2.y = 1;
}
else if (vector2.y < 0)
{
vector2.y = -1;
}
else
{
vector2.y = 0;
}
return vector2;
}
}
public Vector2 Scroll =>inputMap.Player.Scroll.ReadValue<Vector2>();
}