10.输入模块

10.输入模块


10.1 知识点

输入模块的作用

在游戏开发中,我们经常需要处理键盘和鼠标输入。传统的做法是在各个脚本的Update中直接调用Unity的Input类进行检测,这会导致以下问题:

核心问题:

  • 代码耦合性高:输入检测逻辑分散在各个模块中
  • 重复代码多:每个模块都需要重复编写输入检测代码
  • 难以改键:需要修改多个地方的代码才能改变按键映射
  • 缺乏统一管理:无法统一控制输入系统的开启和关闭

解决方案:
通过独立的输入管理模块,统一管理所有键盘和鼠标输入,利用事件中心分发输入事件,实现输入逻辑与业务逻辑的解耦。

主要功能:

  1. 统一输入管理:在输入管理器中进行所有按键检测
  2. 事件分发:通过事件中心分发输入事件
  3. 支持改键功能:可以动态修改按键映射
  4. 输入检测开关:提供开启和关闭输入检测的功能
  5. 获取输入信息:支持获取任意按键的输入信息(用于改键)

输入模块的基本原理

设计理念:

  • 集中管理:统一管理所有键盘和鼠标输入
  • 事件驱动:通过事件中心实现输入与业务逻辑的解耦
  • 可配置性:支持动态配置和修改按键映射
  • 灵活扩展:支持键盘、鼠标和Unity Axes输入

工作流程:

  1. 输入检测:在InputMgr的Update中检测键盘和鼠标输入
  2. 事件映射:根据配置的按键映射判断触发哪个事件
  3. 事件分发:通过事件中心分发对应的输入事件
  4. 业务处理:各个模块监听对应的输入事件并处理业务逻辑

输入模块基础实现

为什么需要输入模块

传统输入处理方式的问题:

// 传统方式:在各个脚本中直接检测输入
public class Player : MonoBehaviour
{
    void Update()
    {
        // 移动逻辑
        if (Input.GetKey(KeyCode.W))
        {
            transform.Translate(Vector3.forward * Time.deltaTime);
        }
        if (Input.GetKey(KeyCode.S))
        {
            transform.Translate(Vector3.back * Time.deltaTime);
        }
        
        // 攻击逻辑
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Attack();
        }
        
        // 技能逻辑
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            UseSkill1();
        }
    }
}

存在的问题:

  1. 高耦合:业务逻辑与输入检测耦合在一起
  2. 难以扩展:添加新角色需要重复编写输入检测代码
  3. 难以改键:需要修改多处代码才能改变按键
  4. 难以测试:输入逻辑与业务逻辑混合,难以独立测试

输入模块基本实现

实现思路:

  1. 制作InputMgr单例模式管理器:统一管理所有输入检测
  2. 在Update中检测按键:检测常用按键(W、A、S、D、鼠标按键等)
  3. 通过事件中心分发事件:输入检测到后触发相应事件
  4. 业务模块监听事件:各个模块监听输入事件并处理业务逻辑

基础源码实现:InputMgr.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class InputMgr : Singleton<InputMgr>
{
    //是否开启了输入系统检测
    private bool isStart;

    private InputMgr()
    {
        MonoMgr.Instance.AddUpdateListener(InputUpdate);
    }

    /// <summary>
    /// 开启或者关闭我们的输入管理模块的检测
    /// </summary>
    /// <param name="isStart">是否开启检测</param>
    public void StartOrCloseInputMgr(bool isStart)
    {
        this.isStart = isStart;
    }

    /// <summary>
    /// 输入检测更新
    /// </summary>
    private void InputUpdate()
    {
        //如果外部没有开启检测功能 就不要检测
        if (!isStart)
            return;

        // 检测键盘按键
        CheckKeyCode(KeyCode.W);
        CheckKeyCode(KeyCode.A);
        CheckKeyCode(KeyCode.S);
        CheckKeyCode(KeyCode.D);

        CheckKeyCode(KeyCode.H);
        CheckKeyCode(KeyCode.J);
        CheckKeyCode(KeyCode.K);
        CheckKeyCode(KeyCode.L);

        // 检测鼠标按键
        CheckMouse(0); // 左键
        CheckMouse(1); // 右键

        // 检测Unity Axes
        EventCenter.Instance.EventTrigger<float>(E_EventType.E_Input_Horizontal, Input.GetAxis("Horizontal"));
        EventCenter.Instance.EventTrigger<float>(E_EventType.E_Input_Vertical, Input.GetAxis("Vertical"));
    }

    /// <summary>
    /// 检测键盘按键
    /// </summary>
    /// <param name="key">按键代码</param>
    private void CheckKeyCode(KeyCode key)
    {
        // 按下
        if (Input.GetKeyDown(key))
        {
            EventCenter.Instance.EventTrigger(E_EventType.E_Keyboard_Down, key);
        }

        // 抬起
        if (Input.GetKeyUp(key))
        {
            EventCenter.Instance.EventTrigger(E_EventType.E_Keyboard_Up, key);
        }

        // 长按
        if (Input.GetKey(key))
        {
            EventCenter.Instance.EventTrigger(E_EventType.E_Keyboard, key);
        }
    }

    /// <summary>
    /// 检测鼠标按键
    /// </summary>
    /// <param name="mouseID">鼠标按键ID(0=左键,1=右键,2=中键)</param>
    private void CheckMouse(int mouseID)
    {
        // 按下
        if (Input.GetMouseButtonDown(mouseID))
        {
            EventCenter.Instance.EventTrigger(E_EventType.E_Mouse_Down, mouseID);
        }

        // 抬起
        if (Input.GetMouseButtonUp(mouseID))
        {
            EventCenter.Instance.EventTrigger(E_EventType.E_Mouse_Up, mouseID);
        }

        // 长按
        if (Input.GetMouseButton(mouseID))
        {
            EventCenter.Instance.EventTrigger(E_EventType.E_Mouse, mouseID);
        }
    }
}

使用示例:

using UnityEngine;

