# 输入系统迁移指南 本指南将帮助您从旧版 `InputManager` 迁移到新的基于 `InputProcessor` 的输入系统架构。 ## 为什么要迁移? 新的输入系统架构提供了以下优势: 1. **更好的关注点分离** - 输入处理器只负责特定的输入领域,例如 UI 输入、游戏玩法输入或相机控制 2. **更精细的控制** - 可以独立启用或禁用不同的输入处理器 3. **简化的设计** - 直接的解释器和处理器连接,移除了多余的中间层 4. **灵活的组合** - 可以根据需要组合不同类型的解释器和处理器 ## 迁移步骤概述 1. 识别您的应用程序中的不同输入域(UI 输入、游戏玩法输入等) 2. 为每个域创建专用的输入处理器 3. 设置 `InputProcessor` 组件并配置适当的解释器类型 4. 将对 `InputManager.Instance` 的引用替换为相应的 `InputProcessor` 实例 5. 进行测试并确保功能正常 ## 详细迁移步骤 ### 步骤 1:识别输入域 识别您的应用程序中的不同输入需求。常见的域包括: - UI 交互(按钮点击、拖动等) - 游戏玩法控制(角色移动、操作等) - 相机控制(平移、缩放、旋转) - 特殊工具或模式(例如编辑模式、调试模式) ### 步骤 2:创建输入处理器 为每个输入域创建专用的处理器类,这些类应实现 `IMobileInputEventHandler` 接口: ```csharp 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` 实例: ```csharp // 在游戏控制器或管理器中 private InputProcessor gameplayInputProcessor; private GameplayInputHandler gameplayInputHandler; private void Start() { // 创建输入处理器 gameplayInputHandler = gameObject.AddComponent(); // 创建 InputProcessor 并配置其输入解释器类型 // 对于游戏玩法,可能使用 PC 或 Touch 解释器 gameplayInputProcessor = InputProcessor.Create( "GameplayInput", InputInterpreterType.PC, // 在 PC 平台上 gameplayInputHandler ); } ``` ### 步骤 4:替换 InputManager 引用 找到代码中对 `InputManager.Instance` 的所有引用,并替换为相应的 `InputProcessor` 实例和方法调用: **旧代码**: ```csharp // 检查触摸状态 if (InputManager.Instance.HasTouch()) { // 获取触摸位置 Vector2 touchPos = InputManager.Instance.GetTouchPosition(); // ... } // 订阅事件 InputManager.Instance.OnFingerMove += OnFingerMoveHandler; ``` **新代码**: ```csharp // 检查触摸状态 if (gameplayInputProcessor.HasTouch()) { // 获取触摸位置 Vector2 touchPos = gameplayInputProcessor.GetTouchPosition(); // ... } // 事件处理现在直接在 GameplayInputHandler 中实现 // 不再需要单独的事件订阅 ``` ### 步骤 5:添加特殊处理 在某些情况下,您可能需要特定的输入处理逻辑: #### UI 排除处理 如果您需要排除 UI 区域的输入: ```csharp // 使用排除 UI 的解释器类型 UIExcludedInputProcessor = InputProcessor.Create( "GameplayInput", InputInterpreterType.PC_ExcludeUI, // 排除 UI 区域的输入 gameplayInputHandler ); ``` #### 组织多个 InputProcessor 对于复杂应用程序,您可以创建一个管理类来组织多个输入处理器: ```csharp 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(); gameplayInputHandler = gameObject.AddComponent(); cameraInputHandler = gameObject.AddComponent(); } 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 交互期间禁用游戏玩法输入: ```csharp // 在 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 的解释器 ### 如何管理之前的优先级系统? 新架构中,优先级是通过显式启用/禁用不同的输入处理器来管理的,而不是隐式的优先级系统。这样可以提供更清晰的控制流和更好的可预测性。 ## 结论 迁移到新的输入系统架构将提高代码的可维护性和可扩展性。虽然初始迁移需要一些工作,但长期收益将远远超过投入的成本。如果在迁移过程中遇到问题,请参考示例代码或联系开发团队获取支持。