Initial Unity project commit

This commit is contained in:
2026-07-08 19:53:15 +08:00
commit 75f254212e
15657 changed files with 11633879 additions and 0 deletions
@@ -0,0 +1,236 @@
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 且挂载了该脚本。");
}
}
}