This commit is contained in:
Mikhail 2024-03-06 21:37:21 +08:00
parent f172b8212b
commit 3701423bf6
22 changed files with 288 additions and 238 deletions

View File

@ -70,29 +70,3 @@ namespace DCFApixels.DragonECS
#endif #endif
} }
} }
#if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
{
using UnityEditor;
[CustomEditor(typeof(AutoEntityCreator))]
[CanEditMultipleObjects]
public class AutoEntityCreatorEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("Autoset"))
{
foreach (var tr in targets)
{
AutoEntityCreator creator = (AutoEntityCreator)tr;
creator.Autoset_Editor();
EditorUtility.SetDirty(creator);
}
}
}
}
}
#endif

View File

@ -86,149 +86,3 @@ namespace DCFApixels.DragonECS
} }
} }
} }
#if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
{
using DCFApixels.DragonECS.Unity.Internal;
using UnityEditor;
[CustomEditor(typeof(EcsEntityConnect))]
[CanEditMultipleObjects]
public class EcsEntityEditor : Editor
{
private bool _isInit = false;
private EcsEntityConnect Target => (EcsEntityConnect)target;
private bool IsMultipleTargets => targets.Length > 1;
private void Init()
{
if (_isInit)
{
return;
}
_isInit = true;
}
public override void OnInspectorGUI()
{
Init();
EcsEntityConnect[] targets = new EcsEntityConnect[this.targets.Length];
for (int i = 0; i < targets.Length; i++)
{
targets[i] = (EcsEntityConnect)this.targets[i];
}
DrawEntityInfo(targets);
DrawTemplates();
DrawButtons();
DrawComponents(targets);
}
private void DrawEntityInfo(EcsEntityConnect[] targets)
{
float width = EditorGUIUtility.currentViewWidth;
float height = EditorGUIUtility.singleLineHeight;
Rect entityRect = GUILayoutUtility.GetRect(width, height + 3f);
var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(entityRect, 3f);
Color w = Color.gray;
w.a = 0.6f;
Color b = Color.black;
b.a = 0.55f;
EditorGUI.DrawRect(entityInfoRect, w);
var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(entityInfoRect, 0.5f);
var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f);
idRect = RectUtility.AddPadding(idRect, 2, 1, 0, 0);
genRect = RectUtility.AddPadding(genRect, 1, 1, 0, 0);
worldRect = RectUtility.AddPadding(worldRect, 1, 2, 0, 0);
EditorGUI.DrawRect(idRect, b);
EditorGUI.DrawRect(genRect, b);
EditorGUI.DrawRect(worldRect, b);
bool isConnected = Target.Entity.TryUnpack(out int id, out short gen, out short world);
GUIStyle style = new GUIStyle(EditorStyles.numberField);
style.alignment = TextAnchor.MiddleCenter;
style.font = EditorStyles.boldFont;
if (IsMultipleTargets == false && isConnected)
{
Color statusColor = EcsGUI.GreenColor;
statusColor.a = 0.6f;
EditorGUI.DrawRect(statusRect, statusColor);
EditorGUI.IntField(idRect, id, style);
EditorGUI.IntField(genRect, gen, style);
EditorGUI.IntField(worldRect, world, style);
}
else
{
Color statusColor = IsMultipleTargets ? new Color32(200, 200, 200, 255) : EcsGUI.RedColor;
statusColor.a = 0.6f;
EditorGUI.DrawRect(statusRect, statusColor);
using (new EditorGUI.DisabledScope(true))
{
GUI.Label(idRect, "Entity ID", style);
GUI.Label(genRect, "Generation", style);
GUI.Label(worldRect, "World ID", style);
}
}
}
private void DrawTemplates()
{
var iterator = serializedObject.GetIterator();
iterator.NextVisible(true);
bool enterChildren = true;
while (iterator.NextVisible(enterChildren))
{
EditorGUILayout.PropertyField(iterator, true);
enterChildren = false;
}
}
private void DrawButtons()
{
GUILayout.BeginHorizontal();
if (GUILayout.Button("Autoset"))
{
Target.SetTemplates_Editor(Target.GetComponents<MonoEntityTemplate>());
EditorUtility.SetDirty(target);
}
if (GUILayout.Button("Autoset Cascade"))
{
foreach (var item in Target.GetComponentsInChildren<EcsEntityConnect>())
{
item.SetTemplates_Editor(item.GetComponents<MonoEntityTemplate>());
EditorUtility.SetDirty(item);
}
}
GUILayout.EndHorizontal();
}
private void DrawComponents(EcsEntityConnect[] targets)
{
if (IsMultipleTargets)
{
for (int i = 0; i < targets.Length; i++)
{
if (targets[i].IsConected == true)
{
EditorGUILayout.HelpBox("Multiple component editing is not available.", MessageType.Warning);
return;
}
}
}
if (Target.Entity.TryUnpack(out int entityID, out EcsWorld world))
{
EcsGUI.Layout.DrawRuntimeComponents(entityID, world);
}
}
}
}
#endif

