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

81 lines
2.9 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 UnityEngine;
using UnityEngine.UI;
namespace Ichni.Story.UI
{
/// <summary>
/// 故事树中单个 block 的视图基类。负责通用的定位、状态视觉与点击分发。
/// 具体类型(文本 / 音乐 / 教程)由子类实现 <see cref="OnClicked"/>。
/// </summary>
public abstract class StoryBlockView : SerializedMonoBehaviour
{
[Header("Block State")]
public string blockId;
public StoryBlockState state;
[Header("Common References")]
public RectTransform blockRect;
public RectTransform inPort;
public RectTransform outPort;
public Button button;
// 关联的定义,供子类读取类型专属字段
protected StoryBlockDefinition definition;
/// <summary>
/// 初始化 block 视图。逻辑坐标已由控制器按网格换算为 <paramref name="position"/>
/// (以 BlockContainer 左侧中线为原点、x 向右为正、y 向下为正的 anchoredPosition
/// </summary>
/// <param name="def">block 定义(提供尺寸与类型专属数据)。</param>
/// <param name="position">已换算好的 anchoredPosition。</param>
/// <param name="blockState">推导得到的 block 状态。</param>
public virtual void Initialize(StoryBlockDefinition def, Vector2 position, StoryBlockState blockState)
{
definition = def;
blockId = def.blockId;
state = blockState;
// 统一坐标约定:以 BlockContainer 的左侧中线为原点,向右为 +x、向下为 +y。
blockRect.anchorMin = new Vector2(0f, 0.5f);
blockRect.anchorMax = new Vector2(0f, 0.5f);
blockRect.pivot = new Vector2(0f, 0.5f);
blockRect.sizeDelta = new Vector2(400, 200);
blockRect.anchoredPosition = position;
if (button != null)
button.onClick.AddListener(HandleClick);
ApplyState(state);
}
/// <summary>
/// 应用状态并更新视觉。基类默认按状态切换按钮可交互性;
/// 子类可 override 以更新锁定图标、颜色等具体表现。
/// </summary>
public virtual void ApplyState(StoryBlockState newState)
{
state = newState;
if (button != null)
button.interactable = state != StoryBlockState.Locked;
}
private void HandleClick()
{
if (state == StoryBlockState.Locked)
return;
if (StoryManager.instance != null && StoryManager.instance.treeController != null)
StoryManager.instance.treeController.currentBlock = this;
OnClicked();
}
/// <summary>
/// 点击(非锁定状态)时的具体行为,由子类实现。
/// </summary>
protected abstract void OnClicked();
}
}