Files
ichni_Official/Assets/Scripts/NewStorySystem/Data/StoryHelperData.cs
SoulliesOfficial 810d019619 剧情+对话完善
2026-07-21 15:24:42 -04:00

113 lines
5.2 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;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Tables;
namespace Ichni.Story
{
/// <summary>
/// 全局 Helper 的独立数据资产。
/// <para>该资产不隶属于任何 StoryData由 <see cref="StoryManager.helperData"/> 统一引用,
/// 因而所有章节都共用同一个 Helper 角色、名称和候选对话池。</para>
/// <para>运行时会在满足条件的候选中按权重抽取,并在候选数量允许时避免与上次对话重复;
/// 具体抽取和 UI 展示由 <see cref="StoryHelperController"/> 负责。</para>
/// </summary>
[CreateAssetMenu(fileName = "StoryHelperData", menuName = "Ichni/Story/New/Story Helper Data")]
public class StoryHelperData : SerializedScriptableObject
{
/// <summary>
/// Helper 的稳定身份标识。当前阶段只有一个 Helper但后续的更换界面、存档和统计
/// 都应使用该 ID而非依赖可变的资源名称或显示名称。
/// </summary>
[LabelText("Helper ID")]
[Tooltip("使用小写英文、数字和下划线,例如 chapter0_helper。未来切换与持久化 Helper 时使用此稳定 ID。")]
public string helperId;
/// <summary>
/// 当前静态版本使用的立绘。留空时,静态 Presenter 会保留场景中原本配置的 Image
/// 因而可以在不立即迁移全部美术引用的情况下逐步接入本数据资产。
/// </summary>
[PreviewField(75, ObjectFieldAlignment.Left)]
[LabelText("Portrait Sprite")]
[Tooltip("当前静态 Helper 立绘。未来改用 Spine 或 Live2D 时,可由对应 Presenter 忽略该字段。")]
public Sprite portraitSprite;
/// <summary>
/// Helper 名称与对话文本所使用的 Unity Localization String Table。
/// </summary>
[LabelText("Localization Table")]
[Tooltip("Display Name Key、Fallback Dialogue Key 与 Dialogue Pool 的 Text Key 均在此 String Table 中查找。")]
public TableReference localizationTable;
/// <summary>
/// Helper 显示名称的 Unity Localization Entry Key。
/// </summary>
[LabelText("Display Name Key (Localization)")]
[Tooltip("Helper 显示名称使用的 Unity Localization Entry Key。")]
public string displayNameKey;
/// <summary>
/// 当所有候选对话均不满足条件时显示的兜底对话 Entry Key。
/// </summary>
[LabelText("Fallback Dialogue Key (Localization)")]
[Tooltip("没有候选对话满足条件时显示的 Unity Localization Entry Key。")]
public string fallbackDialogueKey;
/// <summary>
/// 全章节共用的候选对话。条件留空表示始终可参与抽取。
/// </summary>
[LabelText("Dialogue Pool")]
[ListDrawerSettings(ShowFoldout = true, DefaultExpandedState = false, DraggableItems = true, ShowItemCount = true)]
[Tooltip("全章节共用的候选 Helper 对话。条件留空时该项始终可参与按权重抽取。")]
public List<StoryHelperDialogueDefinition> dialoguePool = new List<StoryHelperDialogueDefinition>();
}
/// <summary>
/// Helper 对话池中的一条候选记录。
/// <para>条件复用故事树的 <see cref="StoryCondition"/>,因此未来可直接根据章节剧情变量、
/// 路线变量或指定 Block 的完成状态筛选,而不需要为 Helper 另写一套条件语法。</para>
/// </summary>
[Serializable]
[InlineProperty]
[HideReferenceObjectPicker]
public class StoryHelperDialogueDefinition
{
/// <summary>
/// 候选对话的稳定 ID仅用于调试、去重和未来数据追踪。
/// 命名使用小写英文、数字和下划线,例如 <c>general_greeting_01</c>。
/// </summary>
[HorizontalGroup("Identity", 0.38f)]
[LabelText("ID")]
[LabelWidth(20)]
[Tooltip("候选对话的稳定 ID仅用于调试、去重和未来数据追踪。")]
public string dialogueId;
/// <summary>
/// 实际显示内容的 Unity Localization Entry Key。
/// </summary>
[HorizontalGroup("Identity")]
[LabelText("Text Key")]
[LabelWidth(52)]
[Tooltip("实际显示文本的 Unity Localization Entry Key。")]
public string dialogueKey;
/// <summary>
/// 此对话可被抽取的条件;留空表示始终可用。
/// </summary>
[LabelText("Availability")]
[Tooltip("此候选对话可参与抽取的条件;留空表示始终可用。")]
public StoryCondition availabilityCondition = new StoryCondition();
/// <summary>
/// 在所有满足条件的候选中的相对抽取权重。值越大,出现概率越高;
/// 小于 1 的值在运行时应按 1 处理,避免无效的零或负权重。
/// </summary>
[LabelText("Weight")]
[MinValue(1)]
[Tooltip("在满足条件的候选中使用的相对抽取权重,最小为 1。")]
public int weight = 1;
}
}