mirror of
http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite.git
synced 2025-11-19 23:37:13 +08:00
Co-authored-by: m0_75251201 <m0_75251201@noreply.gitcode.com> Reviewed-on: http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite/pulls/60
169 lines
5.8 KiB
C#
169 lines
5.8 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using Base;
|
||
using Entity;
|
||
using Item;
|
||
using Prefab;
|
||
using UnityEngine;
|
||
|
||
namespace UI
|
||
{
|
||
/// <summary>
|
||
/// 通用的结算UI组件,用于在指定时间内动态显示指定库存中的物品图标。
|
||
/// </summary>
|
||
public class SettlementUIInventoryDisplay : MonoBehaviour, ITickUI
|
||
{
|
||
[Tooltip("用于显示物品图标的父Transform")]
|
||
public Transform showIcon;
|
||
[Tooltip("物品图标的Prefab")]
|
||
public ImagePrefabUI iconPrefab;
|
||
|
||
private int index;
|
||
private float timer;
|
||
private float totalTime;
|
||
private List<ItemResource> itemsToDisplay = new();
|
||
|
||
/// <summary>
|
||
/// 开始显示物品流程。
|
||
/// </summary>
|
||
/// <param name="time">显示所有物品所需总时间。</param>
|
||
/// <param name="inventorySlotProvider">提供物品槽位的数组。</param>
|
||
public void StartShow(float time, InventorySlot[] inventorySlotProvider)
|
||
{
|
||
// 在开始新显示流程前,先确保移除旧的TickUI注册
|
||
Clock.RemoveTickUI(this);
|
||
|
||
// 清除当前显示区域中的所有旧图标
|
||
foreach (Transform iconTransform in showIcon)
|
||
{
|
||
Destroy(iconTransform.gameObject);
|
||
}
|
||
|
||
// 如果没有物品或获取物品失败,则直接返回。
|
||
if (inventorySlotProvider == null || !inventorySlotProvider.Any())
|
||
{
|
||
Debug.LogWarning("SettlementUIInventoryDisplay: 没有物品可显示或库存提供者返回空。");
|
||
return;
|
||
}
|
||
|
||
totalTime = time;
|
||
timer = 0;
|
||
index = 0;
|
||
itemsToDisplay.Clear();
|
||
|
||
// 将所有InventorySlot中的物品及其数量展开,添加到待显示列表中
|
||
foreach (var inventorySlot in inventorySlotProvider)
|
||
{
|
||
// 确保物品资源不为空
|
||
if (inventorySlot.Item != null)
|
||
{
|
||
for (var i = 0; i < inventorySlot.Quantity; i++)
|
||
{
|
||
itemsToDisplay.Add(inventorySlot.Item);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 如果填充后依然没有物品,也提前返回
|
||
if (itemsToDisplay.Count == 0)
|
||
{
|
||
Debug.LogWarning("SettlementUIInventoryDisplay: 处理库存槽位后未找到有效物品。");
|
||
return;
|
||
}
|
||
|
||
// totalTime 有效性检查
|
||
if (totalTime <= 0f)
|
||
{
|
||
Debug.LogWarning("SettlementUIInventoryDisplay: 总显示时间为零或负数。立即显示所有物品。");
|
||
ShowAllImmediately();
|
||
return;
|
||
}
|
||
|
||
// 确保只有当有物品且需要动态显示时才注册到 Clock
|
||
Clock.AddTickUI(this);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 每帧更新UI显示逻辑。
|
||
/// </summary>
|
||
public void TickUI()
|
||
{
|
||
// 如果没有物品可显示,或所有物品都已显示,直接停止计时。
|
||
if (itemsToDisplay.Count == 0 || index >= itemsToDisplay.Count)
|
||
{
|
||
Clock.RemoveTickUI(this);
|
||
return;
|
||
}
|
||
|
||
timer += Time.deltaTime;
|
||
|
||
// 计算当前时间点应该已经显示了多少物品。
|
||
// Math.Min确保end不会超过物品总数。
|
||
var end = Math.Min(itemsToDisplay.Count, (int)(itemsToDisplay.Count * timer / totalTime));
|
||
|
||
// 循环实例化从上次显示位置到当前应该显示位置之间的物品图标
|
||
for (; index < end; index++)
|
||
{
|
||
var item = itemsToDisplay[index];
|
||
// 确保物品不为空
|
||
if (item == null)
|
||
{
|
||
Debug.LogWarning($"SettlementUIInventoryDisplay: 索引 {index} 处的物品为空,跳过图标创建。");
|
||
continue;
|
||
}
|
||
|
||
// 实例化图标Prefab并设置父Transform
|
||
var obj = Instantiate(iconPrefab, showIcon);
|
||
// 设置图标图片。item.Icon?[0] 确保在Icon为null时不报错
|
||
obj.Icon = item.Icon?[0];
|
||
obj.gameObject.name = $"Icon_{item.Name}_{index}";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 立即显示所有待显示的物品图标,并停止计时器更新。
|
||
/// </summary>
|
||
public void ShowAllImmediately()
|
||
{
|
||
// 停止TickUI的更新,防止同步出现动态显示
|
||
Clock.RemoveTickUI(this);
|
||
|
||
if (itemsToDisplay.Count == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (index >= itemsToDisplay.Count)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 从当前 index 开始,显示所有剩余物品
|
||
for (; index < itemsToDisplay.Count; index++)
|
||
{
|
||
var item = itemsToDisplay[index];
|
||
if (item == null)
|
||
{
|
||
Debug.LogWarning($"SettlementUIInventoryDisplay: 立即显示时索引 {index} 处的物品为空,跳过图标创建。");
|
||
continue;
|
||
}
|
||
|
||
// 实例化图标Prefab并设置父Transform
|
||
var obj = Instantiate(iconPrefab, showIcon);
|
||
obj.Icon = item.Icon?[0];
|
||
obj.gameObject.name = $"Icon_{item.Name}_{index}_Immediate";
|
||
}
|
||
|
||
// 确保 index 达到最大
|
||
index = itemsToDisplay.Count;
|
||
}
|
||
|
||
private void OnDestroy()
|
||
{
|
||
// 确保在组件销毁时,从Clock中移除注册
|
||
Clock.RemoveTickUI(this);
|
||
}
|
||
}
|
||
}
|