public class InputModuleTest : MonoBehaviour
{
    void Start()
    {
        Debug.Log("输入模块测试:开始");
        
        // 开启输入检测
        InputMgr.Instance.StartOrCloseInputMgr(true);
        
        // 监听键盘按键事件
        EventCenter.Instance.AddEventListener<KeyCode>(E_EventType.E_Keyboard_Down, OnKeyDown);
        EventCenter.Instance.AddEventListener<KeyCode>(E_EventType.E_Keyboard_Up, OnKeyUp);
        EventCenter.Instance.AddEventListener<KeyCode>(E_EventType.E_Keyboard, OnKeyPressed);
        
        // 监听鼠标事件
        EventCenter.Instance.AddEventListener<int>(E_EventType.E_Mouse_Down, OnMouseDown);
        
        // 监听Axis事件
        EventCenter.Instance.AddEventListener<float>(E_EventType.E_Input_Horizontal, OnHorizontalMove);
        EventCenter.Instance.AddEventListener<float>(E_EventType.E_Input_Vertical, OnVerticalMove);
    }

    private void OnKeyDown(KeyCode key)
    {
        Debug.Log($"键盘按下:{key}");
        // 输出:键盘按下:W
    }

    private void OnKeyUp(KeyCode key)
    {
        Debug.Log($"键盘抬起:{key}");
        // 输出:键盘抬起:W
    }

    private void OnKeyPressed(KeyCode key)
    {
        Debug.Log($"键盘长按:{key}");
        // 输出:键盘长按:W(每帧)
    }

    private void OnMouseDown(int mouseID)
    {
        Debug.Log($"鼠标按下:{mouseID}");
        // 输出:鼠标按下:0(左键)
    }

    private void OnHorizontalMove(float value)
    {
        // 水平移动(-1~1)
        Debug.Log($"水平输入:{value}");
    }

    private void OnVerticalMove(float value)
    {
        // 垂直移动(-1~1)
        Debug.Log($"垂直输入:{value}");
    }

    void OnDestroy()
    {
        // 移除事件监听
        EventCenter.Instance.RemoveEventListener<KeyCode>(E_EventType.E_Keyboard_Down, OnKeyDown);
        EventCenter.Instance.RemoveEventListener<KeyCode>(E_EventType.E_Keyboard_Up, OnKeyUp);
        EventCenter.Instance.RemoveEventListener<KeyCode>(E_EventType.E_Keyboard, OnKeyPressed);
        EventCenter.Instance.RemoveEventListener<int>(E_EventType.E_Mouse_Down, OnMouseDown);
        EventCenter.Instance.RemoveEventListener<float>(E_EventType.E_Input_Horizontal, OnHorizontalMove);
        EventCenter.Instance.RemoveEventListener<float>(E_EventType.E_Input_Vertical, OnVerticalMove);
    }
}

基础实现的局限性

存在的问题:

  1. 按键写死:只能检测固定的几个按键
  2. 无法改键:想要改变按键映射需要修改代码
  3. 行为固定:每个按键都只能触发特定的事件类型
  4. 缺乏灵活性:无法根据游戏需求灵活配置按键

输入模块改键功能优化

为什么需要改键功能

应用场景:
在游戏中,玩家希望能够自定义按键映射:

  • 角色移动:WASD、方向键或其他按键
  • 技能释放:数字键1-9或其他按键
  • 攻击按键:鼠标左键、右键或其他按键
  • 交互按键:E键、F键或其他按键

需求分析:

  1. 改键功能应该是针对某一个行为的:游戏中的行为是固定的,我们需要改变的是触发该行为的按键
  2. 具体键位的触发不应该写死:需要根据存储的键位数据进行初始化或进行修改
  3. 键位的修改可以是键盘输入,也可以是鼠标输入,输入类型也可以是任意的

实现改键功能

设计思路:

  1. 创建InputInfo类:用于存储按键信息(键盘或鼠标、按下或抬起或长按、具体按键)
  2. 使用字典存储映射:Dictionary<事件类型, InputInfo>
  3. 提供配置方法:提供ChangeKeyboardInfo和ChangeMouseInfo方法用于配置按键
  4. 动态检测输入:根据配置的映射关系动态检测输入

InputInfo实现:InputInfo.cs

using UnityEngine;

/// <summary>
/// 输入信息类
/// 用于存储和管理键盘和鼠标的输入信息
/// </summary>
public class InputInfo
{
    #region 枚举

    /// <summary>
    /// 键盘或鼠标枚举
    /// </summary>
    public enum E_KeyOrMouse
    {
        /// <summary>
        /// 键盘输入
        /// </summary>
        Key,
        /// <summary>
        /// 鼠标输入
        /// </summary>
        Mouse,
    }

    /// <summary>
    /// 输入类型枚举
    /// </summary>
    public enum E_InputType
    {
        /// <summary>
        /// 按下
        /// </summary>
        Down,
        /// <summary>
        /// 抬起
        /// </summary>
        Up,
        /// <summary>
        /// 长按
        /// </summary>
        Always,
    }

    #endregion

    #region 字段

    /// <summary>
    /// 具体输入的类型——键盘还是鼠标
    /// </summary>
    public E_KeyOrMouse keyOrMouse;

    /// <summary>
    /// 输入的类型——抬起、按下、长按
    /// </summary>
    public E_InputType inputType;

    /// <summary>
    /// KeyCode
    /// </summary>
    public KeyCode key;

    /// <summary>
    /// mouseID
    /// </summary>
    public int mouseID;

    #endregion

    #region 构造函数

    /// <summary>
    /// 主要给键盘输入初始化
    /// </summary>
    /// <param name="inputType">输入类型</param>
    /// <param name="key">按键代码</param>
    public InputInfo(E_InputType inputType, KeyCode key)
    {
        this.keyOrMouse = E_KeyOrMouse.Key;
        this.inputType = inputType;
        this.key = key;
    }

    /// <summary>
    /// 主要给鼠标输入初始化
    /// </summary>
    /// <param name="inputType">输入类型</param>
    /// <param name="mouseID">鼠标按键ID</param>
    public InputInfo(E_InputType inputType, int mouseID)
    {
        this.keyOrMouse = E_KeyOrMouse.Mouse;
        this.inputType = inputType;
        this.mouseID = mouseID;
    }

    #endregion
}

