mirror of
http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite.git
synced 2025-11-20 04:37:11 +08:00
(client) feat:健康给予,路径优化,结算界面,商店界面 (#60)
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
This commit is contained in:
168
Client/Assets/Scripts/UI/SettlementUIInventoryDisplay.cs
Normal file
168
Client/Assets/Scripts/UI/SettlementUIInventoryDisplay.cs
Normal file
@@ -0,0 +1,168 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user