using UnityEngine; using UnityEngine.InputSystem; using Inventory; using UI; // 引入 UI 命名空间以访问 TabletController using Player; using System; public class ItemUsageSystem : MonoBehaviour { // 全局静态事件,当任何物品被成功使用时触发 public static event Action OnItemUsedGlobal; [Header("References")] public PlayerInput playerInput; [Header("Vitals")] public PlayerVitalsSystem vitalsSystem; // 我们需要知道当前选中了哪个格子,所以引用 InventorySystem // 但更好的方式是让 InventoryUI 或 InventorySystem 告诉我们当前选中了啥 // 这里我们直接访问单例,简单直接 private void Awake() { if (playerInput == null) { playerInput = GetComponent(); if (playerInput == null) { var pc = FindObjectOfType(true); if (pc != null) { playerInput = pc.GetComponent(); } } } } private void OnEnable() { if (vitalsSystem == null) { vitalsSystem = PlayerVitalsSystem.Instance != null ? PlayerVitalsSystem.Instance : FindObjectOfType(); } if (playerInput != null) { if (playerInput.currentActionMap != null && playerInput.currentActionMap.name != "Player") { Debug.LogWarning($"[ItemUsageSystem] 当前 ActionMap 为 '{playerInput.currentActionMap.name}',Use 可能不会触发。"); } // [Debug] 尝试绑定输入事件 // 根据报错,你的 Action 名字应该是 "Use" 而不是 "Fire" var actionName = "Use"; // 安全检查:先确认 Action 是否存在 var useAction = playerInput.actions.FindAction(actionName); if (useAction != null) { useAction.performed += OnUsePerformed; Debug.Log($"[ItemUsageSystem] 成功绑定输入动作: {actionName}"); } else { Debug.LogError($"[ItemUsageSystem] 错误:在 PlayerInput 中找不到名为 '{actionName}' 的动作!请检查 Input Actions 设置是否有名为 '{actionName}' 的动作。"); } } else { Debug.LogError("[ItemUsageSystem] 错误:PlayerInput 组件未赋值!"); } } private void OnDisable() { if (playerInput != null) { // 使用 FindAction 避免 KeyNotFoundException var actionName = "Use"; var useAction = playerInput.actions.FindAction(actionName); if (useAction != null) { useAction.performed -= OnUsePerformed; } } } private void OnUsePerformed(InputAction.CallbackContext context) { // [Debug] 接收到按键输入 Debug.Log("[ItemUsageSystem] 检测到使用键按下 (OnUsePerformed)"); if (InventorySystem.Instance == null) { Debug.LogError("[ItemUsageSystem] 错误:找不到 InventorySystem 实例!"); return; } // 获取当前选中的物品 int slotIndex = InventorySystem.Instance.selectedSlotIndex; // 检查槽位是否越界 if (slotIndex < 0 || slotIndex >= InventorySystem.Instance.inventory.Count) { Debug.Log($"[ItemUsageSystem] 当前选中的槽位无效: {slotIndex}"); return; } var item = InventorySystem.Instance.inventory[slotIndex]; // 检查是否有物品 if (item != null && item.data != null) { UseItem(item.data, slotIndex); } else { Debug.Log($"[ItemUsageSystem] 当前槽位 {slotIndex} 是空的,无法使用物品。"); } } private void UseItem(ItemData data, int slotIndex) { Debug.Log($"[ItemUsage] 尝试使用物品: {data.displayName} ({data.itemType})"); switch (data.itemType) { case ItemType.Consumable: HandleConsumable(data, slotIndex); TryShowSpecialUseUI(data); break; case ItemType.Equipment: HandleEquipment(data, slotIndex); TryShowSpecialUseUI(data); break; case ItemType.Resource: if (!TryShowSpecialUseUI(data)) { Debug.Log("这是一个资源,不能直接使用。"); } break; case ItemType.Tool: TryShowSpecialUseUI(data); break; } // 触发全局物品使用事件 OnItemUsedGlobal?.Invoke(data); } private bool TryShowSpecialUseUI(ItemData data) { if (data == null || !data.showSpecialUseUI) return false; var popup = SpecialUsePopupController.Instance != null ? SpecialUsePopupController.Instance : FindObjectOfType(true); if (popup == null) return false; var sprite = data.specialUseSprite != null ? data.specialUseSprite : data.icon; string[] pages = null; if (data.useSpecialUseUIPages && data.specialUseUIPages != null && data.specialUseUIPages.Count > 0) { pages = new string[data.specialUseUIPages.Count]; for (int i = 0; i < data.specialUseUIPages.Count; i++) { pages[i] = data.specialUseUIPages[i] != null ? data.specialUseUIPages[i].text : string.Empty; } } if (pages == null || pages.Length == 0) { var text = !string.IsNullOrWhiteSpace(data.specialUseUIText) ? data.specialUseUIText : (!string.IsNullOrWhiteSpace(data.description) ? data.description : data.displayName); pages = new[] { text }; } popup.ShowPages(pages, sprite, 0); return true; } private void HandleConsumable(ItemData data, int slotIndex) { // TODO: 播放吃/喝动画 // TODO: 增加属性 (Health/Hunger) Debug.Log($"[ItemUsage] 消耗了 {data.displayName}"); if (vitalsSystem != null) { vitalsSystem.ApplyDelta(data.thirstDelta, data.hungerDelta, data.sanityDelta); } // 消耗逻辑:移除当前物品,添加结果物品(如果有) InventorySystem.Instance.RemoveFromSlot(slotIndex, 1); if (data.consumedResult != null) { InventorySystem.Instance.Add(data.consumedResult, 1); } } private void HandleEquipment(ItemData data, int slotIndex) { // [Debug] 正在处理装备逻辑 Debug.Log($"[ItemUsageSystem] 处理装备: {data.displayName} (ID: {data.id})"); // 判断是否是平板 (建议同时检查 ID 和名称以防万一) if (data.name.Contains("Tablet") || data.displayName.Contains("Tablet") || data.displayName.Contains("平板") || data.id == "tablet") { ToggleTabletUI(); } else { Debug.LogWarning($"[ItemUsageSystem] 这是一个装备,但没有定义具体的使用逻辑: {data.displayName}"); } } private void ToggleTabletUI() { if (TabletController.Instance != null) { Debug.Log(">>> 正在打开 AI 平板界面 <<<"); TabletController.Instance.ShowTablet(); } else { Debug.LogError("[ItemUsageSystem] 找不到 TabletController 实例!请确保场景中有 TabletCanvas 且挂载了该脚本。"); } } }