Files
Echo/Assets/_Project/Scripts/Player/ItemUsageSystem.cs
T
2026-07-08 20:42:51 +08:00

237 lines
7.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
using UnityEngine.InputSystem;
using Inventory;
using UI; // 引入 UI 命名空间以访问 TabletController
using Player;
using System;
public class ItemUsageSystem : MonoBehaviour
{
// 全局静态事件,当任何物品被成功使用时触发
public static event Action<ItemData> OnItemUsedGlobal;
[Header("References")]
public PlayerInput playerInput;
[Header("Vitals")]
public PlayerVitalsSystem vitalsSystem;
// 我们需要知道当前选中了哪个格子,所以引用 InventorySystem
// 但更好的方式是让 InventoryUI 或 InventorySystem 告诉我们当前选中了啥
// 这里我们直接访问单例,简单直接
private void Awake()
{
if (playerInput == null)
{
playerInput = GetComponent<PlayerInput>();
if (playerInput == null)
{
var pc = FindObjectOfType<Player.PlayerController>(true);
if (pc != null)
{
playerInput = pc.GetComponent<PlayerInput>();
}
}
}
}
private void OnEnable()
{
if (vitalsSystem == null)
{
vitalsSystem = PlayerVitalsSystem.Instance != null ? PlayerVitalsSystem.Instance : FindObjectOfType<PlayerVitalsSystem>();
}
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<SpecialUsePopupController>(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 且挂载了该脚本。");
}
}
}