InputMgr改键功能实现:InputMgr.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class InputMgr : Singleton<InputMgr>
{
    /// <summary>
    /// 输入信息字典
    /// 键:事件类型
    /// 值:输入信息
    /// </summary>
    private Dictionary<E_EventType, InputInfo> inputDic = new Dictionary<E_EventType, InputInfo>();

    /// <summary>
    /// 当前遍历时取出的输入信息
    /// </summary>
    private InputInfo nowInputInfo;

    /// <summary>
    /// 是否开启了输入系统检测
    /// </summary>
    private bool isStart;

    private InputMgr()
    {
        MonoMgr.Instance.AddUpdateListener(InputUpdate);
    }

    /// <summary>
    /// 开启或者关闭我们的输入管理模块的检测
    /// </summary>
    /// <param name="isStart">是否开启检测</param>
    public void StartOrCloseInputMgr(bool isStart)
    {
        this.isStart = isStart;
    }

    /// <summary>
    /// 提供给外部改键或初始化的方法(键盘)
    /// </summary>
    /// <param name="eventType">事件类型</param>
    /// <param name="key">按键代码</param>
    /// <param name="inputType">输入类型</param>
    public void ChangeKeyboardInfo(E_EventType eventType, KeyCode key, InputInfo.E_InputType inputType)
    {
        // 初始化
        if (!inputDic.ContainsKey(eventType))
        {
            inputDic.Add(eventType, new InputInfo(inputType, key));
        }
        else // 改键
        {
            // 如果之前是鼠标 我们必须要修改它的按键类型
            inputDic[eventType].keyOrMouse = InputInfo.E_KeyOrMouse.Key;
            inputDic[eventType].key = key;
            inputDic[eventType].inputType = inputType;
        }
    }

    /// <summary>
    /// 提供给外部改键或初始化的方法(鼠标)
    /// </summary>
    /// <param name="eventType">事件类型</param>
    /// <param name="mouseID">鼠标按键ID</param>
    /// <param name="inputType">输入类型</param>
    public void ChangeMouseInfo(E_EventType eventType, int mouseID, InputInfo.E_InputType inputType)
    {
        // 初始化
        if (!inputDic.ContainsKey(eventType))
        {
            inputDic.Add(eventType, new InputInfo(inputType, mouseID));
        }
        else // 改键
        {
            // 如果之前是鼠标 我们必须要修改它的按键类型
            inputDic[eventType].keyOrMouse = InputInfo.E_KeyOrMouse.Mouse;
            inputDic[eventType].mouseID = mouseID;
            inputDic[eventType].inputType = inputType;
        }
    }

    /// <summary>
    /// 移除指定行为的输入监听
    /// </summary>
    /// <param name="eventType">事件类型</param>
    public void RemoveInputInfo(E_EventType eventType)
    {
        if (inputDic.ContainsKey(eventType))
            inputDic.Remove(eventType);
    }

    /// <summary>
    /// 输入检测更新
    /// </summary>
    private void InputUpdate()
    {
        // 如果外部没有开启检测功能 就不要检测
        if (!isStart)
            return;

        // 遍历配置的输入映射
        foreach (E_EventType eventType in inputDic.Keys)
        {
            nowInputInfo = inputDic[eventType];
            // 如果是键盘输入
            if (nowInputInfo.keyOrMouse == InputInfo.E_KeyOrMouse.Key)
            {
                // 是抬起还是按下还是长按
                switch (nowInputInfo.inputType)
                {
                    case InputInfo.E_InputType.Down:
                        if (Input.GetKeyDown(nowInputInfo.key))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    case InputInfo.E_InputType.Up:
                        if (Input.GetKeyUp(nowInputInfo.key))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    case InputInfo.E_InputType.Always:
                        if (Input.GetKey(nowInputInfo.key))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    default:
                        break;
                }
            }
            // 如果是鼠标输入
            else
            {
                switch (nowInputInfo.inputType)
                {
                    case InputInfo.E_InputType.Down:
                        if (Input.GetMouseButtonDown(nowInputInfo.mouseID))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    case InputInfo.E_InputType.Up:
                        if (Input.GetMouseButtonUp(nowInputInfo.mouseID))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    case InputInfo.E_InputType.Always:
                        if (Input.GetMouseButton(nowInputInfo.mouseID))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    default:
                        break;
                }
            }
        }

        // 始终检测Unity Axes
        EventCenter.Instance.EventTrigger<float>(E_EventType.E_Input_Horizontal, Input.GetAxis("Horizontal"));
        EventCenter.Instance.EventTrigger<float>(E_EventType.E_Input_Vertical, Input.GetAxis("Vertical"));
    }
}

改键功能使用示例:

using UnityEngine;

public class KeyRemappingTest : MonoBehaviour
{
    void Start()
    {
        Debug.Log("改键功能测试:开始");
        
        // 开启输入检测
        InputMgr.Instance.StartOrCloseInputMgr(true);
        
        // 配置初始按键映射
        InitializeKeyMapping();
        
        // 监听技能事件
        EventCenter.Instance.AddEventListener(E_EventType.E_Input_Skill1, OnSkill1);
        EventCenter.Instance.AddEventListener(E_EventType.E_Input_Skill2, OnSkill2);
        EventCenter.Instance.AddEventListener(E_EventType.E_Input_Skill3, OnSkill3);
        
        // 延迟3秒后测试改键
        Invoke("TestKeyRemapping", 3f);
    }

    /// <summary>
    /// 初始化按键映射
    /// </summary>
    private void InitializeKeyMapping()
    {
        // 技能1绑定到数字键1
        InputMgr.Instance.ChangeKeyboardInfo(E_EventType.E_Input_Skill1, KeyCode.Alpha1, InputInfo.E_InputType.Down);
        
        // 技能2绑定到数字键2
        InputMgr.Instance.ChangeKeyboardInfo(E_EventType.E_Input_Skill2, KeyCode.Alpha2, InputInfo.E_InputType.Down);
        
        // 技能3绑定到数字键3
        InputMgr.Instance.ChangeKeyboardInfo(E_EventType.E_Input_Skill3, KeyCode.Alpha3, InputInfo.E_InputType.Down);
        
        Debug.Log("初始按键映射配置完成");
        // 输出:初始按键映射配置完成
    }

    private void OnSkill1()
    {
        Debug.Log("技能1释放");
        // 输出:技能1释放
    }

