前言
新输入系统主要有两种方式,一种是全局的InputActions直接用new获取
UIInputActions = new PlayerInputActions();
UIInputActions.Enable();
inputActions.Player.Attack.performed += OnAttack;
另一种是在组件上挂载PlayerInpput,好处是可以区分不同玩家,精细的禁用单个行为,但是使用比较麻烦
最重要的还是要用字符串加载,很不灵活
private InputAction counterAttackAction;
playerInput = GetComponent<PlayerInput>();
attackAction = playerInput.actions["Attack"];
attackAction.performed += OnAttack;
但其实都是获取action,如果能够把playerinput封装的和inputactions一样,就可以完全替代
我也是突然想到PlayerInputActions本质就是json文件,那么直接读取这个json文件,就可以自动生成需要的代码了
实践
所以我用ai辅助写了自动生成代码的脚本,直接从PlayerInputActions.inputactions读取数据,自动生成类
这是生成的类:
public partial class Player
{
public InputAction moveAction;
private void InitActions()
{
moveAction = playerInput.actions["Move"];
然后可以比InputActions更简单的调用
private Vector2 MoveVector => moveAction.ReadValue<Vector2>();
private bool HasJumpInput => jumpAction.ReadValue<float>() > 0;
private void InputBinding()
{
InitActions();
// Subscribe to action events
aimSwordAction.performed += OnAimSword;
用于自动生成的脚本
class InputCodeGenerator
{
[MenuItem("Tools/Generate Code from InputActions")]
public static void GenerateCodeFromInputActions()
{
// 找到 PlayerInputActions 的 InputActionAsset
var playerInputActions = AssetDatabase.LoadAssetAtPath<InputActionAsset>("Assets/Settings/Input/PlayerInputActions.inputactions");
if (playerInputActions == null)
{
Debug.LogError("PlayerInputActions.inputactions not found!");
return;
}
StringBuilder codeBuilder = new StringBuilder();
codeBuilder.AppendLine("using UnityEngine;");
codeBuilder.AppendLine("using UnityEngine.InputSystem;");
codeBuilder.AppendLine();
codeBuilder.AppendLine("public partial class Player");
codeBuilder.AppendLine("{");
// codeBuilder.AppendLine(" private PlayerInput playerInput;");
codeBuilder.AppendLine();
// 生成字段和初始化代码
foreach (var map in playerInputActions.actionMaps)
{
foreach (var action in map.actions)
{
string actionName = char.ToLower(action.name[0]) + action.name.Substring(1);
codeBuilder.AppendLine($" public InputAction {
actionName}Action;");
// codeBuilder.AppendLine($" private void On{action.name}(InputAction.CallbackContext context) {
{ \n }}");
}
}
codeBuilder.AppendLine();
codeBuilder.AppendLine(" private void InitActions()");
codeBuilder.AppendLine(" {");
// codeBuilder.AppendLine(" playerInput = GetComponent<PlayerInput>();");
// 生成动作绑定代码
foreach (var map in playerInputActions.actionMaps)
{
foreach (var action in map.actions)
{
string actionName = char.ToLower(action.name[0]) + action.name.Substring(1);
codeBuilder.AppendLine($" {
actionName}Action = playerInput.actions[\"{
action.name}\"];");
// codeBuilder.AppendLine($" {actionName}Action.performed += On{action.name};");
}
}
codeBuilder.AppendLine(" }");
codeBuilder.AppendLine("}");
// 写入文件
string path = "Assets/Scripts/Player/BasePlayerInput.cs";
File.WriteAllText(path, codeBuilder.ToString());
AssetDatabase.Refresh();
Debug.Log("PlayerController.cs generated successfully.");
}
}