Files
Cielonos/Assets/Scripts/MainGame/UI/PlayerUI/MainGamePages/RewardChoice/RewardChoiceUIPage.cs

217 lines
7.3 KiB
C#
Raw Normal View History

2026-06-27 12:52:03 -04:00
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;
2026-07-18 03:16:20 -04:00
private Action onSkipCallback;
2026-06-27 12:52:03 -04:00
/// <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)
2026-07-18 03:16:20 -04:00
{
SetOffers(offers, onConfirm, null);
}
public void SetOffers(List<ItemBase> offers, Action<int> onConfirm, Action onSkip)
2026-06-27 12:52:03 -04:00
{
onConfirmCallback = onConfirm;
2026-07-18 03:16:20 -04:00
onSkipCallback = onSkip;
2026-06-27 12:52:03 -04:00
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;
2026-07-18 03:16:20 -04:00
onSkipCallback = null;
2026-06-27 12:52:03 -04:00
}
/// <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()
{
2026-07-18 03:16:20 -04:00
Action callback = onSkipCallback;
2026-06-27 12:52:03 -04:00
Close();
2026-07-18 03:16:20 -04:00
callback?.Invoke();
2026-06-27 12:52:03 -04:00
}
/// <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;
}
}
}
}