    private void OnSkill2()
    {
        Debug.Log("技能2释放");
        // 输出:技能2释放
    }

    private void OnSkill3()
    {
        Debug.Log("技能3释放");
        // 输出:技能3释放
    }

    /// <summary>
    /// 测试改键功能
    /// </summary>
    private void TestKeyRemapping()
    {
        Debug.Log("测试改键功能");
        
        // 改键:将技能1改为鼠标左键
        InputMgr.Instance.ChangeMouseInfo(E_EventType.E_Input_Skill1, 0, InputInfo.E_InputType.Down);
        Debug.Log("技能1已改为鼠标左键");
        
        // 改键:将技能2改为Q键
        InputMgr.Instance.ChangeKeyboardInfo(E_EventType.E_Input_Skill2, KeyCode.Q, InputInfo.E_InputType.Down);
        Debug.Log("技能2已改为Q键");
        
        // 改键:将技能3改为长按E键
        InputMgr.Instance.ChangeKeyboardInfo(E_EventType.E_Input_Skill3, KeyCode.E, InputInfo.E_InputType.Always);
        Debug.Log("技能3已改为长按E键");
    }

    void OnDestroy()
    {
        // 移除事件监听
        EventCenter.Instance.RemoveEventListener(E_EventType.E_Input_Skill1, OnSkill1);
        EventCenter.Instance.RemoveEventListener(E_EventType.E_Input_Skill2, OnSkill2);
        EventCenter.Instance.RemoveEventListener(E_EventType.E_Input_Skill3, OnSkill3);
    }
}

输入模块获取输入信息优化

为什么需要获取输入信息功能

应用场景:
在做改键功能时,我们需要让玩家按下任意按键来重新绑定。这时就需要能够获取用户按下的任意按键信息。

需求分析:

  1. 获取任意键盘按键:遍历所有KeyCode,检测哪个按键被按下
  2. 获取任意鼠标按键:检测鼠标左、中、右键哪个被按下
  3. 延迟一帧检测:避免开启检测时立刻触发当前的输入

实现思路:

  1. 遍历KeyCode枚举:使用Enum.GetValues(typeof(KeyCode))获取所有按键
  2. 逐帧检测输入:只有当Input.anyKeyDown为true时才开始检测
  3. 延迟一帧:使用协程延迟一帧再开始检测,避免立即触发
  4. 返回输入信息:通过委托将检测到的输入信息返回给外部

获取输入信息功能实现

InputMgr增强版:InputMgr.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class InputMgr : Singleton<InputMgr>
{
    private Dictionary<E_EventType, InputInfo> inputDic = new Dictionary<E_EventType, InputInfo>();

    // 当前遍历时取出的输入信息
    private InputInfo nowInputInfo;

    // 是否开启了输入系统检测
    private bool isStart;

    // 用于在改键时获取输入信息的委托 只有当update中获取到信息的时候 再通过委托传递给外部
    private UnityAction<InputInfo> getInputInfoCallBack;

    // 是否开始检测输入信息
    private bool isBeginCheckInput = false;

    private InputMgr()
    {
        MonoMgr.Instance.AddUpdateListener(InputUpdate);
    }

    /// <summary>
    /// 开启或者关闭我们的输入管理模块的检测
    /// </summary>
    /// <param name="isStart">是否开启检测</param>
    public void StartOrCloseInputMgr(bool isStart)
    {
        this.isStart = isStart;
    }

    /// <summary>
    /// 提供给外部改键或初始化的方法(键盘)
    /// </summary>
    public void ChangeKeyboardInfo(E_EventType eventType, KeyCode key, InputInfo.E_InputType inputType)
    {
        // 初始化
        if (!inputDic.ContainsKey(eventType))
        {
            inputDic.Add(eventType, new InputInfo(inputType, key));
        }
        else // 改键
        {
            inputDic[eventType].keyOrMouse = InputInfo.E_KeyOrMouse.Key;
            inputDic[eventType].key = key;
            inputDic[eventType].inputType = inputType;
        }
    }

    /// <summary>
    /// 提供给外部改键或初始化的方法(鼠标)
    /// </summary>
    public void ChangeMouseInfo(E_EventType eventType, int mouseID, InputInfo.E_InputType inputType)
    {
        // 初始化
        if (!inputDic.ContainsKey(eventType))
        {
            inputDic.Add(eventType, new InputInfo(inputType, mouseID));
        }
        else // 改键
        {
            inputDic[eventType].keyOrMouse = InputInfo.E_KeyOrMouse.Mouse;
            inputDic[eventType].mouseID = mouseID;
            inputDic[eventType].inputType = inputType;
        }
    }

    /// <summary>
    /// 移除指定行为的输入监听
    /// </summary>
    /// <param name="eventType">事件类型</param>
    public void RemoveInputInfo(E_EventType eventType)
    {
        if (inputDic.ContainsKey(eventType))
            inputDic.Remove(eventType);
    }

    /// <summary>
    /// 获取下一次的输入信息
    /// 用于改键功能中,等待玩家按下任意按键
    /// </summary>
    /// <param name="callBack">输入信息回调</param>
    public void GetInputInfo(UnityAction<InputInfo> callBack)
    {
        getInputInfoCallBack = callBack;
        MonoMgr.Instance.StartCoroutine(BeginCheckInput());
    }

    /// <summary>
    /// 延迟一帧开始检测输入
    /// 避免开启检测时立刻触发当前的输入
    /// </summary>
    private IEnumerator BeginCheckInput()
    {
        // 等一帧
        yield return 0;
        // 一帧后才会被置成true
        isBeginCheckInput = true;
    }

    /// <summary>
    /// 输入检测更新
    /// </summary>
    private void InputUpdate()
    {
        // 当委托不为空时 证明想要获取到输入的信息 传递给外部
        if (isBeginCheckInput)
        {
            // 当一个键按下时 然后遍历所有按键信息 得到是谁被按下了
            if (Input.anyKeyDown)
            {
                InputInfo inputInfo = null;
                
                // 我们需要去遍历监听所有键位的按下 来得到对应输入的信息
                // 键盘
                Array keyCodes = Enum.GetValues(typeof(KeyCode));
                foreach (KeyCode inputKey in keyCodes)
                {
                    // 判断到底是谁被按下了 那么就可以得到对应的输入的键盘信息
                    if (Input.GetKeyDown(inputKey))
                    {
                        inputInfo = new InputInfo(InputInfo.E_InputType.Down, inputKey);
                        break;
                    }
                }
                
                // 鼠标
                if (inputInfo == null)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        if (Input.GetMouseButtonDown(i))
                        {
                            inputInfo = new InputInfo(InputInfo.E_InputType.Down, i);
                            break;
                        }
                    }
                }
                
                // 把获取到的信息传递给外部
                getInputInfoCallBack?.Invoke(inputInfo);
                getInputInfoCallBack = null;
                // 检测一次后就停止检测了
                isBeginCheckInput = false;
            }
        }

        // 如果外部没有开启检测功能 就不要检测
        if (!isStart)
            return;

        // 遍历配置的输入映射并检测输入
        foreach (E_EventType eventType in inputDic.Keys)
        {
            nowInputInfo = inputDic[eventType];
            // 如果是键盘输入
            if (nowInputInfo.keyOrMouse == InputInfo.E_KeyOrMouse.Key)
            {
                // 是抬起还是按下还是长按
                switch (nowInputInfo.inputType)
                {
                    case InputInfo.E_InputType.Down:
                        if (Input.GetKeyDown(nowInputInfo.key))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    case InputInfo.E_InputType.Up:
                        if (Input.GetKeyUp(nowInputInfo.key))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    case InputInfo.E_InputType.Always:
                        if (Input.GetKey(nowInputInfo.key))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    default:
                        break;
                }
            }
            // 如果是鼠标输入
            else
            {
                switch (nowInputInfo.inputType)
                {
                    case InputInfo.E_InputType.Down:
                        if (Input.GetMouseButtonDown(nowInputInfo.mouseID))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    case InputInfo.E_InputType.Up:
                        if (Input.GetMouseButtonUp(nowInputInfo.mouseID))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    case InputInfo.E_InputType.Always:
                        if (Input.GetMouseButton(nowInputInfo.mouseID))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    default:
                        break;
                }
            }
        }

        // 始终检测Unity Axes
        EventCenter.Instance.EventTrigger<float>(E_EventType.E_Input_Horizontal, Input.GetAxis("Horizontal"));
        EventCenter.Instance.EventTrigger<float>(E_EventType.E_Input_Vertical, Input.GetAxis("Vertical"));
    }
}