View File

@ -80,31 +80,3 @@ namespace DCFApixels.DragonECS
#endregion #endregion
} }
} }
#if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomEditor(typeof(EcsWorldProviderBase), true)]
[CanEditMultipleObjects]
public class EcsWorldProviderBaseEditor : Editor
{
private EcsWorldProviderBase Target => (EcsWorldProviderBase)target;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (Target.IsEmpty)
{
var style = EcsEditor.GetStyle(new Color32(255, 0, 75, 100));
GUILayout.Box("Is Empty", style, GUILayout.ExpandWidth(true));
}
else
{
var style = EcsEditor.GetStyle(new Color32(75, 255, 0, 100));
EcsWorld world = Target.GetRaw();
GUILayout.Box($"{world.GetMeta().Name} ( {world.id} )", style, GUILayout.ExpandWidth(true));
}
}
}
}
#endif

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2593ccf9a57f4f045a7e3bf6a839f3c3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,26 @@
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomEditor(typeof(AutoEntityCreator))]
[CanEditMultipleObjects]
public class AutoEntityCreatorEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("Autoset"))
{
foreach (var tr in targets)
{
AutoEntityCreator creator = (AutoEntityCreator)tr;
creator.Autoset_Editor();
EditorUtility.SetDirty(creator);
}
}
}
}
}
#endif

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7e21fcbcfdafbb64d86bf965cd16c6b0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,146 @@
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using UnityEditor;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomEditor(typeof(EcsEntityConnect))]
[CanEditMultipleObjects]
public class EcsEntityConnectEditor : Editor
{
private bool _isInit = false;
private EcsEntityConnect Target => (EcsEntityConnect)target;
private bool IsMultipleTargets => targets.Length > 1;
private void Init()
{
if (_isInit)
{
return;
}
_isInit = true;
}
public override void OnInspectorGUI()
{
Init();
EcsEntityConnect[] targets = new EcsEntityConnect[this.targets.Length];
for (int i = 0; i < targets.Length; i++)
{
targets[i] = (EcsEntityConnect)this.targets[i];
}
DrawEntityInfo(targets);
DrawTemplates();
DrawButtons();
DrawComponents(targets);
}
private void DrawEntityInfo(EcsEntityConnect[] targets)
{
//TODO Отрефакторить
float width = EditorGUIUtility.currentViewWidth;
float height = EditorGUIUtility.singleLineHeight;
Rect entityRect = GUILayoutUtility.GetRect(width, height + 3f);
var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(entityRect, 3f);
Color w = Color.gray;
w.a = 0.6f;
Color b = Color.black;
b.a = 0.55f;
EditorGUI.DrawRect(entityInfoRect, w);
var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(entityInfoRect, 0.5f);
var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f);
idRect = RectUtility.AddPadding(idRect, 2, 1, 0, 0);
genRect = RectUtility.AddPadding(genRect, 1, 1, 0, 0);
worldRect = RectUtility.AddPadding(worldRect, 1, 2, 0, 0);
EditorGUI.DrawRect(idRect, b);
EditorGUI.DrawRect(genRect, b);
EditorGUI.DrawRect(worldRect, b);
bool isConnected = Target.Entity.TryUnpack(out int id, out short gen, out short world);
GUIStyle style = new GUIStyle(EditorStyles.numberField);
style.alignment = TextAnchor.MiddleCenter;
style.font = EditorStyles.boldFont;
if (IsMultipleTargets == false && isConnected)
{
Color statusColor = EcsGUI.GreenColor;
statusColor.a = 0.6f;
EditorGUI.DrawRect(statusRect, statusColor);
EditorGUI.IntField(idRect, id, style);
EditorGUI.IntField(genRect, gen, style);
EditorGUI.IntField(worldRect, world, style);
}
else
{
Color statusColor = IsMultipleTargets ? new Color32(200, 200, 200, 255) : EcsGUI.RedColor;
statusColor.a = 0.6f;
EditorGUI.DrawRect(statusRect, statusColor);
using (new EditorGUI.DisabledScope(true))
{
GUI.Label(idRect, "Entity ID", style);
GUI.Label(genRect, "Generation", style);
GUI.Label(worldRect, "World ID", style);
}
}
}
private void DrawTemplates()
{
var iterator = serializedObject.GetIterator();
iterator.NextVisible(true);
bool enterChildren = true;
while (iterator.NextVisible(enterChildren))
{
EditorGUILayout.PropertyField(iterator, true);
enterChildren = false;
}
}
private void DrawButtons()
{
GUILayout.BeginHorizontal();
if (GUILayout.Button("Autoset"))
{
Target.SetTemplates_Editor(Target.GetComponents<MonoEntityTemplate>());
EditorUtility.SetDirty(target);
}
if (GUILayout.Button("Autoset Cascade"))
{
foreach (var item in Target.GetComponentsInChildren<EcsEntityConnect>())
{
item.SetTemplates_Editor(item.GetComponents<MonoEntityTemplate>());
EditorUtility.SetDirty(item);
}
}
GUILayout.EndHorizontal();
}
private void DrawComponents(EcsEntityConnect[] targets)
{
if (IsMultipleTargets)
{
for (int i = 0; i < targets.Length; i++)
{
if (targets[i].IsConected == true)
{
EditorGUILayout.HelpBox("Multiple component editing is not available.", MessageType.Warning);
return;
}
}
}
if (Target.Entity.TryUnpack(out int entityID, out EcsWorld world))
{
EcsGUI.Layout.DrawRuntimeComponents(entityID, world);
}
}
}
}
#endif

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 846d3d07f90835048902b412bfac73aa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,30 @@
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomEditor(typeof(EcsWorldProviderBase), true)]
[CanEditMultipleObjects]
public class EcsWorldProviderBaseEditor : Editor
{
private EcsWorldProviderBase Target => (EcsWorldProviderBase)target;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (Target.IsEmpty)
{
var style = EcsEditor.GetStyle(new Color32(255, 0, 75, 100));
GUILayout.Box("Is Empty", style, GUILayout.ExpandWidth(true));
}
else
{
var style = EcsEditor.GetStyle(new Color32(75, 255, 0, 100));
EcsWorld world = Target.GetRaw();
GUILayout.Box($"{world.GetMeta().Name} ( {world.id} )", style, GUILayout.ExpandWidth(true));
}
}
}
}
#endif

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1db1c2bb174625249a07a4cef8eff757
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,6 +1,6 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using UnityEngine;
using UnityEditor; using UnityEditor;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors namespace DCFApixels.DragonECS.Unity.Editors
{ {

View File

@ -2,6 +2,6 @@
{ {
public static class EcsUnityConsts public static class EcsUnityConsts
{ {
public const string INFO_MARK = "[i]"; public const string INFO_MARK = "[D]";
} }
} }

View File

@ -1,5 +1,4 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using Codice.Utils;
using DCFApixels.DragonECS.Unity.Internal; using DCFApixels.DragonECS.Unity.Internal;
using System; using System;
using System.Reflection; using System.Reflection;

View File

@ -1,10 +1,4 @@
using System; namespace DCFApixels.DragonECS.Unity.Editors
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DCFApixels.DragonECS.Unity.Editors
{ {
internal static class EscEditorConsts internal static class EscEditorConsts
{ {

View File

@ -1,4 +1,4 @@
 #if UNITY_EDITOR #if UNITY_EDITOR
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using UnityEngine; using UnityEngine;

8
src/Editor/Utils.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c36fbe915640753488e69c6e5d6efe92
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: daa1178cae0d21643b233d22f2c3e867 guid: ff5cb33212a8c8a4eb5111cc17759e47
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 8e275376d670bdd4c986d661838ed6b4 guid: a08af8a9e1192f44c8aedf88340cb663
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -68,8 +68,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
for (int i = 0; i < componentsProp.arraySize; i++) for (int i = 0; i < componentsProp.arraySize; i++)
{ {
if (componentsProp.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType) if (componentsProp.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType)
{
return; return;
} }
}
componentsProp.InsertArrayElementAtIndex(0); componentsProp.InsertArrayElementAtIndex(0);
@ -102,6 +104,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
DrawTop(target); DrawTop(target);
GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f));
GUILayout.Label("", GUILayout.Height(0), GUILayout.ExpandWidth(true));
for (int i = 0; i < componentsProp.arraySize; i++) for (int i = 0; i < componentsProp.arraySize; i++)
{ {
DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i); DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i);
@ -158,27 +161,23 @@ namespace DCFApixels.DragonECS.Unity.Editors
string description = template.Description; string description = template.Description;
Color panelColor = template.Color.Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); Color panelColor = template.Color.Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
EditorGUI.BeginChangeCheck(); Rect removeButtonRect = GUILayoutUtility.GetLastRect();
GUIContent label = new GUIContent(name); GUIContent label = new GUIContent(name);
bool isEmpty = componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0; bool isEmpty = componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0;
float width = EditorGUIUtility.currentViewWidth;
float height = isEmpty ? EditorGUIUtility.singleLineHeight : EditorGUI.GetPropertyHeight(componentProperty, label, true);
float padding = EditorGUIUtility.standardVerticalSpacing; float padding = EditorGUIUtility.standardVerticalSpacing;
Rect propertyFullRect = GUILayoutUtility.GetRect(width, height + padding * 3f);
propertyFullRect = RectUtility.AddPadding(propertyFullRect, padding / 2f);
Color alphaPanelColor = panelColor; Color alphaPanelColor = panelColor;
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA; alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
var (propertyRect, controlRect) = RectUtility.HorizontalSliceRight(propertyFullRect, RemoveButtonRect.width); EditorGUI.BeginChangeCheck();
var (removeButtonRect, _) = RectUtility.VerticalSliceTop(controlRect, RemoveButtonRect.height); GUILayout.BeginVertical(EcsEditor.GetStyle(alphaPanelColor));
#region Draw Component Block #region Draw Component Block
EditorGUI.DrawRect(propertyFullRect, alphaPanelColor);
propertyRect = RectUtility.AddPadding(propertyRect, padding);
bool isRemoveComponent = false; bool isRemoveComponent = false;
removeButtonRect.yMin = removeButtonRect.yMax;
removeButtonRect.yMax += RemoveButtonRect.height;
removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width;
removeButtonRect.center += Vector2.up * padding * 2f;
if (GUI.Button(removeButtonRect, "x")) if (GUI.Button(removeButtonRect, "x"))
{ {
isRemoveComponent = true; isRemoveComponent = true;
@ -186,30 +185,31 @@ namespace DCFApixels.DragonECS.Unity.Editors
if (isEmpty) if (isEmpty)
{ {
GUI.Label(propertyRect, label); GUILayout.Label(label);
} }
else else
{ {
EditorGUI.PropertyField(propertyFullRect, componentProperty, label, true); EditorGUILayout.PropertyField(componentProperty, label, true);
} }
if (isRemoveComponent) if (isRemoveComponent)
{ {
OnRemoveComponentAt(index); OnRemoveComponentAt(index);
} }
#endregion
if (!string.IsNullOrEmpty(description)) if (!string.IsNullOrEmpty(description))
{ {
Rect tooltipIconRect = TooltipIconRect; Rect tooltipIconRect = TooltipIconRect;
tooltipIconRect.center = new Vector2(propertyRect.xMax - removeButtonRect.width / 2f, propertyRect.yMin + removeButtonRect.height / 2f); tooltipIconRect.center = removeButtonRect.center;
GUIContent descriptionLabel = new GUIContent("( i )", description); tooltipIconRect.center -= Vector2.right * tooltipIconRect.width;
GUIContent descriptionLabel = new GUIContent(EcsUnityConsts.INFO_MARK, description);
GUI.Label(tooltipIconRect, descriptionLabel, EditorStyles.boldLabel); GUI.Label(tooltipIconRect, descriptionLabel, EditorStyles.boldLabel);
} }
#endregion
GUILayout.EndVertical();
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
componentProperty.serializedObject.ApplyModifiedProperties(); componentProperty.serializedObject.ApplyModifiedProperties();
componentProperty.serializedObject.SetIsDifferentCacheDirty(); EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
} }
} }
@ -225,7 +225,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
GUILayout.Label("", GUILayout.Width(removeButtonRect.width)); GUILayout.Label("", GUILayout.Width(removeButtonRect.width));
if (GUI.Button(removeButtonRect, "x", removeButtonStyle)) if (GUI.Button(removeButtonRect, "x", removeButtonStyle))
{
OnRemoveComponentAt(index); OnRemoveComponentAt(index);
}
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
@ -234,11 +236,15 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
int lastSlashIndex = input.LastIndexOfAny(new char[] { '/', '\\' }); int lastSlashIndex = input.LastIndexOfAny(new char[] { '/', '\\' });
if (lastSlashIndex == -1) if (lastSlashIndex == -1)
{
return input; return input;
}
else else
{
return input.Substring(lastSlashIndex + 1); return input.Substring(lastSlashIndex + 1);
} }
} }
}
[CustomEditor(typeof(ScriptableEntityTemplate), true)] [CustomEditor(typeof(ScriptableEntityTemplate), true)]
public class EntityTemplatePresetEditor : EntityTemplateEditorBase public class EntityTemplatePresetEditor : EntityTemplateEditorBase

View File

@ -56,7 +56,7 @@ namespace DCFApixels.DragonECS
[Serializable] [Serializable]
public abstract class ComponentTemplateBase<T> : ComponentTemplateBase, IComponentTemplate public abstract class ComponentTemplateBase<T> : ComponentTemplateBase, IComponentTemplate
{ {
private static TypeMetaDataCached _meta = EcsDebugUtility.GetCachedTypeMeta<T>(); private static TypeMeta _meta = EcsDebugUtility.GetTypeMeta<T>();
[SerializeField] [SerializeField]
protected T component; protected T component;
@ -142,7 +142,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
_types = types.ToArray(); _types = types.ToArray();
foreach (var type in _types) foreach (var type in _types)
{ {
EcsDebugUtility.GetCachedTypeMeta(type); EcsDebugUtility.GetTypeMeta(type);
} }
_dummies = new IComponentTemplate[_types.Length]; _dummies = new IComponentTemplate[_types.Length];