Files
Continentis/Assets/Scripts/MainGame/Card/Editor/CardDataEditor.cs
SoulliesOfficial 2906206f0c keyword + animation
2025-10-27 07:04:34 -04:00

232 lines
10 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.
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using SLSFramework.UModAssistance;
using Continentis.MainGame.Character;
using Continentis.Mods;
namespace Continentis.MainGame.Card
{
[CustomEditor(typeof(CardData))]
public partial class CardDataEditor : DataEditor
{
// 存储我们需要自定义绘制的属性的引用
private SerializedProperty modNameProp;
private SerializedProperty classNameProp;
private SerializedProperty displayNameProp;
private SerializedProperty cardRarityProp;
private SerializedProperty cardTypeProp;
private SerializedProperty keywordsProp;
private SerializedProperty cardSpriteProp;
private SerializedProperty cardLayoutTagsProp;
private SerializedProperty functionTextProp;
private SerializedProperty cardDescriptionProp;
private SerializedProperty baseWeightProp;
private SerializedProperty variableAttributesProp;
private SerializedProperty originalAttributesProp;
private SerializedProperty runtimeCurrentAttributesProp;
private SerializedProperty upgradeNodeProp;
private SerializedProperty prefabsProp;
private SerializedProperty derivativeCardsProp;
private SerializedProperty derivativeCharactersProp;
protected override void OnEnable()
{
base.OnEnable();
LoadAllKeywordsFromEditRefs();
// 在启用时根据我们修改后的字段名找到对应的SerializedProperty
modNameProp = serializedObject.FindProperty("modName");
classNameProp = serializedObject.FindProperty("className");
displayNameProp = serializedObject.FindProperty("displayName");
cardRarityProp = serializedObject.FindProperty("cardRarity");
cardTypeProp = serializedObject.FindProperty("cardType");
keywordsProp = serializedObject.FindProperty("keywords");
cardSpriteProp = serializedObject.FindProperty("cardSprite");
cardLayoutTagsProp = serializedObject.FindProperty("cardLayoutTags");
functionTextProp = serializedObject.FindProperty("functionText");
cardDescriptionProp = serializedObject.FindProperty("cardDescription");
baseWeightProp = serializedObject.FindProperty("baseWeight");
variableAttributesProp = serializedObject.FindProperty("variableAttributes");
originalAttributesProp = serializedObject.FindProperty("originalAttributes");
runtimeCurrentAttributesProp = serializedObject.FindProperty("runtimeCurrentAttributes");
upgradeNodeProp = serializedObject.FindProperty("upgradeNode");
prefabsProp = serializedObject.FindProperty("prefabRefs");
derivativeCardsProp = serializedObject.FindProperty("derivativeCardDataRefs");
derivativeCharactersProp = serializedObject.FindProperty("derivativeCharacterDataRefs");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
// --- 绘制自定义的Type选择器 ---
// 我们把它从所有自动绘制的属性中分离出来,放在最前面或最后面,让布局更清晰
EditorGUILayout.Space(); // 增加一点间距
EditorGUILayout.LabelField("Fundamental", EditorStyles.boldLabel);
if (DrawTypeSelectorGUI(classNameProp, "Card Logic Class", typeof(CardLogicBase), out Type outType, "Continentis.Mods", "Cards"))
{
string className = classNameProp.stringValue;
string modName = outType.Namespace!.Replace("Continentis.Mods.", "").Split('.')[0];
string displayName = "Card_" + modName + "_" + className + "_DisplayName";
string functionTextName = "Card_" + modName + "_" + className + "_FunctionText";
modNameProp.stringValue = modName;
displayNameProp.stringValue = displayName;
functionTextProp.stringValue = functionTextName;
}
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.PropertyField(modNameProp);
EditorGUILayout.PropertyField(classNameProp);
EditorGUILayout.PropertyField(displayNameProp);
EditorGUI.EndDisabledGroup();
EditorGUILayout.PropertyField(cardRarityProp);
EditorGUILayout.PropertyField(cardTypeProp);
EditorGUILayout.PropertyField(keywordsProp, true);
if (keywordsProp.isExpanded)
{
DrawKeywordSelector();
}
EditorGUILayout.PropertyField(cardSpriteProp);
EditorGUILayout.PropertyField(cardLayoutTagsProp, true);
EditorGUILayout.PropertyField(functionTextProp);
EditorGUILayout.PropertyField(cardDescriptionProp);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Attributes", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(baseWeightProp);
EditorGUILayout.PropertyField(variableAttributesProp, true);
EditorGUILayout.PropertyField(originalAttributesProp, true);
EditorGUILayout.PropertyField(runtimeCurrentAttributesProp, true);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Upgrade", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(upgradeNodeProp);
// --- 绘制自定义的引用列表 ---
EditorGUILayout.Space();
EditorGUILayout.LabelField("References", EditorStyles.boldLabel);
DrawCharacterListGUI<GameObject>(prefabsProp);
DrawCharacterListGUI<CardData>(derivativeCardsProp);
DrawCharacterListGUI<CharacterData>(derivativeCharactersProp);
HandleObjectPicker();
serializedObject.ApplyModifiedProperties();
}
}
public partial class CardDataEditor
{
private List<string> allAvailableKeywords;
/// <summary>
/// 使用 AssetDatabase 查找项目中的所有 KeywordDatabase 并合并它们的列表
/// </summary>
private void LoadAllKeywordsFromEditRefs()
{
// 使用 HashSet 来自动处理重复的关键词
HashSet<string> allKeywordsSet = new HashSet<string>();
// 1. 查找项目中所有类型为 "KeywordDatabase" 的
// "t:KeywordDatabase" 是一个搜索过滤器t: 表示按类型搜索
string[] guids = AssetDatabase.FindAssets("t:ModEditReference");
foreach (string guid in guids)
{
// 2. 将 GUID 转换为资产路径
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
// 3. 加载该路径下的 ScriptableObject
ModEditReference editRef = AssetDatabase.LoadAssetAtPath<ModEditReference>(assetPath);
EditKeywordsReference cardKeywordsRef = editRef.cardKeywordsReference;
if (cardKeywordsRef != null && cardKeywordsRef.keywordRefs != null)
{
// 4. 将词库中的所有词添加到 Set 中
foreach (string keyword in cardKeywordsRef.keywordRefs.Keys)
{
if (!string.IsNullOrEmpty(keyword))
{
allKeywordsSet.Add(keyword);
}
}
}
}
// 5. 将 Set 转换为 List 并排序,以便在菜单中清晰显示
allAvailableKeywords = allKeywordsSet.ToList();
allAvailableKeywords.Sort();
}
private void DrawKeywordSelector()
{
// 1. 检查是否找到了任何关键词
if (allAvailableKeywords == null || allAvailableKeywords.Count == 0)
{
EditorGUILayout.HelpBox("在项目中没有找到任何 KeywordDatabase或者词库为空。", MessageType.Warning);
// 显示一个刷新按钮,以防用户刚刚创建了词库
if (GUILayout.Button("Refresh Keyword Edit References"))
{
LoadAllKeywordsFromEditRefs();
}
return;
}
List<string> currentKeywords = (target as CardData)!.keywords;
// 2. 找出尚未添加的关键词
List<string> keywordsToAdd = allAvailableKeywords.Except(currentKeywords).ToList();
// 3. 如果所有关键词都添加了,显示提示
if (keywordsToAdd.Count == 0)
{
EditorGUILayout.HelpBox("所有可用的关键词都已添加。", MessageType.Info);
}
else
{
// 4. 绘制 "Add Keyword" 按钮
if (GUILayout.Button("Add Keyword from Edit Refs..."))
{
GenericMenu menu = new GenericMenu();
foreach (string keyword in keywordsToAdd)
{
menu.AddItem(new GUIContent(keyword), false, () => {
AddKeywordToList(keyword);
});
}
menu.ShowAsContext();
}
}
// 5. (可选) 添加一个手动刷新按钮
// 因为 AssetDatabase.FindAssets() 速度很快所以我们也可以在每次GUI绘制时都调用
// 但如果词库很多,使用按钮刷新更好。
/*if (GUILayout.Button("Refresh Keyword Databases"))
{
LoadAllKeywordsFromEditRefs();
}*/
}
private void AddKeywordToList(string keyword)
{
keywordsProp.InsertArrayElementAtIndex(keywordsProp.arraySize);
SerializedProperty newElement = keywordsProp.GetArrayElementAtIndex(keywordsProp.arraySize - 1);
newElement.stringValue = keyword;
serializedObject.ApplyModifiedProperties();
}
}
}
#endif