获取输入信息功能使用示例:

using UnityEngine;

public class GetInputInfoTest : MonoBehaviour
{
    void Start()
    {
        Debug.Log("获取输入信息测试:开始");
        
        // 测试获取输入信息
        TestGetInputInfo();
    }

    /// <summary>
    /// 测试获取输入信息
    /// </summary>
    private void TestGetInputInfo()
    {
        Debug.Log("等待用户按下任意按键...");
        
        // 获取下一个按键输入
        InputMgr.Instance.GetInputInfo((inputInfo) =>
        {
            if (inputInfo != null)
            {
                if (inputInfo.keyOrMouse == InputInfo.E_KeyOrMouse.Key)
                {
                    Debug.Log($"检测到键盘按键:{inputInfo.key}");
                    // 输出:检测到键盘按键:Q
                }
                else
                {
                    Debug.Log($"检测到鼠标按键:{inputInfo.mouseID}");
                    // 输出:检测到鼠标按键:0
                }
                
                // 可以根据获取到的输入信息进行改键
                OnKeyRemap(inputInfo);
            }
            else
            {
                Debug.Log("未检测到有效输入");
            }
        });
    }

    /// <summary>
    /// 根据输入信息进行改键
    /// </summary>
    private void OnKeyRemap(InputInfo inputInfo)
    {
        Debug.Log("开始改键...");
        
        // 根据获取到的输入信息改键技能1
        if (inputInfo.keyOrMouse == InputInfo.E_KeyOrMouse.Key)
        {
            InputMgr.Instance.ChangeKeyboardInfo(
                E_EventType.E_Input_Skill1,
                inputInfo.key,
                InputInfo.E_InputType.Down
            );
            Debug.Log($"技能1已改键为:{inputInfo.key}");
        }
        else
        {
            InputMgr.Instance.ChangeMouseInfo(
                E_EventType.E_Input_Skill1,
                inputInfo.mouseID,
                InputInfo.E_InputType.Down
            );
            Debug.Log($"技能1已改键为:鼠标{inputInfo.mouseID}");
        }
        
        Debug.Log("改键完成");
    }
}

测试和使用

创建一个完整的改键系统,结合UI模块实现可视化改键:

using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// 改键系统
/// 演示如何使用InputMgr实现完整的改键功能
/// </summary>
public class KeyRemappingSystem : MonoBehaviour
{
    private Button skill1Button;
    private Button skill2Button;
    private Button skill3Button;
    private Text skill1Text;
    private Text skill2Text;
    private Text skill3Text;

    void Start()
    {
        Debug.Log("改键系统测试:开始");
        
        // 开启输入检测
        InputMgr.Instance.StartOrCloseInputMgr(true);
        
        // 初始化按键映射
        InitializeKeyMapping();
        
        // 监听技能事件
        ListenToSkillEvents();
        
        // 初始化UI(假设已经通过GetControl获取到按钮)
        InitializeUI();
    }

    /// <summary>
    /// 初始化按键映射
    /// </summary>
    private void InitializeKeyMapping()
    {
        // 从配置文件读取按键映射(这里简化为直接设置)
        InputMgr.Instance.ChangeKeyboardInfo(
            E_EventType.E_Input_Skill1,
            KeyCode.Alpha1,
            InputInfo.E_InputType.Down
        );
        
        InputMgr.Instance.ChangeKeyboardInfo(
            E_EventType.E_Input_Skill2,
            KeyCode.Alpha2,
            InputInfo.E_InputType.Down
        );
        
        InputMgr.Instance.ChangeKeyboardInfo(
            E_EventType.E_Input_Skill3,
            KeyCode.Alpha3,
            InputInfo.E_InputType.Down
        );
        
        Debug.Log("按键映射初始化完成");
    }

