【Unity游戏开发】PlayerInput最佳实践,自动生成actions代码

前言

新输入系统主要有两种方式,一种是全局的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.");
    }
}

猜你喜欢

转载自blog.csdn.net/zhuanggenhua/article/details/142816316
今日推荐