Files
ichni_Official/Assets/Scripts/NewStorySystem/Tree/TextBlockView.cs
2026-07-05 16:08:23 -04:00

96 lines
3.5 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 System.Collections.Generic;
using Ichni.Story.Dialogue;
using TMPro;
using UnityEngine;
namespace Ichni.Story.UI
{
/// <summary>
/// 文本块视图。点击后(阶段 2将通过 Yarn Spinner 进入对应节点的对话。
/// </summary>
public class TextBlockView : StoryBlockView
{
[Header("Text Block")]
public TMP_Text storyIdText;
public TMP_Text titleText;
[Tooltip("三种状态对应的背景预制体,生成 block 时按当前状态实例化为第一个子物体")]
public Dictionary<StoryBlockState, GameObject> blockVisuals = new Dictionary<StoryBlockState, GameObject>();
/// <summary>该文本块对应的 Yarn 节点名。</summary>
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;
}
/// <summary>
/// 应用状态:在基类逻辑(按钮可交互性)之外,切换到对应状态的背景视觉。
/// </summary>
public override void ApplyState(StoryBlockState newState)
{
base.ApplyState(newState);
UpdateVisual(newState);
}
/// <summary>
/// 按当前状态实例化对应的背景预制体,作为第一个子物体(位于文本/端口/按钮之下),
/// 并拉伸铺满整个 block。状态切换时先销毁旧背景。
/// </summary>
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);
}
}
}