Files
ichni_Official/Assets/Scripts/NewStorySystem/Dialogue/ChoiceButton.cs
SoulliesOfficial 7b7d069b84 StorySystem
2026-07-07 01:28:27 -04:00

94 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Sirenix.OdinInspector;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Yarn.Unity;
namespace Ichni.Story.Dialogue
{
/// <summary>
/// 单个对话选项按钮的显示与交互控制器。
/// <para>
/// <list type="bullet">
/// <item><b>可用选项</b>:显示 <see cref="availableSprite"/>,点击时触发 <c>onSelected</c> 回调。</item>
/// <item><b>不可用选项</b>:显示 <see cref="unavailableSprite"/>,点击无效(但 Button 的
/// <c>interactable</c> 保持开启,以备未来扩展悬停提示等功能)。</item>
/// </list>
/// </para>
/// <para>
/// 由 <see cref="VNDialoguePresenter"/> 统一调用 <see cref="Setup"/> / <see cref="Cleanup"/>。
/// </para>
/// </summary>
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;
// ── 运行时状态 ────────────────────────────────────────────────────
/// <summary>当前绑定的选项是否可供玩家选择。</summary>
private bool _isAvailable;
// ── 公共 API ─────────────────────────────────────────────────────
/// <summary>
/// 根据 <paramref name="option"/> 配置按钮并激活显示。
/// </summary>
/// <param name="option">Yarn 对话选项数据。<c>option.IsAvailable</c> 决定外观与交互行为。</param>
/// <param name="onSelected">
/// 玩家点击且选项可用时触发的回调。
/// 不可用选项点击不会触发此回调,但按钮保持 <c>interactable=true</c>。
/// </param>
public void Setup(DialogueOption option, System.Action<DialogueOption> 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);
});
}
}
/// <summary>
/// 清除按钮监听并隐藏此按钮。
/// 在 <see cref="VNDialoguePresenter.RunOptionsAsync"/> 结束后统一调用。
/// </summary>
public void Cleanup()
{
if (button != null)
button.onClick.RemoveAllListeners();
gameObject.SetActive(false);
}
}
}