using System.Collections.Generic;
using Cielonos.Core.Interaction;
using DG.Tweening;
using Sirenix.OdinInspector;
using SLSUtilities.UI;
using UnityEngine;
namespace Cielonos.UI
{
///
/// 交互选项列表 UI 页面。
/// 玩家进入可交互物体范围时由 PlayerInteractionSubcontroller 调用 Show(),离开时调用 Hide()。
/// 当选项数量为 1 时,直接显示单个选项而不需要导航;
/// 当选项数量大于 1 时,玩家可用鼠标滚轮或上/下键切换高亮选项,R 键执行。
///
public class InteractionUIArea : UIElementBase
{
[Title("容器")]
[Tooltip("单个选项条目的预制体,需包含 InteractionChoiceItem 组件。")]
[SerializeField] private GameObject choiceItemPrefab;
[Tooltip("选项条目的父节点(Layout Group)。")]
[SerializeField] private RectTransform choiceContainer;
private readonly List _items = new List();
private void Start()
{
Hide();
}
// ====================================================================
// 对外接口
// ====================================================================
///
/// 显示选项列表并高亮指定索引的选项。
/// 由 PlayerInteractionSubcontroller.SetCurrentInteractable() 调用。
///
public void Show(List choices, int selectedIndex)
{
gameObject.SetActive(true);
canvasGroup.DOFade(1f, 0.25f).From(0).OnComplete(() =>
{
canvasGroup.interactable = true;
canvasGroup.blocksRaycasts = true;
}).Play();
rectTransform.DOLocalMoveY(-50f, 0.25f).From(-250f).Play();
ClearItems();
if (choices == null || choices.Count == 0)
{
gameObject.SetActive(false);
return;
}
foreach (InteractionChoice choice in choices)
{
InteractionChoiceItem item = CreateItem();
if (item != null)
{
item.Setup(choice.choiceName, choice.isInteractable);
}
}
UpdateHighlight(selectedIndex);
}
///
/// 更新高亮选项。由 PlayerInteractionSubcontroller.NavigateChoice() 调用。
///
public void UpdateHighlight(int selectedIndex)
{
for (int i = 0; i < _items.Count; i++)
{
_items[i].SetHighlighted(i == selectedIndex);
}
}
///
/// 隐藏选项列表。由 PlayerInteractionSubcontroller.RemoveCurrentInteractable() 调用。
///
public override void Hide()
{
canvasGroup.interactable = false;
canvasGroup.blocksRaycasts = false;
canvasGroup.DOFade(0f, 0.25f).OnComplete(() =>
{
ClearItems();
gameObject.SetActive(false);
}).Play();
rectTransform.DOLocalMoveY(-250f, 0.25f).Play();
}
// ====================================================================
// 内部工具
// ====================================================================
private InteractionChoiceItem CreateItem()
{
if (choiceItemPrefab == null || choiceContainer == null)
{
Debug.LogError("[InteractionUIPage] choiceItemPrefab 或 choiceContainer 未在 Inspector 中配置。");
return null;
}
GameObject go = Instantiate(choiceItemPrefab, choiceContainer);
InteractionChoiceItem item = go.GetComponent();
if (item == null)
{
Debug.LogError("[InteractionUIPage] choiceItemPrefab 缺少 InteractionChoiceItem 组件。");
Destroy(go);
return null;
}
_items.Add(item);
return item;
}
private void ClearItems()
{
foreach (InteractionChoiceItem item in _items)
{
if (item != null) Destroy(item.gameObject);
}
_items.Clear();
}
}
}