mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-09-27 02:36:14 +00:00
提交GAS 打算做一个帧同步的GAS
This commit is contained in:
223
JEX_GAS/Assets/GAS/Editor/AttributeSet/AttributeSetAsset.cs
Normal file
223
JEX_GAS/Assets/GAS/Editor/AttributeSet/AttributeSetAsset.cs
Normal file
@@ -0,0 +1,223 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using GAS.Editor.General;
|
||||
using GAS.General;
|
||||
using GAS.General.Validation;
|
||||
using Sirenix.OdinInspector;
|
||||
using Sirenix.Utilities.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GAS.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class AttributeSetConfig
|
||||
{
|
||||
public static AttributeSetAsset ParentAsset;
|
||||
|
||||
private static IEnumerable AttributeChoices = new ValueDropdownList<string>();
|
||||
|
||||
[HorizontalGroup("A")]
|
||||
[HorizontalGroup("A/R", order: 1)]
|
||||
[DisplayAsString(TextAlignment.Left, FontSize = 18)]
|
||||
[HideLabel]
|
||||
[ValidateInput("@ExistDuplicatedAttribute() == false", GASTextDefine.ERROR_DuplicatedAttribute)]
|
||||
[InfoBox(GASTextDefine.ERROR_Empty, InfoMessageType.Error, VisibleIf = "EmptyAttribute")]
|
||||
[InfoBox(GASTextDefine.ERROR_EmptyName, InfoMessageType.Error, VisibleIf = "EmptyAttributeSetName")]
|
||||
public string Name = "Unnamed";
|
||||
|
||||
[Space]
|
||||
[ListDrawerSettings(ShowFoldout = true, ShowIndexLabels = false, ShowItemCount = false, ShowPaging = false)]
|
||||
[ValueDropdown("AttributeChoices", IsUniqueList = true)]
|
||||
[DisableContextMenu(disableForMember: false, disableCollectionElements: true)]
|
||||
[CustomContextMenu("排序", "@SortAttributeNames()")]
|
||||
[LabelText("Attributes")]
|
||||
[Searchable]
|
||||
public List<string> AttributeNames = new();
|
||||
|
||||
private void SortAttributeNames() => AttributeNames = AttributeNames.OrderBy(x => x).ToList();
|
||||
|
||||
[HorizontalGroup("A", Width = 50)]
|
||||
[HorizontalGroup("A/L", order: 0, Width = 50)]
|
||||
[Button(SdfIconType.Brush, "", ButtonHeight = 25)]
|
||||
public void EditName()
|
||||
{
|
||||
StringEditWindow.OpenWindow("AttributeSet Name", Name, Validations.ValidateVariableName, OnEditNameSuccess,
|
||||
"Edit AttributeSet Name");
|
||||
}
|
||||
|
||||
private void OnEditNameSuccess(string newName)
|
||||
{
|
||||
Name = newName;
|
||||
ParentAsset.SaveAsset();
|
||||
}
|
||||
|
||||
public static void SetAttributeChoices(List<string> attributeChoices)
|
||||
{
|
||||
var choices = new ValueDropdownList<string>();
|
||||
foreach (var attribute in attributeChoices)
|
||||
{
|
||||
choices.Add(attribute, attribute);
|
||||
}
|
||||
|
||||
AttributeChoices = choices;
|
||||
}
|
||||
|
||||
public bool EmptyAttribute()
|
||||
{
|
||||
return AttributeNames.Count == 0;
|
||||
}
|
||||
|
||||
public bool EmptyAttributeSetName()
|
||||
{
|
||||
return string.IsNullOrEmpty(Name);
|
||||
}
|
||||
|
||||
public bool ExistDuplicatedAttribute()
|
||||
{
|
||||
var duplicates = AttributeNames
|
||||
.Where(a => !string.IsNullOrEmpty(a))
|
||||
.GroupBy(a => a)
|
||||
.Where(group => group.Count() > 1)
|
||||
.Select(group => group.Key)
|
||||
.ToList();
|
||||
return duplicates.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
[FilePath(GasDefine.GAS_ATTRIBUTE_SET_ASSET_PATH)]
|
||||
public class AttributeSetAsset : ScriptableSingleton<AttributeSetAsset>
|
||||
{
|
||||
[BoxGroup("Warning", order: -1)]
|
||||
[HideLabel]
|
||||
[ShowIf("ExistDuplicatedAttributeSetName")]
|
||||
[DisplayAsString(TextAlignment.Left, true)]
|
||||
public string ERROR_DuplicatedAttributeSet = "";
|
||||
|
||||
[VerticalGroup("AttributeSetConfigs", order: 1)]
|
||||
[ListDrawerSettings(ShowFoldout = true,
|
||||
CustomAddFunction = "OnAddAttributeSet",
|
||||
CustomRemoveElementFunction = "OnRemoveElement",
|
||||
CustomRemoveIndexFunction = "OnRemoveIndex")]
|
||||
[DisableContextMenu(disableForMember: false, disableCollectionElements: true)]
|
||||
[CustomContextMenu("排序", "@SortAttributeSetConfigs()")]
|
||||
[Searchable]
|
||||
public List<AttributeSetConfig> AttributeSetConfigs = new List<AttributeSetConfig>();
|
||||
|
||||
private void SortAttributeSetConfigs() => AttributeSetConfigs = AttributeSetConfigs.OrderBy(x => x.Name).ToList();
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
AttributeSetConfig.ParentAsset = this;
|
||||
var asset = AttributeAsset.LoadOrCreate();
|
||||
var attributeChoices = asset != null ? (from attr in asset.attributes where !string.IsNullOrWhiteSpace(attr.Name) select attr.Name).ToList() : new();
|
||||
AttributeSetConfig.SetAttributeChoices(attributeChoices);
|
||||
}
|
||||
|
||||
public void SaveAsset()
|
||||
{
|
||||
EditorUtility.SetDirty(this);
|
||||
UpdateAsset(this);
|
||||
Save();
|
||||
Debug.Log("[EX] AttributeSetAsset save!");
|
||||
}
|
||||
|
||||
[VerticalGroup("Generate AttributeSet Code", order: 0)]
|
||||
[GUIColor(0, 0.9f, 0)]
|
||||
[Button(SdfIconType.Upload, GASTextDefine.BUTTON_GenerateAttributeSetCode, ButtonHeight = 30, Expanded = true)]
|
||||
[InfoBox(GASTextDefine.ERROR_InElements, InfoMessageType.Error, VisibleIf = "ErrorInElements")]
|
||||
private void GenCode()
|
||||
{
|
||||
if (ExistDuplicatedAttributeSetName() || ErrorInElements())
|
||||
{
|
||||
EditorUtility.DisplayDialog("Warning", "Please check the warning message!\n" +
|
||||
"Fix the AttributeSet Error!\n", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
SaveAsset();
|
||||
AttributeSetClassGen.Gen();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
bool ErrorInElements()
|
||||
{
|
||||
return AttributeSetConfigs.Any(attribute =>
|
||||
attribute.EmptyAttribute() ||
|
||||
attribute.ExistDuplicatedAttribute() ||
|
||||
attribute.EmptyAttributeSetName());
|
||||
}
|
||||
|
||||
bool ExistDuplicatedAttributeSetName()
|
||||
{
|
||||
var duplicates = AttributeSetConfigs
|
||||
.Where(a => !string.IsNullOrEmpty(a.Name))
|
||||
.GroupBy(a => a.Name)
|
||||
.Where(group => group.Count() > 1)
|
||||
.Select(group => group.Key)
|
||||
.ToList();
|
||||
if (duplicates.Count > 0)
|
||||
{
|
||||
var duplicatedAttributeSets = duplicates.Aggregate("", (current, d) => current + d + ",");
|
||||
duplicatedAttributeSets = duplicatedAttributeSets.Remove(duplicatedAttributeSets.Length - 1, 1);
|
||||
ERROR_DuplicatedAttributeSet =
|
||||
string.Format(GASTextDefine.ERROR_DuplicatedAttributeSet, duplicatedAttributeSets);
|
||||
}
|
||||
|
||||
return duplicates.Count > 0;
|
||||
}
|
||||
|
||||
private void OnAddAttributeSet()
|
||||
{
|
||||
StringEditWindow.OpenWindow("AttributeSet Name", "", (newName) =>
|
||||
{
|
||||
var validateVariableName = Validations.ValidateVariableName(newName);
|
||||
|
||||
if (!validateVariableName.IsValid)
|
||||
{
|
||||
return validateVariableName;
|
||||
}
|
||||
|
||||
if (AttributeSetConfigs.Exists(x => x.Name == newName))
|
||||
{
|
||||
return ValidationResult.Invalid($"The name(\"{newName}\") already exists!");
|
||||
}
|
||||
|
||||
return ValidationResult.Valid;
|
||||
},
|
||||
attributeSetName => AttributeSetConfigs.Add(new AttributeSetConfig() { Name = attributeSetName }),
|
||||
"Create new AttributeSet");
|
||||
GUIUtility.ExitGUI(); // In order to solve: "EndLayoutGroup: BeginLayoutGroup must be called first."
|
||||
}
|
||||
|
||||
private int OnRemoveElement(AttributeSetConfig attributeSet)
|
||||
{
|
||||
var result = EditorUtility.DisplayDialog("Confirmation",
|
||||
$"Are you sure you want to REMOVE AttributeSet:{attributeSet.Name}?",
|
||||
"Yes", "No");
|
||||
|
||||
if (!result) return -1;
|
||||
|
||||
Debug.Log($"[EX] AttributeSet Asset remove element:{attributeSet.Name} !");
|
||||
SaveAsset();
|
||||
return AttributeSetConfigs.IndexOf(attributeSet);
|
||||
}
|
||||
|
||||
private int OnRemoveIndex(int index)
|
||||
{
|
||||
var attributeSet = AttributeSetConfigs[index];
|
||||
var result = EditorUtility.DisplayDialog("Confirmation",
|
||||
$"Are you sure you want to REMOVE AttributeSet:{attributeSet.Name}?",
|
||||
"Yes", "No");
|
||||
|
||||
if (!result) return -1;
|
||||
|
||||
AttributeSetConfigs.RemoveAt(index);
|
||||
Debug.Log($"[EX] Attribute Asset remove element:{attributeSet.Name} !");
|
||||
SaveAsset();
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9c4e9ba159c4e7d8da87897fb20cb56
|
||||
timeCreated: 1703054408
|
257
JEX_GAS/Assets/GAS/Editor/AttributeSet/AttributeSetClassGen.cs
Normal file
257
JEX_GAS/Assets/GAS/Editor/AttributeSet/AttributeSetClassGen.cs
Normal file
@@ -0,0 +1,257 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using GAS.Runtime;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GAS.Editor
|
||||
{
|
||||
public static class AttributeSetClassGen
|
||||
{
|
||||
public static void Gen()
|
||||
{
|
||||
var attributeSetAsset = AttributeSetAsset.LoadOrCreate();
|
||||
|
||||
var attributeAsset = AttributeAsset.LoadOrCreate();
|
||||
var attributeNames =
|
||||
(from t in attributeAsset.attributes where !string.IsNullOrWhiteSpace(t.Name) select t.Name)
|
||||
.ToList();
|
||||
|
||||
// Check if AttributeSet contains attribute that is not defined in AttributeAsset
|
||||
foreach (var attributeSetConfig in attributeSetAsset.AttributeSetConfigs)
|
||||
{
|
||||
foreach (var attributeName in attributeSetConfig.AttributeNames)
|
||||
{
|
||||
if (!attributeNames.Contains(attributeName))
|
||||
{
|
||||
var msg = $"Invalid Attribute(\"{attributeName}\") in AttributeSet(\"{attributeSetConfig.Name}\"), \"{attributeName}\" is not defined in AttributeAsset!";
|
||||
Debug.LogError(msg);
|
||||
EditorUtility.DisplayDialog("Error", msg, "OK");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var invalidAttributes = attributeAsset.attributes.Where(x =>
|
||||
x.CalculateMode is CalculateMode.MinValueOnly or CalculateMode.MaxValueOnly &&
|
||||
x.SupportedOperation != SupportedOperation.Override).ToArray();
|
||||
if (invalidAttributes.Length > 0)
|
||||
{
|
||||
var msg =
|
||||
$"计算模式为\"取最小值\"或\"取最大值\"的属性只能支持\"替换\"操作:\n{string.Join("\n", invalidAttributes.Select(x => $"\"{x.Name}\""))}";
|
||||
Debug.LogError(msg.Replace("\n", ", "));
|
||||
EditorUtility.DisplayDialog("Error", msg, "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
string pathWithoutAssets = Application.dataPath.Substring(0, Application.dataPath.Length - 6);
|
||||
var filePath =
|
||||
$"{pathWithoutAssets}/{GASSettingAsset.CodeGenPath}/{GasDefine.GAS_ATTRIBUTESET_LIB_CSHARP_SCRIPT_NAME}";
|
||||
GenerateAttributeCollection(attributeSetAsset.AttributeSetConfigs, attributeAsset, filePath);
|
||||
|
||||
Console.WriteLine($"Generated Code Script at path: {filePath}");
|
||||
}
|
||||
|
||||
private static void GenerateAttributeCollection(List<AttributeSetConfig> attributeSetConfigs,
|
||||
AttributeAsset attributeAsset, string filePath)
|
||||
{
|
||||
using var writer = new IndentedWriter(new StreamWriter(filePath));
|
||||
|
||||
writer.WriteLine("///////////////////////////////////");
|
||||
writer.WriteLine("//// This is a generated file. ////");
|
||||
writer.WriteLine("//// Do not modify it. ////");
|
||||
writer.WriteLine("///////////////////////////////////");
|
||||
|
||||
writer.WriteLine("");
|
||||
|
||||
writer.WriteLine("using System;");
|
||||
writer.WriteLine("using System.Collections.Generic;");
|
||||
|
||||
writer.WriteLine("");
|
||||
|
||||
writer.WriteLine("namespace GAS.Runtime");
|
||||
writer.WriteLine("{");
|
||||
writer.Indent++;
|
||||
{
|
||||
foreach (var attributeSetConfig in attributeSetConfigs.OrderBy(x => x.Name))
|
||||
{
|
||||
var validName = EditorUtil.MakeValidIdentifier(attributeSetConfig.Name);
|
||||
writer.WriteLine($"public class AS_{validName} : AttributeSet");
|
||||
writer.WriteLine("{");
|
||||
writer.Indent++;
|
||||
{
|
||||
bool skippedFirst = false;
|
||||
foreach (var attributeName in attributeSetConfig.AttributeNames.OrderBy(x => x))
|
||||
{
|
||||
var attributeAccessor = attributeAsset.attributes.Find(x => x.Name == attributeName);
|
||||
|
||||
if (!skippedFirst) skippedFirst = true;
|
||||
else writer.WriteLine("");
|
||||
|
||||
string validAttrName = EditorUtil.MakeValidIdentifier(attributeName);
|
||||
writer.WriteLine($"#region {attributeName}");
|
||||
writer.WriteLine("");
|
||||
{
|
||||
writer.WriteLine($"/// <summary>{attributeAccessor.Comment}</summary>");
|
||||
writer.WriteLine($"public AttributeBase {validAttrName} {{ get; }} = new(\"AS_{validName}\", \"{attributeName}\", {attributeAccessor.DefaultValue}f, CalculateMode.{attributeAccessor.CalculateMode}, (SupportedOperation){(byte)attributeAccessor.SupportedOperation}, {(attributeAccessor.LimitMinValue ? attributeAccessor.MinValue + "f" : "float.MinValue")}, {(attributeAccessor.LimitMaxValue ? attributeAccessor.MaxValue + "f" : "float.MaxValue")});");
|
||||
writer.WriteLine("");
|
||||
writer.WriteLine($"public void Init{validAttrName}(float value) => {validAttrName}.Init(value);");
|
||||
writer.WriteLine($"public void SetCurrent{validAttrName}(float value) => {validAttrName}.SetCurrentValue(value);");
|
||||
writer.WriteLine($"public void SetBase{validAttrName}(float value) => {validAttrName}.SetBaseValue(value);");
|
||||
writer.WriteLine($"public void SetMin{validAttrName}(float value) => {validAttrName}.SetMinValue(value);");
|
||||
writer.WriteLine($"public void SetMax{validAttrName}(float value) => {validAttrName}.SetMaxValue(value);");
|
||||
writer.WriteLine($"public void SetMinMax{validAttrName}(float min, float max) => {validAttrName}.SetMinMaxValue(min, max);");
|
||||
}
|
||||
writer.WriteLine("");
|
||||
writer.WriteLine($"#endregion {attributeName}");
|
||||
}
|
||||
|
||||
writer.WriteLine("");
|
||||
|
||||
writer.WriteLine("public override AttributeBase this[string key]");
|
||||
writer.WriteLine("{");
|
||||
writer.Indent++;
|
||||
{
|
||||
writer.WriteLine("get");
|
||||
writer.WriteLine("{");
|
||||
writer.Indent++;
|
||||
{
|
||||
writer.WriteLine("switch (key)");
|
||||
writer.WriteLine("{");
|
||||
writer.Indent++;
|
||||
{
|
||||
foreach (var attributeName in attributeSetConfig.AttributeNames)
|
||||
{
|
||||
string validAttrName = EditorUtil.MakeValidIdentifier(attributeName);
|
||||
writer.WriteLine($"case \"{validAttrName}\":");
|
||||
writer.Indent++;
|
||||
{
|
||||
writer.WriteLine($"return {validAttrName};");
|
||||
}
|
||||
writer.Indent--;
|
||||
}
|
||||
}
|
||||
writer.Indent--;
|
||||
writer.WriteLine("}");
|
||||
writer.WriteLine("");
|
||||
writer.WriteLine("return null;");
|
||||
}
|
||||
writer.Indent--;
|
||||
writer.WriteLine("}");
|
||||
}
|
||||
writer.Indent--;
|
||||
writer.WriteLine("}");
|
||||
|
||||
writer.WriteLine("");
|
||||
|
||||
writer.WriteLine("public override string[] AttributeNames { get; } =");
|
||||
writer.WriteLine("{");
|
||||
writer.Indent++;
|
||||
{
|
||||
foreach (var attributeName in attributeSetConfig.AttributeNames)
|
||||
{
|
||||
string validAttrName = EditorUtil.MakeValidIdentifier(attributeName);
|
||||
writer.WriteLine($"\"{validAttrName}\",");
|
||||
}
|
||||
}
|
||||
writer.Indent--;
|
||||
writer.WriteLine("};");
|
||||
|
||||
writer.WriteLine("");
|
||||
writer.WriteLine("public override void SetOwner(AbilitySystemComponent owner)");
|
||||
writer.WriteLine("{");
|
||||
writer.Indent++;
|
||||
{
|
||||
writer.WriteLine("_owner = owner;");
|
||||
foreach (var attributeName in attributeSetConfig.AttributeNames)
|
||||
{
|
||||
string validAttrName = EditorUtil.MakeValidIdentifier(attributeName);
|
||||
writer.WriteLine($"{validAttrName}.SetOwner(owner);");
|
||||
}
|
||||
}
|
||||
writer.Indent--;
|
||||
writer.WriteLine("}");
|
||||
|
||||
writer.WriteLine("");
|
||||
writer.WriteLine("public static class Lookup");
|
||||
writer.WriteLine("{");
|
||||
writer.Indent++;
|
||||
{
|
||||
foreach (var attributeName in attributeSetConfig.AttributeNames)
|
||||
{
|
||||
string validAttrName = EditorUtil.MakeValidIdentifier(attributeName);
|
||||
writer.WriteLine(
|
||||
$"public const string {attributeName} = \"AS_{validName}.{validAttrName}\";");
|
||||
}
|
||||
}
|
||||
writer.Indent--;
|
||||
writer.WriteLine("}");
|
||||
}
|
||||
writer.Indent--;
|
||||
writer.WriteLine("}");
|
||||
writer.WriteLine("");
|
||||
}
|
||||
|
||||
writer.WriteLine($"public static class GAttrSetLib");
|
||||
writer.WriteLine("{");
|
||||
writer.Indent++;
|
||||
{
|
||||
writer.WriteLine("public static readonly IReadOnlyDictionary<string, Type> AttrSetTypeDict = new Dictionary<string, Type>");
|
||||
writer.WriteLine("{");
|
||||
writer.Indent++;
|
||||
{
|
||||
foreach (var attributeSet in attributeSetConfigs)
|
||||
{
|
||||
var validName = EditorUtil.MakeValidIdentifier(attributeSet.Name);
|
||||
writer.WriteLine($"{{ \"{attributeSet.Name}\", typeof(AS_{validName}) }},");
|
||||
}
|
||||
}
|
||||
writer.Indent--;
|
||||
writer.WriteLine("};");
|
||||
|
||||
writer.WriteLine("");
|
||||
|
||||
writer.WriteLine("public static readonly IReadOnlyDictionary<Type, string> TypeToName = new Dictionary<Type, string>");
|
||||
writer.WriteLine("{");
|
||||
writer.Indent++;
|
||||
{
|
||||
foreach (var attributeSet in attributeSetConfigs)
|
||||
{
|
||||
var validName = EditorUtil.MakeValidIdentifier(attributeSet.Name);
|
||||
writer.WriteLine($"{{ typeof(AS_{validName}), nameof(AS_{validName}) }},");
|
||||
}
|
||||
}
|
||||
writer.Indent--;
|
||||
writer.WriteLine("};");
|
||||
|
||||
writer.WriteLine("");
|
||||
|
||||
writer.WriteLine("public static readonly IReadOnlyList<string> AttributeFullNames = new List<string>");
|
||||
writer.WriteLine("{");
|
||||
writer.Indent++;
|
||||
{
|
||||
foreach (var attributeSet in attributeSetConfigs)
|
||||
{
|
||||
var validName = EditorUtil.MakeValidIdentifier(attributeSet.Name);
|
||||
foreach (var attributeName in attributeSet.AttributeNames)
|
||||
{
|
||||
string validAttrName = EditorUtil.MakeValidIdentifier(attributeName);
|
||||
writer.WriteLine($"\"AS_{validName}.{validAttrName}\",");
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.Indent--;
|
||||
writer.WriteLine("};");
|
||||
}
|
||||
writer.Indent--;
|
||||
writer.WriteLine("}");
|
||||
}
|
||||
writer.Indent--;
|
||||
writer.Write("}");
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e974fd010a447309cdd4bd5abb5ac24
|
||||
timeCreated: 1703129737
|
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GAS.Editor
|
||||
{
|
||||
public class AttributeSetConfigEditorWindow : EditorWindow
|
||||
{
|
||||
private static List<string> _attributeOptions;
|
||||
|
||||
public string editedName = "";
|
||||
|
||||
public List<string> attributeNames;
|
||||
|
||||
private Action<string, List<string>> _callback;
|
||||
private Func<AttributeSetConfig, bool> _checkAttributeSetValid;
|
||||
|
||||
private List<int> _selectedAttributeIndexes;
|
||||
|
||||
private GUIStyle BigFontLabelStyle;
|
||||
|
||||
private static List<string> AttributeOptions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_attributeOptions == null)
|
||||
{
|
||||
var asset = AttributeAsset.LoadOrCreate();
|
||||
_attributeOptions = asset != null ? (from attr in asset.attributes where !string.IsNullOrWhiteSpace(attr.Name) select attr.Name).OrderBy(x => x).ToList() : new();
|
||||
}
|
||||
|
||||
return _attributeOptions;
|
||||
}
|
||||
}
|
||||
|
||||
public static void OpenWindow(string initialString, List<string> attributeNames,
|
||||
Action<string, List<string>> callback, Func<AttributeSetConfig, bool> checkAttributeSetValid)
|
||||
{
|
||||
var window = GetWindow<AttributeSetConfigEditorWindow>();
|
||||
window.Init(initialString, attributeNames, callback, checkAttributeSetValid);
|
||||
window.Show();
|
||||
}
|
||||
|
||||
Vector2 scrollPosition = Vector2.zero;
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("AttributeSet:", GUILayout.Width(80));
|
||||
editedName = EditorGUILayout.TextField("", editedName);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (GUILayout.Button("Add Attribute", GUILayout.Width(100)))
|
||||
{
|
||||
attributeNames.Add("");
|
||||
_selectedAttributeIndexes.Add(-1);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUI.skin.box);
|
||||
|
||||
for (var i = 0; i < attributeNames.Count; i++)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
EditorGUILayout.LabelField("Attribute:", GUILayout.Width(80));
|
||||
_selectedAttributeIndexes[i] = EditorGUILayout.Popup("", _selectedAttributeIndexes[i],
|
||||
AttributeOptions.ToArray());
|
||||
|
||||
// 更新选中的字符串
|
||||
attributeNames[i] = _selectedAttributeIndexes[i] < 0
|
||||
? ""
|
||||
: AttributeOptions[_selectedAttributeIndexes[i]];
|
||||
|
||||
if (GUILayout.Button("Remove", GUILayout.Width(100)))
|
||||
{
|
||||
attributeNames.RemoveAt(i);
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Save")) Save();
|
||||
}
|
||||
|
||||
public void Init(string initialString, List<string> attributeNames, Action<string, List<string>> callback,
|
||||
Func<AttributeSetConfig, bool> checkAttributeSetValid)
|
||||
{
|
||||
editedName = initialString;
|
||||
_callback = callback;
|
||||
_checkAttributeSetValid = checkAttributeSetValid;
|
||||
this.attributeNames = attributeNames;
|
||||
_selectedAttributeIndexes = new List<int>();
|
||||
foreach (var attributeName in attributeNames)
|
||||
_selectedAttributeIndexes.Add(AttributeOptions.IndexOf(attributeName));
|
||||
|
||||
|
||||
BigFontLabelStyle = new GUIStyle(EditorStyles.label);
|
||||
BigFontLabelStyle.fontSize = 20; // 设置字体大小为 16
|
||||
}
|
||||
|
||||
private void Save()
|
||||
{
|
||||
var attributeSetConfig = new AttributeSetConfig()
|
||||
{
|
||||
Name = editedName,
|
||||
AttributeNames = attributeNames
|
||||
};
|
||||
var valid = _checkAttributeSetValid?.Invoke(attributeSetConfig) ?? true;
|
||||
if (valid)
|
||||
{
|
||||
_callback?.Invoke(editedName, attributeNames);
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a9a04f50ed041b3b47a5ad09eff154d
|
||||
timeCreated: 1703128232
|
@@ -0,0 +1,27 @@
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace GAS.Editor
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using GAS;
|
||||
using Runtime;
|
||||
using UnityEditor;
|
||||
using Editor;
|
||||
|
||||
public static class AttributeSetEditorUtil
|
||||
{
|
||||
public static List<string> GetAttributeSetChoice()
|
||||
{
|
||||
var choices = new List<string>();
|
||||
var asset = AttributeSetAsset.LoadOrCreate();
|
||||
foreach (var attributeSetConfig in asset.AttributeSetConfigs)
|
||||
{
|
||||
var config = attributeSetConfig;
|
||||
choices.Add(config.Name);
|
||||
}
|
||||
|
||||
return choices;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7dd544418f04fa688f327cc695056d1
|
||||
timeCreated: 1704248957
|
@@ -0,0 +1,65 @@
|
||||
#if UNITY_EDITOR
|
||||
namespace GAS.Editor
|
||||
{
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
public class AttributeSetSettingsProvider: SettingsProvider
|
||||
{
|
||||
private AttributeSetAsset _asset;
|
||||
private Editor _editor;
|
||||
|
||||
public AttributeSetSettingsProvider() : base("Project/EX Gameplay Ability System/AttributeSet Manager", SettingsScope.Project)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnActivate(string searchContext, VisualElement rootElement)
|
||||
{
|
||||
var asset = AttributeSetAsset.LoadOrCreate();
|
||||
_asset = asset;
|
||||
_editor = Editor.CreateEditor(asset);
|
||||
GASSettingStatusWatcher.OnEditorFocused += OnEditorFocused;
|
||||
}
|
||||
|
||||
public override void OnDeactivate()
|
||||
{
|
||||
base.OnDeactivate();
|
||||
GASSettingStatusWatcher.OnEditorFocused -= OnEditorFocused;
|
||||
AttributeSetAsset.Save();
|
||||
}
|
||||
|
||||
private void OnEditorFocused()
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
|
||||
public override void OnGUI(string searchContext)
|
||||
{
|
||||
base.OnGUI(searchContext);
|
||||
|
||||
if (_editor == null) return;
|
||||
|
||||
EditorGUILayout.BeginVertical(GUI.skin.box);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
_editor.OnInspectorGUI();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
static AttributeSetSettingsProvider provider;
|
||||
[SettingsProvider]
|
||||
public static SettingsProvider CreateMyCustomSettingsProvider()
|
||||
{
|
||||
if (AttributeSetAsset.Instance && provider == null)
|
||||
{
|
||||
provider = new AttributeSetSettingsProvider();
|
||||
using (var so = new SerializedObject(AttributeSetAsset.Instance))
|
||||
{
|
||||
provider.keywords = GetSearchKeywordsFromSerializedObject(so);
|
||||
}
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a9b99ebbddc406ebd77864cc1a51026
|
||||
timeCreated: 1713234604
|
Reference in New Issue
Block a user