    /// <summary>
    /// 监听技能事件
    /// </summary>
    private void ListenToSkillEvents()
    {
        EventCenter.Instance.AddEventListener(E_EventType.E_Input_Skill1, OnSkill1);
        EventCenter.Instance.AddEventListener(E_EventType.E_Input_Skill2, OnSkill2);
        EventCenter.Instance.AddEventListener(E_EventType.E_Input_Skill3, OnSkill3);
    }

    private void OnSkill1()
    {
        Debug.Log("技能1释放");
    }

    private void OnSkill2()
    {
        Debug.Log("技能2释放");
    }

    private void OnSkill3()
    {
        Debug.Log("技能3释放");
    }

    /// <summary>
    /// 初始化UI
    /// </summary>
    private void InitializeUI()
    {
        Debug.Log("UI初始化完成");
        // 实际项目中会在这里获取按钮和文本组件
    }

    /// <summary>
    /// 改键按钮点击事件
    /// </summary>
    public void OnRemapSkill1()
    {
        RemapKey(E_EventType.E_Input_Skill1, (keyName) =>
        {
            skill1Text.text = keyName;
        });
    }

    public void OnRemapSkill2()
    {
        RemapKey(E_EventType.E_Input_Skill2, (keyName) =>
        {
            skill2Text.text = keyName;
        });
    }

    public void OnRemapSkill3()
    {
        RemapKey(E_EventType.E_Input_Skill3, (keyName) =>
        {
            skill3Text.text = keyName;
        });
    }

    /// <summary>
    /// 改键流程
    /// </summary>
    /// <param name="eventType">要改键的事件类型</param>
    /// <param name="updateUI">更新UI的回调</param>
    private void RemapKey(E_EventType eventType, UnityAction<string> updateUI)
    {
        Debug.Log($"准备改键:{eventType}");
        
        // 1. 获取用户按下的下一个按键
        InputMgr.Instance.GetInputInfo((inputInfo) =>
        {
            if (inputInfo == null)
            {
                Debug.Log("未检测到有效输入");
                return;
            }
            
            // 2. 根据输入信息进行改键
            if (inputInfo.keyOrMouse == InputInfo.E_KeyOrMouse.Key)
            {
                InputMgr.Instance.ChangeKeyboardInfo(
                    eventType,
                    inputInfo.key,
                    InputInfo.E_InputType.Down
                );
                updateUI?.Invoke(inputInfo.key.ToString());
                Debug.Log($"{eventType}已改键为:{inputInfo.key}");
            }
            else
            {
                string mouseName = inputInfo.mouseID == 0 ? "左键" : 
                                   inputInfo.mouseID == 1 ? "右键" : "中键";
                InputMgr.Instance.ChangeMouseInfo(
                    eventType,
                    inputInfo.mouseID,
                    InputInfo.E_InputType.Down
                );
                updateUI?.Invoke($"鼠标{mouseName}");
                Debug.Log($"{eventType}已改键为:鼠标{mouseName}");
            }
        });
    }

    void OnDestroy()
    {
        // 移除事件监听
        EventCenter.Instance.RemoveEventListener(E_EventType.E_Input_Skill1, OnSkill1);
        EventCenter.Instance.RemoveEventListener(E_EventType.E_Input_Skill2, OnSkill2);
        EventCenter.Instance.RemoveEventListener(E_EventType.E_Input_Skill3, OnSkill3);
    }
}

进阶和拓展

进阶优化建议:

  1. 数据持久化:将按键配置保存到本地,下次启动时自动加载
  2. 多按键支持:支持组合键(如Ctrl+C)和长按键组合
  3. 输入冲突检测:检测是否有多个行为绑定到同一个按键
  4. 输入可视化:在游戏界面显示当前按键绑定
  5. 输入录制:支持录制玩家的输入操作并回放
  6. 新输入系统:使用新的InputSystem来制作输入模块

10.2 知识点代码

InputMgr.cs(输入管理器 - 最终版本)

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// 输入管理器
/// 统一管理所有键盘和鼠标输入,通过事件中心分发输入事件
/// 支持改键功能和获取任意输入信息
/// </summary>
public class InputMgr : Singleton<InputMgr>
{
    #region 字段

    /// <summary>
    /// 输入信息字典
    /// 键:事件类型
    /// 值:输入信息
    /// </summary>
    private Dictionary<E_EventType, InputInfo> inputDic = new Dictionary<E_EventType, InputInfo>();

    /// <summary>
    /// 当前遍历时取出的输入信息
    /// </summary>
    private InputInfo nowInputInfo;

    /// <summary>
    /// 是否开启了输入系统检测
    /// </summary>
    private bool isStart;

    /// <summary>
    /// 用于在改键时获取输入信息的委托
    /// 只有当update中获取到信息的时候 再通过委托传递给外部
    /// </summary>
    private UnityAction<InputInfo> getInputInfoCallBack;

    /// <summary>
    /// 是否开始检测输入信息
    /// </summary>
    private bool isBeginCheckInput = false;

    #endregion

    #region 构造函数

    private InputMgr()
    {
        MonoMgr.Instance.AddUpdateListener(InputUpdate);
    }

    #endregion

    #region 输入检测开关

    /// <summary>
    /// 开启或者关闭我们的输入管理模块的检测
    /// </summary>
    /// <param name="isStart">是否开启检测</param>
    public void StartOrCloseInputMgr(bool isStart)
    {
        this.isStart = isStart;
    }

    #endregion

    #region 配置按键映射

    /// <summary>
    /// 提供给外部改键或初始化的方法(键盘)
    /// </summary>
    /// <param name="eventType">事件类型</param>
    /// <param name="key">按键代码</param>
    /// <param name="inputType">输入类型</param>
    public void ChangeKeyboardInfo(E_EventType eventType, KeyCode key, InputInfo.E_InputType inputType)
    {
        // 初始化
        if (!inputDic.ContainsKey(eventType))
        {
            inputDic.Add(eventType, new InputInfo(inputType, key));
        }
        else // 改键
        {
            // 如果之前是鼠标 我们必须要修改它的按键类型
            inputDic[eventType].keyOrMouse = InputInfo.E_KeyOrMouse.Key;
            inputDic[eventType].key = key;
            inputDic[eventType].inputType = inputType;
        }
    }

