StorySystem
This commit is contained in:
93
Assets/Scripts/NewStorySystem/Dialogue/ChoiceButton.cs
Normal file
93
Assets/Scripts/NewStorySystem/Dialogue/ChoiceButton.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user