using Sirenix.OdinInspector;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Yarn.Unity;
namespace Ichni.Story.Dialogue
{
///
/// 单个对话选项按钮的显示与交互控制器。
///
///
/// - 可用选项:显示 ,点击时触发 onSelected 回调。
/// - 不可用选项:显示 ,点击无效(但 Button 的
/// interactable 保持开启,以备未来扩展悬停提示等功能)。
///
///
///
/// 由 统一调用 / 。
///
///
public class ChoiceButton : MonoBehaviour
{
[Tooltip("按钮组件引用(挂载在同 GameObject 上的 Button)。")]
public Button button;
[Tooltip("按钮背景 Image,用于在 available / unavailable 状态间切换 Sprite。")]
public Image buttonBackground;
[Tooltip("选项文本 TMP。")]
public TMP_Text buttonText;
[SerializeField, HideInPlayMode]
[Tooltip("选项可用时的背景 Sprite。")]
private Sprite availableSprite;
[SerializeField, HideInPlayMode]
[Tooltip("选项不可用时的背景 Sprite。")]
private Sprite unavailableSprite;
// ── 运行时状态 ────────────────────────────────────────────────────
/// 当前绑定的选项是否可供玩家选择。
private bool _isAvailable;
// ── 公共 API ─────────────────────────────────────────────────────
///
/// 根据 配置按钮并激活显示。
///
/// Yarn 对话选项数据。option.IsAvailable 决定外观与交互行为。
///
/// 玩家点击且选项可用时触发的回调。
/// 不可用选项点击不会触发此回调,但按钮保持 interactable=true。
///
public void Setup(DialogueOption option, System.Action onSelected)
{
gameObject.SetActive(true);
_isAvailable = option.IsAvailable;
// 设置选项文本
if (buttonText != null)
buttonText.text = option.Line.TextWithoutCharacterName.Text;
// 根据可用性切换背景图
if (buttonBackground != null)
buttonBackground.sprite = _isAvailable ? availableSprite : unavailableSprite;
// 注册点击监听:不可用选项点击静默忽略
if (button != null)
{
button.onClick.RemoveAllListeners();
button.onClick.AddListener(() =>
{
if (_isAvailable)
onSelected?.Invoke(option);
});
}
}
///
/// 清除按钮监听并隐藏此按钮。
/// 在 结束后统一调用。
///
public void Cleanup()
{
if (button != null)
button.onClick.RemoveAllListeners();
gameObject.SetActive(false);
}
}
}