using System; using System.Collections.Generic; using System.Linq; using Base; using Entity; using Item; using Prefab; using UnityEngine; namespace UI { /// /// 通用的结算UI组件,用于在指定时间内动态显示指定库存中的物品图标。 /// 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 itemsToDisplay = new(); /// /// 开始显示物品流程。 /// /// 显示所有物品所需总时间。 /// 提供物品槽位的数组。 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); } /// /// 每帧更新UI显示逻辑。 /// 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}"; } } /// /// 立即显示所有待显示的物品图标,并停止计时器更新。 /// 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); } } }