Files
Cielonos/Assets/Scripts/SLSUtilities/Narrative/Base/Data/StoryProjectDatabase.cs
SoulliesOfficial 8186f54e90 新场景,剧情
2026-06-02 12:55:39 -04:00

105 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.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace SLSUtilities.Narrative
{
[CreateAssetMenu(fileName = "Story Project Database", menuName = "SLSUtilities/Story System/Story Project Database")]
public class StoryProjectDatabase : SerializedScriptableObject
{
// 巧妙利用 Odin 的嵌套分组语法:"父分组/子分组"
// 这样就可以让 TitleGroup 作为父节点显示在最上方,而 BoxGroup 嵌套在其中,解决了 Title 被包裹在 Box 里的问题。
[TitleGroup("全局剧情数据库", "集中管理所有剧情相关数据的注册中心", Alignment = TitleAlignments.Centered)]
[ListDrawerSettings(ShowIndexLabels = true, ListElementLabelName = "nameKey")]
[BoxGroup("全局剧情数据库/角色档案 (Characters)")]
[LabelText("角色档案列表 (Character Profiles)")]
public List<CharacterData> characters = new List<CharacterData>();
[ListDrawerSettings(ShowIndexLabels = true)]
[BoxGroup("全局剧情数据库/变量数据 (Variables)")]
[LabelText("变量数据组 (Variable Groups)")]
public List<VariableData> variables = new List<VariableData>();
[ListDrawerSettings(ShowIndexLabels = true, ListElementLabelName = "keyword")]
[BoxGroup("全局剧情数据库/已注册的资产 (Registered Assets)")]
[LabelText("关键词词条 (Keywords)")]
public List<KeywordData> keywords = new List<KeywordData>();
[ListDrawerSettings(ShowIndexLabels = true, ListElementLabelName = "storyId")]
[BoxGroup("全局剧情数据库/剧情入口 (Narrative Entries)")]
[LabelText("剧情入口路由表 (Narrative Entries)")]
public List<NarrativeEntry> narrativeEntries = new List<NarrativeEntry>();
[Button("自动扫描并注册数据 (Auto-Scan Directory)", ButtonSizes.Large, Icon = SdfIconType.Search)]
[GUIColor(0.4f, 0.8f, 1f)]
[PropertyTooltip("自动在当前数据库所在的文件夹(及其子文件夹)中寻找所有的 CharacterData、VariableData、KeywordData 和 NarrativeEntry并自动填入上方的列表中。")]
public void AutoPopulate()
{
#if UNITY_EDITOR
// 获取当前 Database 资产所在的目录路径
string dbPath = AssetDatabase.GetAssetPath(this);
if (string.IsNullOrEmpty(dbPath))
{
Debug.LogWarning("[StorySystem] 请先将数据库资产 (Database) 保存到项目目录中。");
return;
}
string searchDirectory = System.IO.Path.GetDirectoryName(dbPath);
// 搜索 CharacterData
string[] charGuids = AssetDatabase.FindAssets($"t:{nameof(CharacterData)}", new[] { searchDirectory });
characters.Clear();
foreach (var guid in charGuids)
{
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
var charData = AssetDatabase.LoadAssetAtPath<CharacterData>(assetPath);
if (charData != null && !characters.Contains(charData))
characters.Add(charData);
}
// 搜索 VariableData
string[] varGuids = AssetDatabase.FindAssets($"t:{nameof(VariableData)}", new[] { searchDirectory });
variables.Clear();
foreach (var guid in varGuids)
{
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
var varData = AssetDatabase.LoadAssetAtPath<VariableData>(assetPath);
if (varData != null && !variables.Contains(varData))
variables.Add(varData);
}
// 搜索 KeywordData
string[] kwGuids = AssetDatabase.FindAssets($"t:{nameof(KeywordData)}", new[] { searchDirectory });
keywords.Clear();
foreach (var guid in kwGuids)
{
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
var kwData = AssetDatabase.LoadAssetAtPath<KeywordData>(assetPath);
if (kwData != null && !keywords.Contains(kwData))
keywords.Add(kwData);
}
// 搜索 NarrativeEntry
string[] entryGuids = AssetDatabase.FindAssets($"t:{nameof(NarrativeEntry)}", new[] { searchDirectory });
narrativeEntries.Clear();
foreach (var guid in entryGuids)
{
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
var entryData = AssetDatabase.LoadAssetAtPath<NarrativeEntry>(assetPath);
if (entryData != null && !narrativeEntries.Contains(entryData))
narrativeEntries.Add(entryData);
}
EditorUtility.SetDirty(this);
AssetDatabase.SaveAssets();
Debug.Log($"[StorySystem] 自动扫描完成!共注册了 {characters.Count} 个角色档案、{variables.Count} 个变量数据组、{keywords.Count} 个关键词词条 和 {narrativeEntries.Count} 个剧情入口路由表。");
#else
Debug.LogWarning("自动扫描 (AutoPopulate) 只能在 Unity 编辑器环境下运行。");
#endif
}
}
}