    /// <summary>
    /// 提供给外部改键或初始化的方法(鼠标)
    /// </summary>
    /// <param name="eventType">事件类型</param>
    /// <param name="mouseID">鼠标按键ID</param>
    /// <param name="inputType">输入类型</param>
    public void ChangeMouseInfo(E_EventType eventType, int mouseID, InputInfo.E_InputType inputType)
    {
        // 初始化
        if (!inputDic.ContainsKey(eventType))
        {
            inputDic.Add(eventType, new InputInfo(inputType, mouseID));
        }
        else // 改键
        {
            // 如果之前是鼠标 我们必须要修改它的按键类型
            inputDic[eventType].keyOrMouse = InputInfo.E_KeyOrMouse.Mouse;
            inputDic[eventType].mouseID = mouseID;
            inputDic[eventType].inputType = inputType;
        }
    }

    /// <summary>
    /// 移除指定行为的输入监听
    /// </summary>
    /// <param name="eventType">事件类型</param>
    public void RemoveInputInfo(E_EventType eventType)
    {
        if (inputDic.ContainsKey(eventType))
            inputDic.Remove(eventType);
    }

    #endregion

    #region 获取输入信息

    /// <summary>
    /// 获取下一次的输入信息
    /// 用于改键功能中,等待玩家按下任意按键
    /// </summary>
    /// <param name="callBack">输入信息回调</param>
    public void GetInputInfo(UnityAction<InputInfo> callBack)
    {
        getInputInfoCallBack = callBack;
        MonoMgr.Instance.StartCoroutine(BeginCheckInput());
    }

    /// <summary>
    /// 延迟一帧开始检测输入
    /// 避免开启检测时立刻触发当前的输入
    /// </summary>
    /// <returns>协程迭代器</returns>
    private IEnumerator BeginCheckInput()
    {
        // 等一帧
        yield return 0;
        // 一帧后才会被置成true
        isBeginCheckInput = true;
    }

    #endregion

    #region 输入检测更新

    /// <summary>
    /// 输入检测更新
    /// </summary>
    private void InputUpdate()
    {
        // 当委托不为空时 证明想要获取到输入的信息 传递给外部
        if (isBeginCheckInput)
        {
            // 当一个键按下时 然后遍历所有按键信息 得到是谁被按下了
            if (Input.anyKeyDown)
            {
                InputInfo inputInfo = null;
                
                // 我们需要去遍历监听所有键位的按下 来得到对应输入的信息
                // 键盘
                Array keyCodes = Enum.GetValues(typeof(KeyCode));
                foreach (KeyCode inputKey in keyCodes)
                {
                    // 判断到底是谁被按下了 那么就可以得到对应的输入的键盘信息
                    if (Input.GetKeyDown(inputKey))
                    {
                        inputInfo = new InputInfo(InputInfo.E_InputType.Down, inputKey);
                        break;
                    }
                }
                
                // 鼠标
                if (inputInfo == null)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        if (Input.GetMouseButtonDown(i))
                        {
                            inputInfo = new InputInfo(InputInfo.E_InputType.Down, i);
                            break;
                        }
                    }
                }
                
                // 把获取到的信息传递给外部
                getInputInfoCallBack?.Invoke(inputInfo);
                getInputInfoCallBack = null;
                // 检测一次后就停止检测了
                isBeginCheckInput = false;
            }
        }

        // 如果外部没有开启检测功能 就不要检测
        if (!isStart)
            return;

        // 遍历配置的输入映射并检测输入
        foreach (E_EventType eventType in inputDic.Keys)
        {
            nowInputInfo = inputDic[eventType];
            // 如果是键盘输入
            if (nowInputInfo.keyOrMouse == InputInfo.E_KeyOrMouse.Key)
            {
                // 是抬起还是按下还是长按
                switch (nowInputInfo.inputType)
                {
                    case InputInfo.E_InputType.Down:
                        if (Input.GetKeyDown(nowInputInfo.key))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    case InputInfo.E_InputType.Up:
                        if (Input.GetKeyUp(nowInputInfo.key))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    case InputInfo.E_InputType.Always:
                        if (Input.GetKey(nowInputInfo.key))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    default:
                        break;
                }
            }
            // 如果是鼠标输入
            else
            {
                switch (nowInputInfo.inputType)
                {
                    case InputInfo.E_InputType.Down:
                        if (Input.GetMouseButtonDown(nowInputInfo.mouseID))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    case InputInfo.E_InputType.Up:
                        if (Input.GetMouseButtonUp(nowInputInfo.mouseID))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    case InputInfo.E_InputType.Always:
                        if (Input.GetMouseButton(nowInputInfo.mouseID))
                            EventCenter.Instance.EventTrigger(eventType);
                        break;
                    default:
                        break;
                }
            }
        }

        // 始终检测Unity Axes(轴输入)
        EventCenter.Instance.EventTrigger<float>(E_EventType.E_Input_Horizontal, Input.GetAxis("Horizontal"));
        EventCenter.Instance.EventTrigger<float>(E_EventType.E_Input_Vertical, Input.GetAxis("Vertical"));
    }

    #endregion
}

InputInfo.cs(输入信息类)

using UnityEngine;

/// <summary>
/// 输入信息类
/// 用于存储和管理键盘和鼠标的输入信息
/// </summary>
public class InputInfo
{
    #region 枚举

    /// <summary>
    /// 键盘或鼠标枚举
    /// </summary>
    public enum E_KeyOrMouse
    {
        /// <summary>
        /// 键盘输入
        /// </summary>
        Key,
        /// <summary>
        /// 鼠标输入
        /// </summary>
        Mouse,
    }

    /// <summary>
    /// 输入类型枚举
    /// </summary>
    public enum E_InputType
    {
        /// <summary>
        /// 按下
        /// </summary>
        Down,
        /// <summary>
        /// 抬起
        /// </summary>
        Up,
        /// <summary>
        /// 长按
        /// </summary>
        Always,
    }

    #endregion

    #region 字段

    /// <summary>
    /// 具体输入的类型——键盘还是鼠标
    /// </summary>
    public E_KeyOrMouse keyOrMouse;

