using UnityEngine; using UnityEngine.UI; using BaseGames.Core.Events; namespace BaseGames.UI { /// /// 输入设备图标切换器(架构 10_UIModule §12)。 /// 订阅 EVT_InputDeviceChanged(BoolEventChannelSO,true = 手柄,false = 键鼠), /// 切换后广播给场景内所有 InputIconImage 组件。 /// 通常挂在 UIRoot 或 UIManager 同一 GameObject 上。 /// public class InputDeviceIconSwitcher : MonoBehaviour { [SerializeField] private InputDeviceIconSetSO _kbIconSet; [SerializeField] private InputDeviceIconSetSO _padIconSet; [Header("Event Channel")] [SerializeField] private BoolEventChannelSO _onDeviceChanged; // EVT_InputDeviceChanged public static InputDeviceIconSetSO Current { get; private set; } private readonly CompositeDisposable _subs = new(); private void Awake() { Current = _kbIconSet; } private void OnEnable() => _onDeviceChanged?.Subscribe(SwitchIconSet).AddTo(_subs); private void OnDisable() => _subs.Clear(); private void SwitchIconSet(bool isGamepad) { Current = isGamepad ? _padIconSet : _kbIconSet; // 通知场景内所有图标 Image 刷新(包括非本对象子节点的其他 Canvas 区域) foreach (var img in FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None)) img.Refresh(); } } // ───────────────────────────────────────────────────────────────────────── /// /// 单个按键图标 Image 组件。 /// 记录 bindingPath,由 InputDeviceIconSwitcher 切换时自动刷新。 /// [RequireComponent(typeof(Image))] public class InputIconImage : MonoBehaviour { [Tooltip("InputSystem 绑定路径,如 /space 或 /buttonSouth")] [SerializeField] private string _bindingPath; private Image _image; private void Awake() => _image = GetComponent(); private void Start() => Refresh(); public void Refresh() { if (_image == null || string.IsNullOrEmpty(_bindingPath)) return; var set = InputDeviceIconSwitcher.Current; if (set == null) return; var sprite = set.GetIcon(_bindingPath); if (sprite != null) { _image.sprite = sprite; _image.enabled = true; } } } }