using System.Collections.Generic; using Ichni.Story.Dialogue; using TMPro; using UnityEngine; namespace Ichni.Story.UI { /// /// 文本块视图。点击后(阶段 2)将通过 Yarn Spinner 进入对应节点的对话。 /// public class TextBlockView : StoryBlockView { [Header("Text Block")] public TMP_Text storyIdText; public TMP_Text titleText; [Tooltip("三种状态对应的背景预制体,生成 block 时按当前状态实例化为第一个子物体")] public Dictionary blockVisuals = new Dictionary(); /// 该文本块对应的 Yarn 节点名。 public string YarnNodeName { get; private set; } // 当前已实例化的状态背景对象;状态切换时销毁并替换 private GameObject _currentVisual; public override void Initialize(StoryBlockDefinition def, Vector2 position, StoryBlockState blockState) { // 注意:base.Initialize 末尾会调用 ApplyState(state),届时已生成对应背景 base.Initialize(def, position, blockState); YarnNodeName = def.yarnNodeName; if (storyIdText != null) storyIdText.text = def.blockId; // 阶段 5 将接入 Unity Localization;此处占位直接显示 titleKey if (titleText != null) titleText.text = def.titleKey; } /// /// 应用状态:在基类逻辑(按钮可交互性)之外,切换到对应状态的背景视觉。 /// public override void ApplyState(StoryBlockState newState) { base.ApplyState(newState); UpdateVisual(newState); } /// /// 按当前状态实例化对应的背景预制体,作为第一个子物体(位于文本/端口/按钮之下), /// 并拉伸铺满整个 block。状态切换时先销毁旧背景。 /// private void UpdateVisual(StoryBlockState newState) { if (_currentVisual != null) { Destroy(_currentVisual); _currentVisual = null; } if (blockVisuals == null || !blockVisuals.TryGetValue(newState, out GameObject prefab) || prefab == null) { Debug.LogWarning($"[TextBlockView] block '{blockId}' 缺少状态 {newState} 的背景预制体(blockVisuals 未配置)。"); return; } _currentVisual = Instantiate(prefab, blockRect); _currentVisual.transform.SetAsFirstSibling(); // 背景铺满整个 block if (_currentVisual.transform is RectTransform visualRect) { visualRect.anchorMin = Vector2.zero; visualRect.anchorMax = Vector2.one; visualRect.offsetMin = Vector2.zero; visualRect.offsetMax = Vector2.zero; visualRect.localScale = Vector3.one; } } protected override void OnClicked() { if (StoryDialogueController.instance == null) { Debug.LogWarning($"[TextBlockView] 场景中缺少 StoryDialogueController,无法播放 block '{blockId}' 的对话。"); return; } StoryDialogueController.instance.PlayBlock(this); } } }