#if ENABLE_INPUT_SYSTEM using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; namespace XericLibrary.Runtime.Blueprint { /// /// 蓝图输入管理器(新输入系统)—— 管理 InputActionAsset 的引用计数与启用/停用。 /// /// 多个蓝图可能引用同一个 InputActionAsset,管理器确保: /// - 首个蓝图注册时启用 asset 并绑定 Action 回调; /// - 后续蓝图注册仅增加计数,不重复启用; /// - 蓝图注销时减少计数,计数归零时才解绑并禁用 asset。 /// /// /// 蓝图组件在 Awake 时调用 ,OnDestroy 时调用 /// ;运行时动态更换 asset 也通过这两方法。 /// /// public static class BlueprintInputManager { /// asset → 引用计数 private static Dictionary _refCounts = new Dictionary(); /// asset → 已绑定回调的 ActionMap private static Dictionary _activeMaps = new Dictionary(); // ===== 快捷键最新值(供 QuickGraphInputTool.OnUpdate 轮询) ===== /// Pan 动作最新的 Vector2 方向值(在 performed 中写入,canceled 中归零)。 public static Vector2 LastPanDirection; /// Zoom 动作最新的 float 轴值(在 performed 中写入,canceled 中归零)。 public static float LastZoomAxis; // 缓存的回调引用(确保 Bind/Unbind 使用同一委托实例) private static readonly System.Action s_panHandler = ctx => LastPanDirection = ctx.ReadValue(); private static readonly System.Action s_panCanceled = _ => LastPanDirection = Vector2.zero; private static readonly System.Action s_zoomHandler = ctx => LastZoomAxis = ctx.ReadValue(); private static readonly System.Action s_zoomCanceled = _ => LastZoomAxis = 0f; private static readonly System.Action s_homeHandler = _ => OnActionReceived(BlueprintInputConstants.FocusHome); private static readonly System.Action s_undoHandler = _ => OnActionReceived(BlueprintInputConstants.Undo); private static readonly System.Action s_redoHandler = _ => OnActionReceived(BlueprintInputConstants.Redo); private static readonly System.Action s_parentHandler = _ => OnActionReceived(BlueprintInputConstants.NavigateParent); // ===== 当前焦点蓝图(快捷键分发目标) ===== private static BlueprintGraph s_focusedGraph; /// 设置当前焦点蓝图(快捷键分发目标)。 public static void SetFocusedGraph(BlueprintGraph graph) { s_focusedGraph = graph; } // ===== 注册 / 注销 ===== /// /// 注册一个蓝图对 InputActionAsset 的引用。 /// 若 asset 尚未启用,则启用并绑定快捷键回调。 /// 允许多个蓝图共享同一 asset。 /// public static void RegisterAsset(InputActionAsset asset) { if (asset == null) return; if (_refCounts.TryGetValue(asset, out int count)) { _refCounts[asset] = count + 1; return; } _refCounts[asset] = 1; var map = asset.FindActionMap(BlueprintInputConstants.MapName); if (map != null) { map.Enable(); BindActions(map); _activeMaps[asset] = map; } } /// /// 注销一个蓝图对 InputActionAsset 的引用。 /// 引用计数归零时解绑回调并禁用 asset。 /// public static void UnregisterAsset(InputActionAsset asset) { if (asset == null) return; if (!_refCounts.TryGetValue(asset, out int count)) return; count--; if (count > 0) { _refCounts[asset] = count; return; } _refCounts.Remove(asset); if (_activeMaps.TryGetValue(asset, out var map)) { UnbindActions(map); map.Disable(); _activeMaps.Remove(asset); } } // ===== Action 回调 ===== private static void BindActions(InputActionMap map) { Bind(map, BlueprintInputConstants.Pan, s_panHandler); BindCancelled(map, BlueprintInputConstants.Pan, s_panCanceled); Bind(map, BlueprintInputConstants.Zoom, s_zoomHandler); BindCancelled(map, BlueprintInputConstants.Zoom, s_zoomCanceled); Bind(map, BlueprintInputConstants.FocusHome,s_homeHandler); Bind(map, BlueprintInputConstants.Undo, s_undoHandler); Bind(map, BlueprintInputConstants.Redo, s_redoHandler); Bind(map, BlueprintInputConstants.NavigateParent, s_parentHandler); } private static void UnbindActions(InputActionMap map) { Unbind(map, BlueprintInputConstants.Pan, s_panHandler); UnbindCancelled(map, BlueprintInputConstants.Pan, s_panCanceled); Unbind(map, BlueprintInputConstants.Zoom, s_zoomHandler); UnbindCancelled(map, BlueprintInputConstants.Zoom, s_zoomCanceled); Unbind(map, BlueprintInputConstants.FocusHome,s_homeHandler); Unbind(map, BlueprintInputConstants.Undo, s_undoHandler); Unbind(map, BlueprintInputConstants.Redo, s_redoHandler); Unbind(map, BlueprintInputConstants.NavigateParent, s_parentHandler); } private static void Bind(InputActionMap map, string name, System.Action handler) { var action = map.FindAction(name); if (action != null) action.performed += handler; } private static void Unbind(InputActionMap map, string name, System.Action handler) { var action = map.FindAction(name); if (action != null) action.performed -= handler; } private static void BindCancelled(InputActionMap map, string name, System.Action handler) { var action = map.FindAction(name); if (action != null) action.canceled += handler; } private static void UnbindCancelled(InputActionMap map, string name, System.Action handler) { var action = map.FindAction(name); if (action != null) action.canceled -= handler; } private static void OnActionReceived(string actionName) { if (s_focusedGraph != null) { s_focusedGraph.MarkDirty(); BlueprintToolProvider.DispatchAction(s_focusedGraph, actionName); } } } } #endif