    /// <summary>
    /// 输入的类型——抬起、按下、长按
    /// </summary>
    public E_InputType inputType;

    /// <summary>
    /// 键盘按键代码
    /// </summary>
    public KeyCode key;

    /// <summary>
    /// 鼠标按键ID
    /// </summary>
    public int mouseID;

    #endregion

    #region 构造函数

    /// <summary>
    /// 主要给键盘输入初始化
    /// </summary>
    /// <param name="inputType">输入类型</param>
    /// <param name="key">按键代码</param>
    public InputInfo(E_InputType inputType, KeyCode key)
    {
        this.keyOrMouse = E_KeyOrMouse.Key;
        this.inputType = inputType;
        this.key = key;
    }

    /// <summary>
    /// 主要给鼠标输入初始化
    /// </summary>
    /// <param name="inputType">输入类型</param>
    /// <param name="mouseID">鼠标按键ID</param>
    public InputInfo(E_InputType inputType, int mouseID)
    {
        this.keyOrMouse = E_KeyOrMouse.Mouse;
        this.inputType = inputType;
        this.mouseID = mouseID;
    }

    #endregion
}

InputModuleUsageTest.cs(输入模块使用测试)

using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// 输入模块使用测试
/// 演示输入模块的所有功能
/// </summary>
public class InputModuleUsageTest : MonoBehaviour
{
    void Start()
    {
        Debug.Log("输入模块使用测试:开始");
        
        // 开启输入检测
        InputMgr.Instance.StartOrCloseInputMgr(true);
        
        // 配置按键映射
        ConfigKeyMapping();
        
        // 监听输入事件
        ListenToInputEvents();
        
        // 延迟5秒测试改键
        Invoke("TestKeyRemapping", 5f);
    }

    /// <summary>
    /// 配置按键映射
    /// </summary>
    private void ConfigKeyMapping()
    {
        // 技能1绑定到数字键1
        InputMgr.Instance.ChangeKeyboardInfo(
            E_EventType.E_Input_Skill1,
            KeyCode.Alpha1,
            InputInfo.E_InputType.Down
        );
        
        // 技能2绑定到鼠标左键
        InputMgr.Instance.ChangeMouseInfo(
            E_EventType.E_Input_Skill2,
            0,
            InputInfo.E_InputType.Down
        );
        
        // 技能3绑定到数字键3
        InputMgr.Instance.ChangeKeyboardInfo(
            E_EventType.E_Input_Skill3,
            KeyCode.Alpha3,
            InputInfo.E_InputType.Down
        );
        
        Debug.Log("按键映射配置完成");
        // 输出:按键映射配置完成
    }

    /// <summary>
    /// 监听输入事件
    /// </summary>
    private void ListenToInputEvents()
    {
        EventCenter.Instance.AddEventListener(E_EventType.E_Input_Skill1, OnSkill1);
        EventCenter.Instance.AddEventListener(E_EventType.E_Input_Skill2, OnSkill2);
        EventCenter.Instance.AddEventListener(E_EventType.E_Input_Skill3, OnSkill3);
        EventCenter.Instance.AddEventListener<float>(E_EventType.E_Input_Horizontal, OnHorizontalMove);
        EventCenter.Instance.AddEventListener<float>(E_EventType.E_Input_Vertical, OnVerticalMove);
    }

    private void OnSkill1()
    {
        Debug.Log("技能1释放");
        // 输出:技能1释放
    }

    private void OnSkill2()
    {
        Debug.Log("技能2释放(鼠标左键)");
        // 输出:技能2释放(鼠标左键)
    }

    private void OnSkill3()
    {
        Debug.Log("技能3释放");
        // 输出:技能3释放
    }

    private void OnHorizontalMove(float value)
    {
        if (value != 0)
        {
            Debug.Log($"水平移动:{value}");
            // 输出:水平移动:-1 或 0.5 等
        }
    }

    private void OnVerticalMove(float value)
    {
        if (value != 0)
        {
            Debug.Log($"垂直移动:{value}");
            // 输出:垂直移动:1 或 -0.3 等
        }
    }

    /// <summary>
    /// 测试改键功能
    /// </summary>
    private void TestKeyRemapping()
    {
        Debug.Log("开始测试改键功能");
        
        // 将技能1改为Q键
        InputMgr.Instance.ChangeKeyboardInfo(
            E_EventType.E_Input_Skill1,
            KeyCode.Q,
            InputInfo.E_InputType.Down
        );
        Debug.Log("技能1已改为Q键");
        
        // 测试获取输入信息
        TestGetInputInfo();
    }

    /// <summary>
    /// 测试获取输入信息功能
    /// </summary>
    private void TestGetInputInfo()
    {
        Debug.Log("等待用户按下任意按键...");
        
        InputMgr.Instance.GetInputInfo((inputInfo) =>
        {
            if (inputInfo != null)
            {
                if (inputInfo.keyOrMouse == InputInfo.E_KeyOrMouse.Key)
                {
                    Debug.Log($"检测到键盘按键:{inputInfo.key}");
                }
                else
                {
                    Debug.Log($"检测到鼠标按键:{inputInfo.mouseID}");
                }
                
                // 根据输入信息改键技能3
                if (inputInfo.keyOrMouse == InputInfo.E_KeyOrMouse.Key)
                {
                    InputMgr.Instance.ChangeKeyboardInfo(
                        E_EventType.E_Input_Skill3,
                        inputInfo.key,
                        InputInfo.E_InputType.Down
                    );
                    Debug.Log($"技能3已改键为:{inputInfo.key}");
                }
            }
        });
    }

    void OnDestroy()
    {
        // 移除事件监听
        EventCenter.Instance.RemoveEventListener(E_EventType.E_Input_Skill1, OnSkill1);
        EventCenter.Instance.RemoveEventListener(E_EventType.E_Input_Skill2, OnSkill2);
        EventCenter.Instance.RemoveEventListener(E_EventType.E_Input_Skill3, OnSkill3);
        EventCenter.Instance.RemoveEventListener<float>(E_EventType.E_Input_Horizontal, OnHorizontalMove);
        EventCenter.Instance.RemoveEventListener<float>(E_EventType.E_Input_Vertical, OnVerticalMove);
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