Initial Unity project commit
This commit is contained in:
@@ -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 且挂载了该脚本。");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user