207 lines
7.0 KiB
C#
207 lines
7.0 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using Cielonos.MainGame.Inventory;
|
||
using Cielonos.MainGame.Inventory.Collections;
|
||
using Sirenix.OdinInspector;
|
||
using SLSUtilities.UI;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
namespace Cielonos.MainGame.UI
|
||
{
|
||
/// <summary>
|
||
/// 战后奖励选择界面的 UI 页面控制器。
|
||
/// 弹出时显示 3 个奖励卡片,玩家选择某一个卡片后,可以在详情面板中查看物品描述(或装备升级预览属性增益)。
|
||
/// 点击确认后,将奖励分发给玩家并关闭界面。
|
||
/// </summary>
|
||
public class RewardChoiceUIPage : UIPageBase
|
||
{
|
||
[Title("Selectors")]
|
||
[Tooltip("单个奖励选择卡片的预制体。")]
|
||
public GameObject selectorPrefab;
|
||
[Tooltip("卡片实例的父容器。")]
|
||
public RectTransform selectorContainer;
|
||
[Tooltip("当前生成的卡片列表。")]
|
||
public List<RewardChoiceSelector> selectors = new List<RewardChoiceSelector>();
|
||
|
||
[Title("Detail Panel")]
|
||
[Tooltip("右侧物品详细信息展示面板。")]
|
||
public ItemDetailPanel itemDetailPanel;
|
||
|
||
[Title("Buttons")]
|
||
[Tooltip("确认选择的按钮。")]
|
||
public Button confirmButton;
|
||
[Tooltip("关闭/放弃选择的按钮。")]
|
||
public Button closeButton;
|
||
|
||
private RewardChoiceSelector currentSelected;
|
||
private Action<int> onConfirmCallback;
|
||
|
||
/// <summary>当前被选中的选项索引,若无选中则返回 -1。</summary>
|
||
public int SelectedIndex => currentSelected != null ? selectors.IndexOf(currentSelected) : -1;
|
||
|
||
protected override void Start()
|
||
{
|
||
base.Start();
|
||
|
||
if (confirmButton != null)
|
||
{
|
||
confirmButton.onClick.AddListener(OnConfirmClicked);
|
||
}
|
||
|
||
if (closeButton != null)
|
||
{
|
||
closeButton.onClick.AddListener(OnCloseClicked);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置候选奖励物品池并初始化卡片列表。
|
||
/// </summary>
|
||
/// <param name="offers">生成的候选物品实例列表。</param>
|
||
/// <param name="onConfirm">当玩家确认选择时的回调函数(传入被选中的物品索引)。</param>
|
||
public void SetOffers(List<ItemBase> offers, Action<int> onConfirm)
|
||
{
|
||
onConfirmCallback = onConfirm;
|
||
ClearSelectors();
|
||
|
||
if (offers == null) return;
|
||
|
||
// 循环为候选池中的每个物品生成卡片 UI
|
||
for (int i = 0; i < offers.Count; i++)
|
||
{
|
||
ItemBase item = offers[i];
|
||
if (item == null) continue;
|
||
|
||
RewardChoiceSelector selector = CreateSelector();
|
||
selector.Setup(item);
|
||
}
|
||
|
||
currentSelected = null;
|
||
RefreshConfirmButton();
|
||
|
||
if (itemDetailPanel != null)
|
||
{
|
||
itemDetailPanel.ClearPanel();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 被卡片回调调用,当玩家点击某张卡片时更新选中状态,并在右侧面板展示详情。
|
||
/// </summary>
|
||
public void SelectItem(RewardChoiceSelector selector)
|
||
{
|
||
if (selector == null || !selectors.Contains(selector)) return;
|
||
|
||
// 取消之前选中卡片的高亮
|
||
if (currentSelected != null)
|
||
{
|
||
currentSelected.SetSelected(false);
|
||
}
|
||
|
||
// 设当前点击的卡片为选中状态
|
||
currentSelected = selector;
|
||
currentSelected.SetSelected(true);
|
||
|
||
if (itemDetailPanel != null)
|
||
{
|
||
ItemBase displayItem = currentSelected.item;
|
||
|
||
// 针对升级组件(PrefabricatedComponent)做特殊处理:在详情页展示其目标装备升级前后的属性对比
|
||
if (displayItem is PrefabricatedComponent prefabComp && prefabComp.targetEquipment != null)
|
||
{
|
||
displayItem = prefabComp.targetEquipment;
|
||
itemDetailPanel.SetItem(displayItem);
|
||
|
||
// 在普通面板下方追加展示“属性提升预览”
|
||
int currentLvl = displayItem.passiveAttributeSm?.level ?? 0;
|
||
itemDetailPanel.AppendUpgradePreview(displayItem.upgradeData, currentLvl, prefabComp.stackAmount);
|
||
}
|
||
else
|
||
{
|
||
// 普通道具直接显示基础描述
|
||
itemDetailPanel.SetItem(displayItem);
|
||
}
|
||
}
|
||
|
||
RefreshConfirmButton();
|
||
}
|
||
|
||
protected override void OnPageOpened()
|
||
{
|
||
RefreshConfirmButton();
|
||
}
|
||
|
||
protected override void OnPageClosed()
|
||
{
|
||
currentSelected = null;
|
||
onConfirmCallback = null;
|
||
}
|
||
|
||
/// <summary>确认选择按钮点击事件,执行回调并关闭页面。</summary>
|
||
private void OnConfirmClicked()
|
||
{
|
||
if (currentSelected == null) return;
|
||
|
||
int index = SelectedIndex;
|
||
if (index < 0) return;
|
||
|
||
Action<int> callback = onConfirmCallback;
|
||
Close();
|
||
callback?.Invoke(index);
|
||
}
|
||
|
||
/// <summary>关闭按钮点击事件,关闭当前界面。</summary>
|
||
private void OnCloseClicked()
|
||
{
|
||
Close();
|
||
}
|
||
|
||
/// <summary>从预制体实例化一个新的奖励卡片 UI。</summary>
|
||
private RewardChoiceSelector CreateSelector()
|
||
{
|
||
if (selectorPrefab == null || selectorContainer == null)
|
||
{
|
||
Debug.LogError("[RewardChoiceUIPage] selectorPrefab 或 selectorContainer 未配置。");
|
||
return null;
|
||
}
|
||
|
||
GameObject obj = Instantiate(selectorPrefab, selectorContainer);
|
||
RewardChoiceSelector selector = obj.GetComponent<RewardChoiceSelector>();
|
||
if (selector == null)
|
||
{
|
||
Debug.LogError("[RewardChoiceUIPage] selectorPrefab 缺少 RewardChoiceSelector 组件。");
|
||
Destroy(obj);
|
||
return null;
|
||
}
|
||
|
||
selectors.Add(selector);
|
||
return selector;
|
||
}
|
||
|
||
/// <summary>清空所有已生成的卡片实例。</summary>
|
||
private void ClearSelectors()
|
||
{
|
||
foreach (RewardChoiceSelector selector in selectors)
|
||
{
|
||
if (selector != null)
|
||
{
|
||
Destroy(selector.gameObject);
|
||
}
|
||
}
|
||
|
||
selectors.Clear();
|
||
currentSelected = null;
|
||
}
|
||
|
||
/// <summary>刷新确认按钮的启用/禁用状态(仅在选中卡片后可用)。</summary>
|
||
private void RefreshConfirmButton()
|
||
{
|
||
if (confirmButton != null)
|
||
{
|
||
confirmButton.interactable = currentSelected != null;
|
||
}
|
||
}
|
||
}
|
||
}
|