105 lines
5.2 KiB
C#
105 lines
5.2 KiB
C#
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
|
||
}
|
||
}
|
||
} |