NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/Input/MigrationGuide.md

7.4 KiB
Raw Blame History

输入系统迁移指南

本指南将帮助您从旧版 InputManager 迁移到新的基于 InputProcessor 的输入系统架构。

为什么要迁移?

新的输入系统架构提供了以下优势:

  1. 更好的关注点分离 - 输入处理器只负责特定的输入领域,例如 UI 输入、游戏玩法输入或相机控制
  2. 更精细的控制 - 可以独立启用或禁用不同的输入处理器
  3. 简化的设计 - 直接的解释器和处理器连接,移除了多余的中间层
  4. 灵活的组合 - 可以根据需要组合不同类型的解释器和处理器

迁移步骤概述

  1. 识别您的应用程序中的不同输入域UI 输入、游戏玩法输入等)
  2. 为每个域创建专用的输入处理器
  3. 设置 InputProcessor 组件并配置适当的解释器类型
  4. 将对 InputManager.Instance 的引用替换为相应的 InputProcessor 实例
  5. 进行测试并确保功能正常

详细迁移步骤

步骤 1识别输入域

识别您的应用程序中的不同输入需求。常见的域包括:

  • UI 交互(按钮点击、拖动等)
  • 游戏玩法控制(角色移动、操作等)
  • 相机控制(平移、缩放、旋转)
  • 特殊工具或模式(例如编辑模式、调试模式)

步骤 2创建输入处理器

为每个输入域创建专用的处理器类,这些类应实现 IMobileInputEventHandler 接口:

public class GameplayInputHandler : MonoBehaviour, IMobileInputEventHandler
{
    // 实现接口方法
    public void OnFingerDown(Vector2 screenPosition)
    {
        // 处理按下事件
    }

    public void OnFingerUp(Vector2 screenPosition)
    {
        // 处理抬起事件
    }

    public void OnFingerMove(Vector2 delta)
    {
        // 处理移动事件
    }

    public void OnFingerTap(Vector2 screenPosition)
    {
        // 处理点击事件
    }

    public void OnFingerLongPress(Vector2 screenPosition)
    {
        // 处理长按事件
    }

    public void OnFingerLongPressUp(Vector2 screenPosition)
    {
        // 处理长按释放事件
    }

    public void OnZoom(float delta)
    {
        // 处理缩放事件
    }
}

步骤 3设置 InputProcessor

在相应的场景或控制器中设置 InputProcessor 实例:

// 在游戏控制器或管理器中
private InputProcessor gameplayInputProcessor;
private GameplayInputHandler gameplayInputHandler;

private void Start()
{
    // 创建输入处理器
    gameplayInputHandler = gameObject.AddComponent<GameplayInputHandler>();
    
    // 创建 InputProcessor 并配置其输入解释器类型
    // 对于游戏玩法,可能使用 PC 或 Touch 解释器
    gameplayInputProcessor = InputProcessor.Create(
        "GameplayInput", 
        InputInterpreterType.PC,  // 在 PC 平台上
        gameplayInputHandler
    );
}

步骤 4替换 InputManager 引用

找到代码中对 InputManager.Instance 的所有引用,并替换为相应的 InputProcessor 实例和方法调用:

旧代码

// 检查触摸状态
if (InputManager.Instance.HasTouch())
{
    // 获取触摸位置
    Vector2 touchPos = InputManager.Instance.GetTouchPosition();
    // ...
}

// 订阅事件
InputManager.Instance.OnFingerMove += OnFingerMoveHandler;

新代码

// 检查触摸状态
if (gameplayInputProcessor.HasTouch())
{
    // 获取触摸位置
    Vector2 touchPos = gameplayInputProcessor.GetTouchPosition();
    // ...
}

// 事件处理现在直接在 GameplayInputHandler 中实现
// 不再需要单独的事件订阅

步骤 5添加特殊处理

在某些情况下,您可能需要特定的输入处理逻辑:

UI 排除处理

如果您需要排除 UI 区域的输入:

// 使用排除 UI 的解释器类型
UIExcludedInputProcessor = InputProcessor.Create(
    "GameplayInput", 
    InputInterpreterType.PC_ExcludeUI,  // 排除 UI 区域的输入
    gameplayInputHandler
);

组织多个 InputProcessor

对于复杂应用程序,您可以创建一个管理类来组织多个输入处理器:

public class GameInputSystem : MonoBehaviour
{
    [SerializeField] private InputInterpreterType uiInputInterpreterType = InputInterpreterType.PC_ExcludeUI;
    [SerializeField] private InputInterpreterType gameplayInputInterpreterType = InputInterpreterType.PC;
    [SerializeField] private InputInterpreterType cameraInputInterpreterType = InputInterpreterType.PC;

    private InputProcessor uiInputProcessor;
    private InputProcessor gameplayInputProcessor;
    private InputProcessor cameraInputProcessor;

    private UIInputHandler uiInputHandler;
    private GameplayInputHandler gameplayInputHandler;
    private CameraInputHandler cameraInputHandler;

    private void Awake()
    {
        CreateHandlers();
        CreateInputProcessors();
    }

    private void CreateHandlers()
    {
        uiInputHandler = gameObject.AddComponent<UIInputHandler>();
        gameplayInputHandler = gameObject.AddComponent<GameplayInputHandler>();
        cameraInputHandler = gameObject.AddComponent<CameraInputHandler>();
    }

    private void CreateInputProcessors()
    {
        uiInputProcessor = InputProcessor.Create("UIInput", uiInputInterpreterType, uiInputHandler, transform);
        gameplayInputProcessor = InputProcessor.Create("GameplayInput", gameplayInputInterpreterType, gameplayInputHandler, transform);
        cameraInputProcessor = InputProcessor.Create("CameraInput", cameraInputInterpreterType, cameraInputHandler, transform);
    }

    public void EnableUIInput(bool enable) => uiInputProcessor.IsEnable = enable;
    public void EnableGameplayInput(bool enable) => gameplayInputProcessor.IsEnable = enable;
    public void EnableCameraInput(bool enable) => cameraInputProcessor.IsEnable = enable;

    public bool HasTouch() => gameplayInputProcessor.HasTouch() || uiInputProcessor.HasTouch() || cameraInputProcessor.HasTouch();
}

常见问题解答

如何处理输入处理器之间的交互?

GameInputSystem 类中管理输入优先级和交互。例如,可以在 UI 交互期间禁用游戏玩法输入:

// 在 UIInputHandler 中
public void OnFingerDown(Vector2 screenPosition)
{
    // 通知 GameInputSystem UI 交互开始
    GameInputSystem.Instance.OnUIInteractionStarted();
}

// 在 GameInputSystem 中
public void OnUIInteractionStarted()
{
    // 暂时禁用游戏玩法输入
    EnableGameplayInput(false);
}

如何选择合适的解释器类型?

  • PC - 处理所有鼠标和键盘输入,不考虑 UI 状态
  • PC_ExcludeUI - 只处理非 UI 区域的鼠标和键盘输入
  • Touch - 处理所有触摸输入,不考虑 UI 状态
  • Touch_ExcludeUI - 只处理非 UI 区域的触摸输入
  • AutoPlatform - 根据平台自动选择解释器PC 或 Touch
  • AutoPlatform_ExcludeUI - 自动选择排除 UI 的解释器

如何管理之前的优先级系统?

新架构中,优先级是通过显式启用/禁用不同的输入处理器来管理的,而不是隐式的优先级系统。这样可以提供更清晰的控制流和更好的可预测性。

结论

迁移到新的输入系统架构将提高代码的可维护性和可扩展性。虽然初始迁移需要一些工作,但长期收益将远远超过投入的成本。如果在迁移过程中遇到问题,请参考示例代码或联系开发团队获取支持。