mirror of
https://github.com/DCFApixels/DragonECS-Unity.git
synced 2025-09-18 10:04:36 +08:00
Compare commits
35 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bdeb2f8b58 | ||
![]() |
1799ca3383 | ||
![]() |
510265cfeb | ||
![]() |
71f1328a59 | ||
![]() |
7f80f2564c | ||
![]() |
503b97c1eb | ||
![]() |
d21c65742b | ||
![]() |
cb733e8903 | ||
![]() |
64bc896457 | ||
![]() |
6d0a572c80 | ||
![]() |
ed499de283 | ||
![]() |
14163956e0 | ||
![]() |
760c789acb | ||
![]() |
09f7c6103d | ||
![]() |
236eb3d2bb | ||
![]() |
a7f269a0f2 | ||
![]() |
84401b875d | ||
![]() |
fdbdb94b0c | ||
![]() |
a8f08f2137 | ||
![]() |
c08be8e883 | ||
![]() |
173ba244b1 | ||
![]() |
8418c81e34 | ||
![]() |
67477ef90d | ||
![]() |
ba4e103337 | ||
![]() |
7c6fdcfb6f | ||
![]() |
9182e565e8 | ||
![]() |
077f6b0e72 | ||
![]() |
240e651575 | ||
![]() |
2fd798e631 | ||
![]() |
fb8afe1aee | ||
![]() |
27b352032d | ||
![]() |
26afa999a9 | ||
![]() |
ab80e92b36 | ||
![]() |
dfc1ade888 | ||
![]() |
03212094d9 |
@ -42,7 +42,7 @@
|
||||
> Readme еще не завершен, если есть не ясные моменты, вопросы можно задать тут [Обратная связь](https://github.com/DCFApixels/DragonECS/blob/main/README-RU.md#%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%B0%D1%8F-%D1%81%D0%B2%D1%8F%D0%B7%D1%8C)
|
||||
|
||||
> [!WARNING]
|
||||
> Встроенные реализации шаблоны UnityComponent<T> были перенесены [СЮДА](https://gist.github.com/DCFApixels/c250f2561f09e09ab3e6a4bd4f3013cb#file-unitycomponenttemplates-cs) Так как некоторые модули Unity отключаемы, и например отключение модуля физики приведет к тому что код реализации UnityComponent<Rigidbody> или UnityComponent<Collider> не будет компилироваться.
|
||||
> Встроенные реализации шаблонов `UnityComponent<T>` были перенесены [СЮДА](https://gist.github.com/DCFApixels/c250f2561f09e09ab3e6a4bd4f3013cb#file-unitycomponenttemplates-cs) Так как некоторые модули Unity отключаемы, и например отключение модуля физики приведет к тому что код реализации `UnityComponent<Rigidbody>` или `UnityComponent<Collider>` не будет компилироваться.
|
||||
|
||||
//https://gist.github.com/DCFApixels/c250f2561f09e09ab3e6a4bd4f3013cb#file-unitycomponenttemplates-cs
|
||||
# Оглавление
|
||||
|
@ -8,7 +8,7 @@
|
||||
"displayName": "DragonECS-Unity",
|
||||
"description": "Integration with Unity for DragonECS",
|
||||
"unity": "2021.2",
|
||||
"version": "0.5.11",
|
||||
"version": "0.5.15",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DCFApixels/DragonECS-Unity.git"
|
||||
|
@ -72,7 +72,7 @@ namespace DCFApixels.DragonECS
|
||||
#if UNITY_EDITOR
|
||||
if (_enablePipelineDebug)
|
||||
{
|
||||
pipelineBuilder.Layers.Insert(EcsConsts.POST_END_LAYER, EcsUnityConsts.DEBUG_LAYER);
|
||||
pipelineBuilder.Layers.Add(EcsUnityConsts.DEBUG_LAYER).Before(EcsConsts.POST_END_LAYER);
|
||||
pipelineBuilder.AddUnique(new PipelineMonitorSystem(), EcsUnityConsts.DEBUG_LAYER);
|
||||
}
|
||||
#endif
|
||||
|
@ -9,6 +9,7 @@ using UnityEngine;
|
||||
using DCFApixels.DragonECS.Unity.Internal;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using DCFApixels.DragonECS.Unity.Editors;
|
||||
#endif
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
@ -132,6 +133,9 @@ namespace DCFApixels.DragonECS
|
||||
_isConnectInvoked = true;
|
||||
_entity = entity;
|
||||
_world = world;
|
||||
#if UNITY_EDITOR
|
||||
world.Get<EcsGUI.EntityLinksComponent>().SetConnectLink(entity.GetIDUnchecked(), this);
|
||||
#endif
|
||||
_connectedEntities.Add(GetInstanceID(), this);
|
||||
var goConnects = world.GetPool<GameObjectConnect>();
|
||||
if (goConnects.Has(newEntityID))
|
||||
|
@ -21,9 +21,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
|
||||
private void DrawEntityInfo()
|
||||
{
|
||||
bool isConnected = Target.Entity.TryUnpackForUnityEditor(out int id, out short gen, out short worldID, out EcsWorld world);
|
||||
EcsGUI.EntityStatus status = IsMultipleTargets ? EcsGUI.EntityStatus.Undefined : isConnected ? EcsGUI.EntityStatus.Alive : EcsGUI.EntityStatus.NotAlive;
|
||||
EcsGUI.Layout.EntityBarForAlive(status, id, gen, worldID);
|
||||
//bool isConnected = Target.Entity.TryUnpackForUnityEditor(out int id, out short gen, out short worldID, out EcsWorld world);
|
||||
//EcsGUI.EntityStatus status = IsMultipleTargets ? EcsGUI.EntityStatus.Undefined : isConnected ? EcsGUI.EntityStatus.Alive : EcsGUI.EntityStatus.NotAlive;
|
||||
//EcsGUI.Layout.EntityField(status, id, gen, worldID);
|
||||
EcsGUI.Layout.EntityField(Target.Entity);
|
||||
}
|
||||
|
||||
private void DrawTemplates()
|
||||
@ -104,7 +105,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
if (world.IsNullOrDetroyed() == false)
|
||||
{
|
||||
EcsGUI.Layout.DrawRuntimeComponents(entityID, world);
|
||||
EcsGUI.Layout.DrawRuntimeComponents(entityID, world, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,199 @@
|
||||
#if UNITY_EDITOR
|
||||
using DCFApixels.DragonECS.Core.Unchecked;
|
||||
using DCFApixels.DragonECS.Unity.Internal;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(entlong))]
|
||||
internal class EntlongDrawer : ExtendedPropertyDrawer
|
||||
internal unsafe class EntlongDrawer : ExtendedPropertyDrawer
|
||||
{
|
||||
private float heightCache = 0;
|
||||
private static readonly int s_ObjectFieldHash = "s_ObjectFieldHash".GetHashCode();
|
||||
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
using (EcsGUI.Disable)
|
||||
{
|
||||
EntitySlotInfo slotInfo = new EntitySlotInfo(property.FindPropertyRelative("_full").longValue);
|
||||
var (labelRect, barRect) = position.HorizontalSliceLeft(EditorGUIUtility.labelWidth * 0.65f);
|
||||
Rect labelRect, hyperlinkButtonRect;
|
||||
(labelRect, position) = position.HorizontalSliceLeft(EditorGUIUtility.labelWidth * 0.65f);
|
||||
|
||||
EditorGUI.LabelField(labelRect, label);
|
||||
bool isAlive = EcsWorld.GetWorld(slotInfo.world).IsAlive(slotInfo.id, slotInfo.gen);
|
||||
EcsGUI.EntityBar(barRect, false, isAlive ? EcsGUI.EntityStatus.Alive : EcsGUI.EntityStatus.NotAlive, slotInfo.id, slotInfo.gen, slotInfo.world);
|
||||
var eventType = Event.current.type;
|
||||
Rect dropRect = position;
|
||||
dropRect.yMax = position.yMin + EditorGUIUtility.singleLineHeight;
|
||||
int controlID = GUIUtility.GetControlID(s_ObjectFieldHash, FocusType.Keyboard, position);
|
||||
|
||||
bool containsMouse = dropRect.Contains(Event.current.mousePosition);
|
||||
|
||||
if (containsMouse && eventType == EventType.Repaint && DragAndDrop.activeControlID == controlID)
|
||||
{
|
||||
EditorStyles.selectionRect.Draw(dropRect.AddPadding(-1), GUIContent.none, controlID, false, false);
|
||||
}
|
||||
|
||||
|
||||
(position, hyperlinkButtonRect) = position.HorizontalSliceRight(18f);
|
||||
|
||||
bool drawFoldout = property.hasMultipleDifferentValues == false;
|
||||
|
||||
bool isExpanded = false;
|
||||
if (drawFoldout)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
isExpanded = EditorGUI.Foldout(labelRect, property.isExpanded, label);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
property.isExpanded = isExpanded;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.LabelField(labelRect, label);
|
||||
}
|
||||
|
||||
SerializedProperty fulleProperty = property.FindPropertyRelative("_full");
|
||||
EntitySlotInfo entity = new EntitySlotInfo(fulleProperty.longValue);
|
||||
EcsWorld.TryGetWorld(entity.worldID, out EcsWorld world);
|
||||
|
||||
if (drawFoldout && isExpanded)
|
||||
{
|
||||
using (EcsGUI.UpIndentLevel())
|
||||
{
|
||||
if (world != null && world.IsAlive(entity.id, entity.gen))
|
||||
{
|
||||
EcsGUI.Layout.DrawRuntimeComponents(entity.id, world, false, false);
|
||||
if (Event.current.type == EventType.Layout)
|
||||
{
|
||||
heightCache = GUILayoutUtility.GetLastRect().height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EcsGUI.EntityField(position, property);
|
||||
using (EcsGUI.SetEnable(world != null))
|
||||
{
|
||||
EcsGUI.EntityHyperlinkButton(hyperlinkButtonRect, world, entity.id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (!containsMouse || !GUI.enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (DragAndDrop.visualMode == DragAndDropVisualMode.None)
|
||||
{
|
||||
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
|
||||
}
|
||||
|
||||
if (eventType == EventType.DragPerform || eventType == EventType.DragUpdated)
|
||||
{
|
||||
if (eventType == EventType.DragPerform)
|
||||
{
|
||||
entlong ent = default;
|
||||
bool isValide = false;
|
||||
var dragged = DragAndDrop.objectReferences[0];
|
||||
if (dragged is GameObject go)
|
||||
{
|
||||
if (go.TryGetComponent(out EcsEntityConnect connect))
|
||||
{
|
||||
ent = connect.Entity;
|
||||
isValide = true;
|
||||
}
|
||||
else if (go.TryGetComponent(out EntityMonitor monitor))
|
||||
{
|
||||
ent = monitor.Entity;
|
||||
isValide = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var beh in go.GetComponents<MonoBehaviour>())
|
||||
{
|
||||
if (TryFindEntlong(beh, out ent))
|
||||
{
|
||||
isValide = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dragged is EcsEntityConnect connect)
|
||||
{
|
||||
ent = connect.Entity;
|
||||
isValide = true;
|
||||
}
|
||||
else if (dragged is EntityMonitor monitor)
|
||||
{
|
||||
ent = monitor.Entity;
|
||||
isValide = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TryFindEntlong(dragged, out ent))
|
||||
{
|
||||
isValide = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (isValide)
|
||||
{
|
||||
long entityLong = *(long*)&ent;
|
||||
fulleProperty.longValue = entityLong;
|
||||
}
|
||||
|
||||
|
||||
EcsGUI.Changed = true;
|
||||
DragAndDrop.AcceptDrag();
|
||||
DragAndDrop.activeControlID = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DragAndDrop.activeControlID = controlID;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private bool TryFindEntlong(Object uniObj, out entlong ent)
|
||||
{
|
||||
var fields = uniObj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
foreach (var field in fields)
|
||||
{
|
||||
if (field.FieldType == typeof(entlong))
|
||||
{
|
||||
ent = (entlong)field.GetValue(uniObj);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var iterator = new SerializedObject(uniObj).GetIterator();
|
||||
iterator.NextVisible(true);
|
||||
while (iterator.Next(true))
|
||||
{
|
||||
if (iterator.propertyType == SerializedPropertyType.Integer &&
|
||||
iterator.propertyPath.Contains(nameof(entlong)))
|
||||
{
|
||||
var l = iterator.longValue;
|
||||
ent = *(entlong*)&l;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ent = entlong.NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
const float UNITY_HEIGHT_CONSTANT = 18f;
|
||||
if (property.hasMultipleDifferentValues)
|
||||
{
|
||||
return UNITY_HEIGHT_CONSTANT;
|
||||
}
|
||||
return Mathf.Max(heightCache, UNITY_HEIGHT_CONSTANT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
world.DelEntity(id);
|
||||
}
|
||||
}
|
||||
EcsGUI.Layout.EntityBarForAlive(isAlive ? EcsGUI.EntityStatus.Alive : EcsGUI.EntityStatus.NotAlive, id, gen, worldID);
|
||||
//EcsGUI.Layout.EntityBarForAlive(isAlive ? EcsGUI.EntityStatus.Alive : EcsGUI.EntityStatus.NotAlive, id, gen, worldID);
|
||||
EcsGUI.Layout.EntityField(entity);
|
||||
|
||||
var drawers = UnityEditorUtility._entityEditorBlockDrawers;
|
||||
if (drawers.Length > 0)
|
||||
|
@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using DCFApixels.DragonECS.Unity.Editors;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Internal
|
||||
{
|
||||
@ -17,6 +18,10 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
public void Set(entlong entity)
|
||||
{
|
||||
_entity = entity;
|
||||
#if UNITY_EDITOR
|
||||
var world = entity.GetWorldUnchecked();
|
||||
world.Get<EcsGUI.EntityLinksComponent>().SetMonitorLink(entity.GetIDUnchecked(), this);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ namespace DCFApixels.DragonECS
|
||||
void IEcsModule.Import(EcsPipeline.Builder b)
|
||||
{
|
||||
UnityDebugService.Activate();
|
||||
b.Layers.Insert(EcsConsts.POST_END_LAYER, EcsUnityConsts.DEBUG_LAYER);
|
||||
b.Layers.Add(EcsUnityConsts.DEBUG_LAYER).Before(EcsConsts.POST_END_LAYER);
|
||||
b.AddUnique(new PipelineMonitorSystem(), EcsUnityConsts.DEBUG_LAYER);
|
||||
foreach (var world in _worlds)
|
||||
{
|
||||
|
@ -77,8 +77,8 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
{
|
||||
int indexof = INDEXED_LINK_PREV.Length - 1;// откатываю символ ∆
|
||||
int stringIndexLength = e.LogString.IndexOf(INDEXED_LINK_POST) - indexof;
|
||||
|
||||
if(stringIndexLength == path.Length)
|
||||
|
||||
if (stringIndexLength == path.Length)
|
||||
{
|
||||
bool isSkip = false;
|
||||
for (int j = 1; j < stringIndexLength; j++)
|
||||
@ -87,11 +87,11 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
var logchar = e.LogString[indexof + j];
|
||||
if (pathchar != logchar) { isSkip = true; break; }
|
||||
}
|
||||
|
||||
|
||||
if (isSkip) { continue; }
|
||||
|
||||
|
||||
OpenIDE(e);
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -149,7 +149,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
if (_consoleLogCounter > currentCount)
|
||||
{
|
||||
var l = _consoleLogCounter - currentCount;
|
||||
if(l < inst._logEntries.Count)
|
||||
if (l < inst._logEntries.Count)
|
||||
{
|
||||
inst._logEntries.FastRemoveSpan(0, l);
|
||||
}
|
||||
|
41
src/Internal/Editor/DragonGUIContent.cs
Normal file
41
src/Internal/Editor/DragonGUIContent.cs
Normal file
@ -0,0 +1,41 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
internal struct DragonGUIContent
|
||||
{
|
||||
public static readonly DragonGUIContent Empty = new DragonGUIContent();
|
||||
public GUIContent value;
|
||||
public DragonGUIContent(GUIContent value) { this.value = value; }
|
||||
public DragonGUIContent(Texture texture)
|
||||
{
|
||||
value = UnityEditorUtility.GetLabelOrNull(texture);
|
||||
}
|
||||
public DragonGUIContent(Texture texture, string tooltip)
|
||||
{
|
||||
value = UnityEditorUtility.GetLabelOrNull(texture);
|
||||
if (value != null)
|
||||
{
|
||||
value.tooltip = tooltip;
|
||||
}
|
||||
}
|
||||
public DragonGUIContent(string text)
|
||||
{
|
||||
value = UnityEditorUtility.GetLabelOrNull(text);
|
||||
}
|
||||
public DragonGUIContent(string text, string tooltip)
|
||||
{
|
||||
value = UnityEditorUtility.GetLabelOrNull(text);
|
||||
if (value != null)
|
||||
{
|
||||
value.tooltip = tooltip;
|
||||
}
|
||||
}
|
||||
public static implicit operator DragonGUIContent(GUIContent a) { return new DragonGUIContent(a); }
|
||||
public static implicit operator DragonGUIContent(Texture a) { return new DragonGUIContent(a); }
|
||||
public static implicit operator DragonGUIContent(string a) { return new DragonGUIContent(a); }
|
||||
public static implicit operator GUIContent(DragonGUIContent a) { return a.value; }
|
||||
}
|
||||
}
|
||||
#endif
|
2
src/Internal/Editor/DragonGUIContent.cs.meta
Normal file
2
src/Internal/Editor/DragonGUIContent.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83b46b5e659b87942857f69c1b056dcf
|
@ -1,13 +1,11 @@
|
||||
#if UNITY_EDITOR
|
||||
using DCFApixels.DragonECS.Core.Unchecked;
|
||||
using DCFApixels.DragonECS.Unity.Editors.X;
|
||||
using DCFApixels.DragonECS.Unity.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Color = UnityEngine.Color;
|
||||
using UnityComponent = UnityEngine.Component;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
@ -111,105 +109,51 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
}
|
||||
public static void DrawWorldComponents(EcsWorld world)
|
||||
{
|
||||
bool isNull = world == null || world.IsDestroyed || world.ID == 0;
|
||||
if (isNull) { return; }
|
||||
using (BeginVertical(UnityEditorUtility.GetTransperentBlackBackgrounStyle()))
|
||||
{
|
||||
IsShowRuntimeComponents = EditorGUILayout.BeginFoldoutHeaderGroup(IsShowRuntimeComponents, "RUNTIME COMPONENTS", EditorStyles.foldout);
|
||||
EditorGUILayout.EndFoldoutHeaderGroup();
|
||||
if (IsShowRuntimeComponents == false) { return; }
|
||||
|
||||
var worldID = world.ID;
|
||||
var cmps = world.GetWorldComponents();
|
||||
int index = -1;
|
||||
int total = 9;
|
||||
foreach (var cmp in cmps)
|
||||
{
|
||||
index++;
|
||||
var meta = cmp.ComponentType.ToMeta();
|
||||
if (meta.IsHidden == false || IsShowHidden)
|
||||
{
|
||||
Type componentType = cmp.ComponentType;
|
||||
|
||||
object data = cmp.GetRaw(worldID);
|
||||
|
||||
ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType);
|
||||
|
||||
float padding = EditorGUIUtility.standardVerticalSpacing;
|
||||
Rect optionButton = GUILayoutUtility.GetLastRect();
|
||||
optionButton.yMin = optionButton.yMax;
|
||||
optionButton.yMax += HeadIconsRect.height;
|
||||
optionButton.xMin = optionButton.xMax - 64;
|
||||
optionButton.center += Vector2.up * padding * 2f;
|
||||
//Canceling isExpanded
|
||||
if (ClickTest(optionButton))
|
||||
{
|
||||
ref bool isExpanded = ref expandMatrix.Down();
|
||||
isExpanded = !isExpanded;
|
||||
}
|
||||
|
||||
Color panelColor = SelectPanelColor(meta, index, total);
|
||||
using (BeginVertical(panelColor.SetAlpha(EscEditorConsts.COMPONENT_DRAWER_ALPHA)))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
////Close button
|
||||
//optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
|
||||
//if (CloseButton(optionButton))
|
||||
//{
|
||||
// cmp.Del(worldID);
|
||||
// return;
|
||||
//}
|
||||
|
||||
//Edit script button
|
||||
if (ScriptsCache.TryGetScriptAsset(meta, out MonoScript script))
|
||||
{
|
||||
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
|
||||
EcsGUI.ScriptAssetButton(optionButton, script);
|
||||
}
|
||||
//Description icon
|
||||
if (string.IsNullOrEmpty(meta.Description.Text) == false)
|
||||
{
|
||||
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
|
||||
DescriptionIcon(optionButton, meta.Description.Text);
|
||||
}
|
||||
|
||||
RuntimeComponentReflectionCache.FieldInfoData componentInfoData = new RuntimeComponentReflectionCache.FieldInfoData(null, componentType, meta.Name);
|
||||
if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData))
|
||||
{
|
||||
cmp.SetRaw(worldID, resultData);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RuntimeComponentsDrawer.DrawWorldComponents(world);
|
||||
}
|
||||
|
||||
#region entity bar
|
||||
public static void EntityBarForAlive(EntityStatus status, int id, short gen, short world)
|
||||
public static void EntityField(entlong entity)
|
||||
{
|
||||
float width = EditorGUIUtility.currentViewWidth;
|
||||
float height = EntityBarHeight;
|
||||
EcsGUI.EntityBarForAlive(GUILayoutUtility.GetRect(width, height), status, id, gen, world);
|
||||
EntityField(default(GUIContent), entity);
|
||||
}
|
||||
public static void EntityBar(EntityStatus status, bool isPlaceholder, int id, short gen, short world)
|
||||
public static void EntityField(string label, entlong entity)
|
||||
{
|
||||
float width = EditorGUIUtility.currentViewWidth;
|
||||
float height = EntityBarHeight;
|
||||
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height), isPlaceholder, status, id, gen, world);
|
||||
EntityField(UnityEditorUtility.GetLabel(label), entity);
|
||||
}
|
||||
public static void EntityBar(int id, short gen, short world)
|
||||
public static unsafe void EntityField(GUIContent label, entlong entity)
|
||||
{
|
||||
float width = EditorGUIUtility.currentViewWidth;
|
||||
float height = EntityBarHeight;
|
||||
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height), id, gen, world);
|
||||
EcsGUI.EntityField(GUILayoutUtility.GetRect(width, height), label, entity);
|
||||
}
|
||||
public static void EntityBar()
|
||||
public static void EntityField(EntitySlotInfo entity)
|
||||
{
|
||||
EntityField(default(GUIContent), entity);
|
||||
}
|
||||
public static void EntityField(string label, EntitySlotInfo entity)
|
||||
{
|
||||
EntityField(UnityEditorUtility.GetLabel(label), entity);
|
||||
}
|
||||
public static void EntityField(GUIContent label, EntitySlotInfo entity)
|
||||
{
|
||||
float width = EditorGUIUtility.currentViewWidth;
|
||||
float height = EntityBarHeight;
|
||||
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height));
|
||||
EcsGUI.EntityField(GUILayoutUtility.GetRect(width, height), label, entity);
|
||||
}
|
||||
public static void EntityField(SerializedProperty property)
|
||||
{
|
||||
EntityField(property, default(GUIContent));
|
||||
}
|
||||
public static void EntityField(SerializedProperty property, string label)
|
||||
{
|
||||
EntityField(property, UnityEditorUtility.GetLabel(label));
|
||||
}
|
||||
public static void EntityField(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
float width = EditorGUIUtility.currentViewWidth;
|
||||
float height = EntityBarHeight;
|
||||
EcsGUI.EntityField(GUILayoutUtility.GetRect(width, height), property, label);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -225,304 +169,18 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
return EcsGUI.AddClearSystemButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 24f), out dropDownRect);
|
||||
}
|
||||
public static void DrawRuntimeComponents(entlong entity, bool isWithFoldout = true)
|
||||
public static void DrawRuntimeComponents(entlong entity, bool isWithFoldout, bool isRoot = true)
|
||||
{
|
||||
if (entity.TryUnpackForUnityEditor(out int entityID, out _, out _, out EcsWorld world))
|
||||
{
|
||||
DrawRuntimeComponents(entityID, world, isWithFoldout);
|
||||
DrawRuntimeComponents(entityID, world, isWithFoldout, isRoot);
|
||||
}
|
||||
}
|
||||
|
||||
[ThreadStatic]
|
||||
private static List<IEcsPool> _componentPoolsBuffer;
|
||||
public static void DrawRuntimeComponents(int entityID, EcsWorld world, bool isWithFoldout = true)
|
||||
public static void DrawRuntimeComponents(int entityID, EcsWorld world, bool isWithFoldout, bool isRoot)
|
||||
{
|
||||
using (BeginVertical(UnityEditorUtility.GetTransperentBlackBackgrounStyle()))
|
||||
{
|
||||
if (isWithFoldout)
|
||||
{
|
||||
IsShowRuntimeComponents = EditorGUILayout.BeginFoldoutHeaderGroup(IsShowRuntimeComponents, "RUNTIME COMPONENTS", EditorStyles.foldout);
|
||||
EditorGUILayout.EndFoldoutHeaderGroup();
|
||||
}
|
||||
if (isWithFoldout == false || IsShowRuntimeComponents)
|
||||
{
|
||||
if (AddComponentButtons(out Rect dropDownRect))
|
||||
{
|
||||
RuntimeComponentsUtility.GetAddComponentGenericMenu(world).Open(dropDownRect, entityID);
|
||||
}
|
||||
|
||||
using (SetBackgroundColor(GUI.color.SetAlpha(0.16f)))
|
||||
{
|
||||
GUILayout.Box("", UnityEditorUtility.GetWhiteStyle(), GUILayout.ExpandWidth(true));
|
||||
}
|
||||
IsShowHidden = EditorGUI.Toggle(GUILayoutUtility.GetLastRect(), "Show Hidden", IsShowHidden);
|
||||
|
||||
if (_componentPoolsBuffer == null)
|
||||
{
|
||||
_componentPoolsBuffer = new List<IEcsPool>(64);
|
||||
}
|
||||
world.GetComponentPoolsFor(entityID, _componentPoolsBuffer);
|
||||
int i = 0;
|
||||
//int iMax = _componentPoolsBuffer.Count;
|
||||
foreach (var componentPool in _componentPoolsBuffer)
|
||||
{
|
||||
DrawRuntimeComponent(entityID, componentPool, 9, i++);
|
||||
}
|
||||
}
|
||||
}
|
||||
RuntimeComponentsDrawer.DrawRuntimeComponents(entityID, world, isWithFoldout, isRoot);
|
||||
}
|
||||
private static void DrawRuntimeComponent(int entityID, IEcsPool pool, int total, int index)
|
||||
{
|
||||
var meta = pool.ComponentType.ToMeta();
|
||||
if (meta.IsHidden == false || IsShowHidden)
|
||||
{
|
||||
Type componentType = pool.ComponentType;
|
||||
|
||||
object data = pool.GetRaw(entityID);
|
||||
|
||||
ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType);
|
||||
|
||||
float padding = EditorGUIUtility.standardVerticalSpacing;
|
||||
Rect optionButton = GUILayoutUtility.GetLastRect();
|
||||
optionButton.yMin = optionButton.yMax;
|
||||
optionButton.yMax += HeadIconsRect.height;
|
||||
optionButton.xMin = optionButton.xMax - 64;
|
||||
optionButton.center += Vector2.up * padding * 2f;
|
||||
//Canceling isExpanded
|
||||
if (ClickTest(optionButton))
|
||||
{
|
||||
ref bool isExpanded = ref expandMatrix.Down();
|
||||
isExpanded = !isExpanded;
|
||||
}
|
||||
|
||||
Color panelColor = SelectPanelColor(meta, index, total);
|
||||
|
||||
using (BeginVertical(panelColor.SetAlpha(EscEditorConsts.COMPONENT_DRAWER_ALPHA)))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
//Close button
|
||||
optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
|
||||
if (CloseButton(optionButton))
|
||||
{
|
||||
pool.Del(entityID);
|
||||
return;
|
||||
}
|
||||
//Edit script button
|
||||
if (ScriptsCache.TryGetScriptAsset(meta, out MonoScript script))
|
||||
{
|
||||
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
|
||||
EcsGUI.ScriptAssetButton(optionButton, script);
|
||||
}
|
||||
//Description icon
|
||||
if (string.IsNullOrEmpty(meta.Description.Text) == false)
|
||||
{
|
||||
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
|
||||
DescriptionIcon(optionButton, meta.Description.Text);
|
||||
}
|
||||
|
||||
RuntimeComponentReflectionCache.FieldInfoData componentInfoData = new RuntimeComponentReflectionCache.FieldInfoData(null, componentType, meta.Name);
|
||||
|
||||
if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData))
|
||||
{
|
||||
pool.SetRaw(entityID, resultData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Default DrawRuntimeData
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||
private static void ResetRuntimeComponentReflectionCache()
|
||||
{
|
||||
foreach (var item in _runtimeComponentReflectionCaches)
|
||||
{
|
||||
item.Value.Dispose();
|
||||
}
|
||||
_runtimeComponentReflectionCaches.Clear();
|
||||
}
|
||||
internal class RuntimeComponentReflectionCache : IDisposable
|
||||
{
|
||||
public readonly Type Type;
|
||||
|
||||
public readonly bool IsUnityObjectType;
|
||||
public readonly bool IsUnitySerializable;
|
||||
public readonly bool IsUnmanaged;
|
||||
|
||||
public readonly FieldInfoData[] Fields;
|
||||
|
||||
public readonly RefEditorWrapper Wrapper;
|
||||
|
||||
public RuntimeComponentReflectionCache(Type type)
|
||||
{
|
||||
Type = type;
|
||||
|
||||
IsUnmanaged = UnsafeUtility.IsUnmanaged(type);
|
||||
IsUnityObjectType = typeof(UnityObject).IsAssignableFrom(type);
|
||||
IsUnitySerializable = IsUnityObjectType || (!type.IsGenericType && type.IsSerializable);
|
||||
|
||||
Wrapper = RefEditorWrapper.Take();
|
||||
|
||||
if (type == typeof(void)) { return; }
|
||||
|
||||
if (IsUnitySerializable == false)
|
||||
{
|
||||
var fs = type.GetFields(fieldFlags);
|
||||
Fields = new FieldInfoData[fs.Length];
|
||||
for (int i = 0; i < fs.Length; i++)
|
||||
{
|
||||
var f = fs[i];
|
||||
Fields[i] = new FieldInfoData(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
if(Wrapper != null)
|
||||
{
|
||||
UnityObject.DestroyImmediate(Wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct FieldInfoData
|
||||
{
|
||||
public readonly FieldInfo FieldInfo;
|
||||
public readonly Type FieldType;
|
||||
public readonly string UnityFormatName;
|
||||
public readonly bool IsUnityObjectField;
|
||||
public FieldInfoData(FieldInfo fieldInfo)
|
||||
{
|
||||
FieldInfo = fieldInfo;
|
||||
FieldType = fieldInfo.FieldType;
|
||||
IsUnityObjectField = typeof(UnityObject).IsAssignableFrom(fieldInfo.FieldType);
|
||||
UnityFormatName = UnityEditorUtility.TransformFieldName(fieldInfo.Name);
|
||||
}
|
||||
public FieldInfoData(FieldInfo fieldInfo, Type fieldType, string unityFormatName)
|
||||
{
|
||||
FieldInfo = fieldInfo;
|
||||
FieldType = fieldType;
|
||||
UnityFormatName = unityFormatName;
|
||||
IsUnityObjectField = typeof(UnityObject).IsAssignableFrom(fieldType);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static Dictionary<Type, RuntimeComponentReflectionCache> _runtimeComponentReflectionCaches = new Dictionary<Type, RuntimeComponentReflectionCache>();
|
||||
private static RuntimeComponentReflectionCache GetRuntimeComponentReflectionCache(Type type)
|
||||
{
|
||||
if (_runtimeComponentReflectionCaches.TryGetValue(type, out RuntimeComponentReflectionCache result) == false)
|
||||
{
|
||||
result = new RuntimeComponentReflectionCache(type);
|
||||
_runtimeComponentReflectionCaches.Add(type, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private static bool DrawRuntimeData(ref RuntimeComponentReflectionCache.FieldInfoData fieldInfoData, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData)
|
||||
{
|
||||
outData = data;
|
||||
Type type = data == null ? typeof(void) : data.GetType();
|
||||
|
||||
RuntimeComponentReflectionCache cache = GetRuntimeComponentReflectionCache(type);
|
||||
|
||||
bool isUnityObjectField = fieldInfoData.IsUnityObjectField;
|
||||
if (isUnityObjectField == false && data == null)
|
||||
{
|
||||
EditorGUILayout.TextField(label, "Null");
|
||||
return false;
|
||||
}
|
||||
bool isUnityObjectType = cache.IsUnityObjectType;
|
||||
|
||||
ref bool isExpanded = ref expandMatrix.Down();
|
||||
bool changed = false;
|
||||
|
||||
|
||||
if (cache.IsUnitySerializable == false)
|
||||
{
|
||||
isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(isExpanded, label, EditorStyles.foldout);
|
||||
EditorGUILayout.EndFoldoutHeaderGroup();
|
||||
|
||||
if (isExpanded)
|
||||
{
|
||||
using (UpIndentLevel())
|
||||
{
|
||||
for (int j = 0, jMax = cache.Fields.Length; j < jMax; j++)
|
||||
{
|
||||
var field = cache.Fields[j];
|
||||
if (DrawRuntimeData(ref field, UnityEditorUtility.GetLabel(field.UnityFormatName), expandMatrix, field.FieldInfo.GetValue(data), out object fieldData))
|
||||
{
|
||||
field.FieldInfo.SetValue(data, fieldData);
|
||||
outData = data;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Type fieldType = fieldInfoData.FieldType;
|
||||
if (isUnityObjectType || isUnityObjectField)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var uobj = UnsafeUtility.As<object, UnityObject>(ref data);
|
||||
|
||||
bool isComponent = typeof(UnityComponent).IsAssignableFrom(fieldType);
|
||||
if (isComponent)
|
||||
{
|
||||
uobj = EditorGUILayout.ObjectField(label, uobj, typeof(UnityObject), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
uobj = EditorGUILayout.ObjectField(label, uobj, fieldType, true);
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
if (isComponent && uobj is GameObject go)
|
||||
{
|
||||
uobj = go.GetComponent(fieldType);
|
||||
}
|
||||
|
||||
outData = uobj;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
RefEditorWrapper wrapper = cache.Wrapper;
|
||||
|
||||
wrapper.data = data;
|
||||
wrapper.SO.Update();
|
||||
|
||||
wrapper.IsExpanded = isExpanded;
|
||||
try
|
||||
{
|
||||
EditorGUILayout.PropertyField(wrapper.Property, label, true);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
if (Event.current.type != EventType.Repaint)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
isExpanded = wrapper.IsExpanded;
|
||||
wrapper.SO.ApplyModifiedProperties();
|
||||
outData = wrapper.Data;
|
||||
changed = true;
|
||||
}
|
||||
//wrapper.Release();
|
||||
}
|
||||
}
|
||||
|
||||
expandMatrix.Up();
|
||||
return changed;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
#if UNITY_EDITOR
|
||||
using DCFApixels.DragonECS.Core;
|
||||
using DCFApixels.DragonECS.Core.Unchecked;
|
||||
using DCFApixels.DragonECS.Unity.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -141,10 +143,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
private readonly int _value;
|
||||
public IndentLevelScope(int value)
|
||||
{
|
||||
_value = EditorGUI.indentLevel;
|
||||
EditorGUI.indentLevel = value;
|
||||
_value = IndentLevel;
|
||||
IndentLevel = value;
|
||||
}
|
||||
public void Dispose() { EditorGUI.indentLevel = _value; }
|
||||
public void Dispose() { IndentLevel = _value; }
|
||||
}
|
||||
public struct AlignmentScope : IDisposable
|
||||
{
|
||||
@ -259,7 +261,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
public static AlignmentScope SetAlignment(TextAnchor value) => new AlignmentScope(GUI.skin.label, value);
|
||||
public static AlignmentScope SetAlignment(GUIStyle target) => new AlignmentScope(target);
|
||||
public static IndentLevelScope SetIndentLevel(int level) => new IndentLevelScope(level);
|
||||
public static IndentLevelScope UpIndentLevel() => new IndentLevelScope(EditorGUI.indentLevel + 1);
|
||||
public static IndentLevelScope UpIndentLevel() => new IndentLevelScope(IndentLevel + 1);
|
||||
public static ContentColorScope SetContentColor(Color value) => new ContentColorScope(value);
|
||||
public static ContentColorScope SetContentColor(Color value, float a) => new ContentColorScope(value.r, value.g, value.b, a);
|
||||
public static ContentColorScope SetContentColor(float r, float g, float b, float a = 1f) => new ContentColorScope(r, g, b, a);
|
||||
@ -276,20 +278,36 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
public static LabelWidthScope SetLabelWidth(float value) => new LabelWidthScope(value);
|
||||
#endregion
|
||||
|
||||
private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
//private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
|
||||
internal readonly static Color GrayColor = new Color32(100, 100, 100, 255);
|
||||
internal readonly static Color GreenColor = new Color32(75, 255, 0, 255);
|
||||
internal readonly static Color RedColor = new Color32(255, 0, 75, 255);
|
||||
|
||||
private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
|
||||
|
||||
public static float EntityBarHeight => EditorGUIUtility.singleLineHeight + 3f;
|
||||
|
||||
private static float indent => (float)EditorGUI.indentLevel * 15f;
|
||||
private static float indentLevel => EditorGUI.indentLevel;
|
||||
internal static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
|
||||
|
||||
#region Properties
|
||||
public static float EntityBarHeight
|
||||
{
|
||||
get => EditorGUIUtility.singleLineHeight + 3f;
|
||||
}
|
||||
public static float Indent
|
||||
{
|
||||
get => EditorGUI.indentLevel * 15f;
|
||||
}
|
||||
public static int IndentLevel
|
||||
{
|
||||
get => EditorGUI.indentLevel;
|
||||
set => EditorGUI.indentLevel = value;
|
||||
}
|
||||
public static float OneLineHeight
|
||||
{
|
||||
get => EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
public static float Spacing
|
||||
{
|
||||
get => EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
private static ComponentColorMode AutoColorMode
|
||||
{
|
||||
get { return UserSettingsPrefs.instance.ComponentColorMode; }
|
||||
@ -310,14 +328,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
// get { return UserSettingsPrefs.instance.IsFastModeRuntimeComponents; }
|
||||
// set { UserSettingsPrefs.instance.IsFastModeRuntimeComponents = value; }
|
||||
//}
|
||||
private static float OneLineHeight
|
||||
{
|
||||
get => EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
private static float Spacing
|
||||
{
|
||||
get => EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region enums
|
||||
@ -327,12 +337,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
Add = 1,
|
||||
Clear = 2,
|
||||
}
|
||||
[Flags]
|
||||
public enum EntityStatus : byte
|
||||
{
|
||||
NotAlive = 0,
|
||||
Alive = 1 << 0,
|
||||
Undefined = 1 << 1,
|
||||
Alive = 1,
|
||||
Undefined = 2,
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -366,7 +375,37 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
#endregion
|
||||
|
||||
#region small elems
|
||||
public static void DrawIcon(Rect position, Texture icon, float iconPadding, string description)
|
||||
public static void DrawTextureSoftColor(Rect position, Texture texture)
|
||||
{
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
Graphics.DrawTexture(position, texture, new Rect(0f, 0f, 1f, 1f), 0, 0, 0, 0, GUI.color * 0.5f, null);
|
||||
}
|
||||
}
|
||||
public static void DrawTexture(Rect position, Texture texture)
|
||||
{
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
Graphics.DrawTexture(position, texture, new Rect(0f, 0f, 1f, 1f), 0, 0, 0, 0, GUI.color, null);
|
||||
}
|
||||
}
|
||||
public static void DrawRectSoftColor(Rect position, Color color)
|
||||
{
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
Texture texture = UnityEditorUtility.GetWhiteTexture();
|
||||
Graphics.DrawTexture(position, texture, new Rect(0f, 0f, 1f, 1f), 0, 0, 0, 0, GUI.color * color * 0.5f, null);
|
||||
}
|
||||
}
|
||||
public static void DrawRect(Rect position, Color color)
|
||||
{
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
Texture texture = UnityEditorUtility.GetWhiteTexture();
|
||||
Graphics.DrawTexture(position, texture, new Rect(0f, 0f, 1f, 1f), 0, 0, 0, 0, GUI.color * color, null);
|
||||
}
|
||||
}
|
||||
public static void DrawIcon(Rect position, Texture icon, float iconPadding, string tooltip)
|
||||
{
|
||||
if (position.width != position.height)
|
||||
{
|
||||
@ -378,8 +417,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
}
|
||||
using (SetColor(GUI.enabled ? GUI.color : GUI.color * new Color(1f, 1f, 1f, 0.4f)))
|
||||
{
|
||||
GUI.Label(position, UnityEditorUtility.GetLabel(string.Empty, description));
|
||||
GUI.DrawTexture(RectUtility.AddPadding(position, iconPadding), icon);
|
||||
GUI.Label(position, UnityEditorUtility.GetLabel(string.Empty, tooltip));
|
||||
DrawTextureSoftColor(RectUtility.AddPadding(position, iconPadding), icon);
|
||||
}
|
||||
}
|
||||
public static (bool, bool) IconButtonGeneric(Rect position)
|
||||
@ -413,7 +452,25 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
}
|
||||
}
|
||||
|
||||
public static void EntityHyperlinkButton(Rect position, EcsWorld world, int entityID)
|
||||
{
|
||||
var current = Event.current;
|
||||
var hover = IconHoverScan(position, current);
|
||||
|
||||
var click = IconButton(position, Icons.Instance.HyperlinkIcon, 2f, string.Empty);
|
||||
if (GUI.enabled)
|
||||
{
|
||||
if (click)
|
||||
{
|
||||
var obj = world.Get<EntityLinksComponent>().GetLink(entityID);
|
||||
if (obj != null)
|
||||
{
|
||||
EditorGUIUtility.PingObject(obj);
|
||||
Selection.activeObject = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void ScriptAssetButton(Rect position, MonoScript script)
|
||||
{
|
||||
var current = Event.current;
|
||||
@ -489,20 +546,99 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
#endregion
|
||||
|
||||
#region entity bar
|
||||
public static void EntityBarForAlive(Rect position, EntityStatus status, int id, short gen, short world)
|
||||
internal readonly struct EntityLinksComponent : IEcsWorldComponent<EntityLinksComponent>
|
||||
{
|
||||
EntityBar(position, status != EntityStatus.Alive, status, id, gen, world);
|
||||
private readonly Storage _storage;
|
||||
private EntityLinksComponent(Storage storage) { _storage = storage; }
|
||||
public void SetConnectLink(int entityID, EcsEntityConnect link) { _storage.links[entityID].connect = link; }
|
||||
public void SetMonitorLink(int entityID, EntityMonitor link) { _storage.links[entityID].monitor = link; }
|
||||
public EcsEntityConnect GetConnectLink(int entityID) { return _storage.links[entityID].connect; }
|
||||
public EntityMonitor GetMonitorLink(int entityID) { return _storage.links[entityID].monitor; }
|
||||
public UnityEngine.Object GetLink(int entityID)
|
||||
{
|
||||
ref var links = ref _storage.links[entityID];
|
||||
if (links.connect != null)
|
||||
{
|
||||
return links.connect;
|
||||
}
|
||||
return links.monitor;
|
||||
}
|
||||
void IEcsWorldComponent<EntityLinksComponent>.Init(ref EntityLinksComponent component, EcsWorld world)
|
||||
{
|
||||
component = new EntityLinksComponent(new Storage(world));
|
||||
}
|
||||
void IEcsWorldComponent<EntityLinksComponent>.OnDestroy(ref EntityLinksComponent component, EcsWorld world)
|
||||
{
|
||||
component = default;
|
||||
}
|
||||
private class Storage : IEcsWorldEventListener
|
||||
{
|
||||
private readonly EcsWorld _world;
|
||||
public (EcsEntityConnect connect, EntityMonitor monitor)[] links;
|
||||
public Storage(EcsWorld world)
|
||||
{
|
||||
_world = world;
|
||||
_world.AddListener(this);
|
||||
links = new (EcsEntityConnect, EntityMonitor)[_world.Capacity];
|
||||
}
|
||||
public void OnWorldResize(int newSize) { Array.Resize(ref links, newSize); }
|
||||
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer) { }
|
||||
public void OnWorldDestroy() { }
|
||||
}
|
||||
}
|
||||
public static void EntityBar(Rect position, int id, short gen, short world)
|
||||
public static void EntityField(Rect position, entlong entity)
|
||||
{
|
||||
EntityBar_Internal(position, false, id, gen, world);
|
||||
EntityField(position, DragonGUIContent.Empty, entity);
|
||||
}
|
||||
public static void EntityBar(Rect position)
|
||||
public static unsafe void EntityField(Rect position, DragonGUIContent label, entlong entity)
|
||||
{
|
||||
EntityBar_Internal(position, true);
|
||||
EntityField(position, label, (EntitySlotInfo)entity);
|
||||
}
|
||||
public static void EntityBar(Rect position, bool isPlaceholder, EntityStatus status, int id = 0, short gen = 0, short world = 0)
|
||||
public static void EntityField(Rect position, EntitySlotInfo entity)
|
||||
{
|
||||
EntityField(position, DragonGUIContent.Empty, entity);
|
||||
}
|
||||
public static void EntityField(Rect position, DragonGUIContent label, EntitySlotInfo entity)
|
||||
{
|
||||
bool isAlive = false;
|
||||
if (EcsWorld.TryGetWorld(entity.worldID, out EcsWorld world))
|
||||
{
|
||||
isAlive = world.IsAlive(entity.id, entity.gen);
|
||||
}
|
||||
EntityField_Internal(position, label, entity.id == 0, isAlive ? EntityStatus.Alive : EntityStatus.NotAlive, entity.id, entity.gen, entity.worldID);
|
||||
}
|
||||
public static void EntityField(Rect position, SerializedProperty property)
|
||||
{
|
||||
EntityField(position, property, DragonGUIContent.Empty);
|
||||
}
|
||||
public static void EntityField(Rect position, SerializedProperty property, DragonGUIContent label)
|
||||
{
|
||||
EntitySlotInfo entity = new EntitySlotInfo(property.FindPropertyRelative("_full").longValue);
|
||||
|
||||
if (property.hasMultipleDifferentValues)
|
||||
{
|
||||
EntityField_Internal(position, label, true, EntityStatus.Undefined, 0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isAlive = false;
|
||||
if (EcsWorld.TryGetWorld(entity.worldID, out EcsWorld world))
|
||||
{
|
||||
isAlive = world.IsAlive(entity.id, entity.gen);
|
||||
}
|
||||
EntityField_Internal(position, label, entity.id == 0, isAlive ? EntityStatus.Alive : EntityStatus.NotAlive, entity.id, entity.gen, entity.worldID);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void EntityField_Internal(Rect position, GUIContent label, bool isPlaceholder, EntityStatus status, int id, short gen, short world)
|
||||
{
|
||||
if (label != null)
|
||||
{
|
||||
Rect labelRect;
|
||||
(labelRect, position) = position.HorizontalSliceLeft(EditorGUIUtility.labelWidth * 0.65f);
|
||||
EditorGUI.LabelField(labelRect, label);
|
||||
}
|
||||
|
||||
using (SetLabelWidth(0f))
|
||||
{
|
||||
var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(position, 3f);
|
||||
@ -511,10 +647,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
switch (status)
|
||||
{
|
||||
case EntityStatus.NotAlive:
|
||||
statusColor = EcsGUI.RedColor;
|
||||
statusColor = RedColor;
|
||||
break;
|
||||
case EntityStatus.Alive:
|
||||
statusColor = EcsGUI.GreenColor;
|
||||
statusColor = GreenColor;
|
||||
break;
|
||||
default:
|
||||
statusColor = new Color32(200, 200, 200, 255);
|
||||
@ -524,18 +660,18 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
statusColor.a = 0.6f;
|
||||
EditorGUI.DrawRect(statusRect, statusColor);
|
||||
|
||||
EntityBar_Internal(entityInfoRect, isPlaceholder, id, gen, world);
|
||||
EntityFieldContent_Internal(entityInfoRect, isPlaceholder, id, gen, world);
|
||||
}
|
||||
}
|
||||
private static void EntityBar_Internal(Rect position, bool isPlaceHolder, int id = 0, short gen = 0, short world = 0)
|
||||
private static void EntityFieldContent_Internal(Rect position, bool isPlaceHolder, int id, short gen, short world)
|
||||
{
|
||||
using (SetLabelWidth(0f))
|
||||
using (SetLabelWidth(0f)) using (SetIndentLevel(0))
|
||||
{
|
||||
Color w = Color.gray;
|
||||
w.a = 0.6f;
|
||||
Color b = Color.black;
|
||||
b.a = 0.55f;
|
||||
EditorGUI.DrawRect(position, w);
|
||||
DrawRectSoftColor(position, w);
|
||||
|
||||
var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(position, 0.4f);
|
||||
var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f);
|
||||
@ -543,22 +679,19 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
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);
|
||||
DrawRectSoftColor(idRect, b);
|
||||
DrawRectSoftColor(genRect, b);
|
||||
DrawRectSoftColor(worldRect, b);
|
||||
|
||||
GUIStyle style = UnityEditorUtility.GetInputFieldCenterAnhor();
|
||||
|
||||
if (isPlaceHolder)
|
||||
{
|
||||
using (new EditorGUI.DisabledScope(true))
|
||||
using (SetAlpha(0.85f)) using (Disable)
|
||||
{
|
||||
GUI.Label(idRect, "Entity ID", style);
|
||||
using (SetAlpha(0.85f))
|
||||
{
|
||||
GUI.Label(genRect, "Generation", style);
|
||||
GUI.Label(worldRect, "World ID", style);
|
||||
}
|
||||
GUI.Label(genRect, "Generation", style);
|
||||
GUI.Label(worldRect, "World ID", style);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1031,7 +1164,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
var x = Group.Splited.GetEnumerator();
|
||||
x.MoveNext();
|
||||
return x.Current.GetHashCode() ^ state;
|
||||
};
|
||||
}
|
||||
;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
@ -44,7 +44,12 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
get { return UserSettingsPrefs.instance.IsShowHidden; }
|
||||
set { UserSettingsPrefs.instance.IsShowHidden = value; }
|
||||
}
|
||||
private static ComponentColorMode ComponentColorMode
|
||||
protected bool IsShowRuntimeComponents
|
||||
{
|
||||
get { return UserSettingsPrefs.instance.IsShowRuntimeComponents; }
|
||||
set { UserSettingsPrefs.instance.IsShowRuntimeComponents = value; }
|
||||
}
|
||||
protected static ComponentColorMode ComponentColorMode
|
||||
{
|
||||
get { return UserSettingsPrefs.instance.ComponentColorMode; }
|
||||
set { UserSettingsPrefs.instance.ComponentColorMode = value; }
|
||||
@ -190,7 +195,12 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
get { return UserSettingsPrefs.instance.IsShowHidden; }
|
||||
set { UserSettingsPrefs.instance.IsShowHidden = value; }
|
||||
}
|
||||
private static ComponentColorMode ComponentColorMode
|
||||
protected bool IsShowRuntimeComponents
|
||||
{
|
||||
get { return UserSettingsPrefs.instance.IsShowRuntimeComponents; }
|
||||
set { UserSettingsPrefs.instance.IsShowRuntimeComponents = value; }
|
||||
}
|
||||
protected static ComponentColorMode ComponentColorMode
|
||||
{
|
||||
get { return UserSettingsPrefs.instance.ComponentColorMode; }
|
||||
set { UserSettingsPrefs.instance.ComponentColorMode = value; }
|
||||
|
@ -86,9 +86,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
}
|
||||
}
|
||||
}
|
||||
internal class ComponentDropDown : MetaObjectsDropDown<IComponentTemplate>
|
||||
internal class ComponentTemplatesDropDown : MetaObjectsDropDown<IComponentTemplate>
|
||||
{
|
||||
public ComponentDropDown()
|
||||
public ComponentTemplatesDropDown()
|
||||
{
|
||||
IEnumerable<(IComponentTemplate template, ITypeMeta meta)> itemMetaPairs = ComponentTemplateTypeCache.Dummies.ToArray().Select(dummy =>
|
||||
{
|
||||
@ -163,14 +163,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
|
||||
if (_fieldProperty != null)
|
||||
{
|
||||
_fieldProperty.managedReferenceValue = cmptmp.Clone();
|
||||
_fieldProperty.managedReferenceValue = cmptmp.Clone_Reflection();
|
||||
_fieldProperty.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
internal class RuntimeComponentDropDown : MetaObjectsDropDown<IEcsPool>
|
||||
internal class RuntimeComponentsDropDown : MetaObjectsDropDown<IEcsPool>
|
||||
{
|
||||
public RuntimeComponentDropDown(IEnumerable<IEcsPool> pools)
|
||||
public RuntimeComponentsDropDown(IEnumerable<IEcsPool> pools)
|
||||
{
|
||||
IEnumerable<(IEcsPool pool, ITypeMeta meta)> itemMetaPairs = pools.Select(pool =>
|
||||
{
|
||||
@ -268,6 +268,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
|
||||
protected override void ItemSelected(AdvancedDropdownItem item)
|
||||
{
|
||||
//EcsGUI.Changed = true;
|
||||
base.ItemSelected(item);
|
||||
var tType = (Item)item;
|
||||
ItemSelected(tType);
|
||||
@ -332,7 +333,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
var x = Group.Splited.GetEnumerator();
|
||||
x.MoveNext();
|
||||
return x.Current.GetHashCode() ^ state;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
736
src/Internal/Editor/RuntimeComponentsDrawer.cs
Normal file
736
src/Internal/Editor/RuntimeComponentsDrawer.cs
Normal file
@ -0,0 +1,736 @@
|
||||
#if UNITY_EDITOR
|
||||
using DCFApixels.DragonECS.Unity.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Color = UnityEngine.Color;
|
||||
using UnityComponent = UnityEngine.Component;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Editors.X
|
||||
{
|
||||
internal class RuntimeComponentsDrawer
|
||||
{
|
||||
private const BindingFlags INSTANCE_FIELD_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||
private static void ResetRuntimeComponentReflectionCache()
|
||||
{
|
||||
RefEditorWrapper.ResetStaticState();
|
||||
foreach (var item in _runtimeComponentReflectionCaches)
|
||||
{
|
||||
item.Value.ResetWrappers();
|
||||
}
|
||||
//_runtimeComponentReflectionCaches.Clear();
|
||||
}
|
||||
private const int RuntimeComponentsMaxDepth = 2;
|
||||
private const int RuntimeComponentsDepthRoot = -1;
|
||||
|
||||
private static RuntimeComponentsDrawer[] _drawers;
|
||||
private static int _runtimeComponentsDepth = RuntimeComponentsDepthRoot;
|
||||
static RuntimeComponentsDrawer()
|
||||
{
|
||||
_drawers = new RuntimeComponentsDrawer[RuntimeComponentsMaxDepth + 1];
|
||||
_drawers[0] = new RuntimeComponentsDrawer();
|
||||
_drawers[1] = new RuntimeComponentsDrawer();
|
||||
_drawers[2] = new RuntimeComponentsDrawer();
|
||||
}
|
||||
|
||||
private List<IEcsPool> _componentPoolsBuffer = new List<IEcsPool>(64);
|
||||
|
||||
|
||||
#region Properties
|
||||
private static ComponentColorMode AutoColorMode
|
||||
{
|
||||
get { return UserSettingsPrefs.instance.ComponentColorMode; }
|
||||
set { UserSettingsPrefs.instance.ComponentColorMode = value; }
|
||||
}
|
||||
private static bool IsShowHidden
|
||||
{
|
||||
get { return UserSettingsPrefs.instance.IsShowHidden; }
|
||||
set { UserSettingsPrefs.instance.IsShowHidden = value; }
|
||||
}
|
||||
private static bool IsShowRuntimeComponents
|
||||
{
|
||||
get { return UserSettingsPrefs.instance.IsShowRuntimeComponents; }
|
||||
set { UserSettingsPrefs.instance.IsShowRuntimeComponents = value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region reflection cache
|
||||
internal class RuntimeComponentReflectionCache
|
||||
{
|
||||
public readonly Type Type;
|
||||
public readonly bool IsUnmanaged;
|
||||
public readonly DrawerType DrawerType;
|
||||
public readonly FieldInfoData[] Fields;
|
||||
|
||||
private RefEditorWrapper[] _wrappers = new RefEditorWrapper[RuntimeComponentsMaxDepth];
|
||||
public RefEditorWrapper GetWrapper(int depth)
|
||||
{
|
||||
return _wrappers[depth];
|
||||
}
|
||||
|
||||
public RuntimeComponentReflectionCache(Type type)
|
||||
{
|
||||
Type = type;
|
||||
ResetWrappers();
|
||||
IsUnmanaged = UnsafeUtility.IsUnmanaged(type);
|
||||
|
||||
bool isVoideType = type == typeof(void);
|
||||
bool isUnityObjectType = typeof(UnityObject).IsAssignableFrom(type);
|
||||
bool isLeaf = isUnityObjectType || type.IsPrimitive || type == typeof(string) || type.IsEnum;
|
||||
|
||||
DrawerType = DrawerType.UNDEFINED;
|
||||
|
||||
if(type.IsArray || isVoideType)
|
||||
{
|
||||
DrawerType = DrawerType.Ignored;
|
||||
}
|
||||
|
||||
if (DrawerType == DrawerType.UNDEFINED && isLeaf)
|
||||
{
|
||||
if (type.IsEnum)
|
||||
{
|
||||
DrawerType = type.HasAttribute<FlagsAttribute>() ? DrawerType.EnumFlags : DrawerType.Enum;
|
||||
}
|
||||
else if (isUnityObjectType)
|
||||
{
|
||||
DrawerType = DrawerType.UnityObject;
|
||||
}
|
||||
else if (type == typeof(bool))
|
||||
{
|
||||
DrawerType = DrawerType.Bool;
|
||||
}
|
||||
else if (type == typeof(string))
|
||||
{
|
||||
DrawerType = DrawerType.String;
|
||||
}
|
||||
else if (type == typeof(float))
|
||||
{
|
||||
DrawerType = DrawerType.Float;
|
||||
}
|
||||
else if (type == typeof(double))
|
||||
{
|
||||
DrawerType = DrawerType.Double;
|
||||
}
|
||||
else if (type == typeof(byte))
|
||||
{
|
||||
DrawerType = DrawerType.Byte;
|
||||
}
|
||||
else if (type == typeof(sbyte))
|
||||
{
|
||||
DrawerType = DrawerType.SByte;
|
||||
}
|
||||
else if (type == typeof(short))
|
||||
{
|
||||
DrawerType = DrawerType.Short;
|
||||
}
|
||||
else if (type == typeof(ushort))
|
||||
{
|
||||
DrawerType = DrawerType.UShort;
|
||||
}
|
||||
else if (type == typeof(int))
|
||||
{
|
||||
DrawerType = DrawerType.Int;
|
||||
}
|
||||
else if (type == typeof(uint))
|
||||
{
|
||||
DrawerType = DrawerType.UInt;
|
||||
}
|
||||
else if (type == typeof(long))
|
||||
{
|
||||
DrawerType = DrawerType.Long;
|
||||
}
|
||||
else if (type == typeof(ulong))
|
||||
{
|
||||
DrawerType = DrawerType.ULong;
|
||||
}
|
||||
}
|
||||
|
||||
if (DrawerType == DrawerType.UNDEFINED)
|
||||
{
|
||||
DrawerType = type.IsGenericType ? DrawerType.UnityNotSerializableComposite : DrawerType.UnitySerializableComposite;
|
||||
}
|
||||
|
||||
if (isVoideType) { return; }
|
||||
|
||||
if (DrawerType == DrawerType.UnityNotSerializableComposite)
|
||||
{
|
||||
var fieldInfos = type.GetFields(INSTANCE_FIELD_FLAGS);
|
||||
Fields = new FieldInfoData[fieldInfos.Length];
|
||||
for (int i = 0; i < fieldInfos.Length; i++)
|
||||
{
|
||||
var fieldInfo = fieldInfos[i];
|
||||
Fields[i] = new FieldInfoData(fieldInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void ResetWrappers()
|
||||
{
|
||||
_wrappers[0] = RefEditorWrapper.Take();
|
||||
_wrappers[1] = RefEditorWrapper.Take();
|
||||
}
|
||||
public readonly struct FieldInfoData
|
||||
{
|
||||
public readonly FieldInfo FieldInfo;
|
||||
public readonly Type FieldType;
|
||||
public readonly string UnityFormatName;
|
||||
public readonly bool IsUnityObjectField;
|
||||
public readonly bool IsPassToUnitySerialize;
|
||||
public readonly RuntimeComponentReflectionCache ValueTypeReflectionCache;
|
||||
|
||||
public FieldInfoData(FieldInfo fieldInfo)
|
||||
{
|
||||
FieldInfo = fieldInfo;
|
||||
FieldType = fieldInfo.FieldType;
|
||||
IsUnityObjectField = typeof(UnityObject).IsAssignableFrom(fieldInfo.FieldType);
|
||||
UnityFormatName = UnityEditorUtility.TransformFieldName(fieldInfo.Name);
|
||||
IsPassToUnitySerialize =
|
||||
(fieldInfo.IsPublic || fieldInfo.HasAttribute<SerializeField>() || fieldInfo.HasAttribute<SerializeReference>()) &&
|
||||
(fieldInfo.IsInitOnly || fieldInfo.HasAttribute<System.NonSerializedAttribute>()) == false;
|
||||
ValueTypeReflectionCache = FieldType.IsValueType ? GetRuntimeComponentReflectionCache(FieldType) : null;
|
||||
}
|
||||
public FieldInfoData(FieldInfo fieldInfo, Type fieldType, string unityFormatName, bool isPassToSerialize = true)
|
||||
{
|
||||
FieldInfo = fieldInfo;
|
||||
FieldType = fieldType;
|
||||
UnityFormatName = unityFormatName;
|
||||
IsUnityObjectField = typeof(UnityObject).IsAssignableFrom(fieldType);
|
||||
IsPassToUnitySerialize = isPassToSerialize;
|
||||
ValueTypeReflectionCache = FieldType.IsValueType ? GetRuntimeComponentReflectionCache(FieldType) : null;
|
||||
}
|
||||
public RuntimeComponentReflectionCache GetReflectionCache(Type type)
|
||||
{
|
||||
if (ValueTypeReflectionCache != null)
|
||||
{
|
||||
return ValueTypeReflectionCache;
|
||||
}
|
||||
return GetRuntimeComponentReflectionCache(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static Dictionary<Type, RuntimeComponentReflectionCache> _runtimeComponentReflectionCaches = new Dictionary<Type, RuntimeComponentReflectionCache>();
|
||||
private static RuntimeComponentReflectionCache GetRuntimeComponentReflectionCache(Type type)
|
||||
{
|
||||
if (_runtimeComponentReflectionCaches.TryGetValue(type, out RuntimeComponentReflectionCache result) == false)
|
||||
{
|
||||
result = new RuntimeComponentReflectionCache(type);
|
||||
_runtimeComponentReflectionCaches.Add(type, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region draw world component
|
||||
public static void DrawWorldComponents(EcsWorld world)
|
||||
{
|
||||
if (_runtimeComponentsDepth == RuntimeComponentsDepthRoot)
|
||||
{
|
||||
try
|
||||
{
|
||||
_runtimeComponentsDepth = 0;
|
||||
_drawers[0].DrawWorldComponents_Internal(world);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_runtimeComponentsDepth = RuntimeComponentsDepthRoot;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void DrawWorldComponents_Internal(EcsWorld world)
|
||||
{
|
||||
bool isNull = world == null || world.IsDestroyed || world.ID == 0;
|
||||
if (isNull) { return; }
|
||||
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetTransperentBlackBackgrounStyle()))
|
||||
{
|
||||
IsShowRuntimeComponents = EditorGUILayout.BeginFoldoutHeaderGroup(IsShowRuntimeComponents, "RUNTIME COMPONENTS", EditorStyles.foldout);
|
||||
EditorGUILayout.EndFoldoutHeaderGroup();
|
||||
if (IsShowRuntimeComponents == false) { return; }
|
||||
|
||||
var worldID = world.ID;
|
||||
var cmps = world.GetWorldComponents();
|
||||
int index = -1;
|
||||
int total = 9;
|
||||
foreach (var cmp in cmps)
|
||||
{
|
||||
index++;
|
||||
var meta = cmp.ComponentType.ToMeta();
|
||||
if (meta.IsHidden == false || IsShowHidden)
|
||||
{
|
||||
Type componentType = cmp.ComponentType;
|
||||
|
||||
object data = cmp.GetRaw(worldID);
|
||||
|
||||
ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType);
|
||||
|
||||
float padding = EditorGUIUtility.standardVerticalSpacing;
|
||||
Rect optionButton = GUILayoutUtility.GetLastRect();
|
||||
optionButton.yMin = optionButton.yMax;
|
||||
optionButton.yMax += EcsGUI.HeadIconsRect.height;
|
||||
optionButton.xMin = optionButton.xMax - 64;
|
||||
optionButton.center += Vector2.up * padding * 2f;
|
||||
//Canceling isExpanded
|
||||
if (EcsGUI.ClickTest(optionButton))
|
||||
{
|
||||
ref bool isExpanded = ref expandMatrix.Down();
|
||||
isExpanded = !isExpanded;
|
||||
}
|
||||
|
||||
Color panelColor = EcsGUI.SelectPanelColor(meta, index, total);
|
||||
using (EcsGUI.Layout.BeginVertical(panelColor.SetAlpha(EscEditorConsts.COMPONENT_DRAWER_ALPHA)))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
//Edit script button
|
||||
if (ScriptsCache.TryGetScriptAsset(meta, out MonoScript script))
|
||||
{
|
||||
optionButton = EcsGUI.HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
|
||||
EcsGUI.ScriptAssetButton(optionButton, script);
|
||||
}
|
||||
//Description icon
|
||||
if (string.IsNullOrEmpty(meta.Description.Text) == false)
|
||||
{
|
||||
optionButton = EcsGUI.HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
|
||||
EcsGUI.DescriptionIcon(optionButton, meta.Description.Text);
|
||||
}
|
||||
|
||||
RuntimeComponentReflectionCache.FieldInfoData componentInfoData = new RuntimeComponentReflectionCache.FieldInfoData(null, componentType, meta.Name);
|
||||
if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData, 0))
|
||||
{
|
||||
cmp.SetRaw(worldID, resultData);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region draw entity component
|
||||
public static void DrawRuntimeComponents(int entityID, EcsWorld world, bool isWithFoldout, bool isRoot)
|
||||
{
|
||||
if (isRoot)
|
||||
{
|
||||
_runtimeComponentsDepth = RuntimeComponentsDepthRoot;
|
||||
}
|
||||
_runtimeComponentsDepth++;
|
||||
|
||||
try
|
||||
{
|
||||
_drawers[_runtimeComponentsDepth].DrawRuntimeComponents(entityID, world, isWithFoldout);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_runtimeComponentsDepth--;
|
||||
if (_runtimeComponentsDepth < RuntimeComponentsDepthRoot)
|
||||
{
|
||||
_runtimeComponentsDepth = RuntimeComponentsDepthRoot;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void DrawRuntimeComponents(int entityID, EcsWorld world, bool isWithFoldout)
|
||||
{
|
||||
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetTransperentBlackBackgrounStyle())) using (EcsGUI.SetIndentLevel(0))
|
||||
{
|
||||
if (_runtimeComponentsDepth >= RuntimeComponentsMaxDepth)
|
||||
{
|
||||
GUILayout.Label("Max depth for inspecting components at runtime");
|
||||
return;
|
||||
}
|
||||
if (isWithFoldout)
|
||||
{
|
||||
IsShowRuntimeComponents = EditorGUILayout.BeginFoldoutHeaderGroup(IsShowRuntimeComponents, "RUNTIME COMPONENTS", EditorStyles.foldout);
|
||||
EditorGUILayout.EndFoldoutHeaderGroup();
|
||||
}
|
||||
if (isWithFoldout == false || IsShowRuntimeComponents)
|
||||
{
|
||||
if (EcsGUI.Layout.AddComponentButtons(out Rect dropDownRect))
|
||||
{
|
||||
RuntimeComponentsUtility.GetAddComponentGenericMenu(world).Open(dropDownRect, entityID);
|
||||
}
|
||||
|
||||
using (EcsGUI.SetBackgroundColor(GUI.color.SetAlpha(0.16f)))
|
||||
{
|
||||
GUILayout.Box("", UnityEditorUtility.GetWhiteStyle(), GUILayout.ExpandWidth(true));
|
||||
}
|
||||
IsShowHidden = EditorGUI.Toggle(GUILayoutUtility.GetLastRect(), "Show Hidden", IsShowHidden);
|
||||
|
||||
|
||||
world.GetComponentPoolsFor(entityID, _componentPoolsBuffer);
|
||||
for (int i = 0; i < _componentPoolsBuffer.Count; i++)
|
||||
{
|
||||
DrawRuntimeComponent(entityID, _componentPoolsBuffer[i], 9, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void DrawRuntimeComponent(int entityID, IEcsPool pool, int total, int index)
|
||||
{
|
||||
var meta = pool.ComponentType.ToMeta();
|
||||
if (meta.IsHidden == false || IsShowHidden)
|
||||
{
|
||||
Type componentType = pool.ComponentType;
|
||||
|
||||
object data = pool.GetRaw(entityID);
|
||||
|
||||
ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType);
|
||||
|
||||
float padding = EditorGUIUtility.standardVerticalSpacing;
|
||||
Rect optionButton = GUILayoutUtility.GetLastRect();
|
||||
optionButton.yMin = optionButton.yMax;
|
||||
optionButton.yMax += EcsGUI.HeadIconsRect.height;
|
||||
optionButton.xMin = optionButton.xMax - 64;
|
||||
optionButton.center += Vector2.up * padding * 2f;
|
||||
//Canceling isExpanded
|
||||
if (EcsGUI.ClickTest(optionButton))
|
||||
{
|
||||
ref bool isExpanded = ref expandMatrix.Down();
|
||||
isExpanded = !isExpanded;
|
||||
}
|
||||
|
||||
Color panelColor = EcsGUI.SelectPanelColor(meta, index, total);
|
||||
|
||||
using (EcsGUI.Layout.BeginVertical(panelColor.SetAlpha(EscEditorConsts.COMPONENT_DRAWER_ALPHA)))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
//Close button
|
||||
optionButton.xMin = optionButton.xMax - EcsGUI.HeadIconsRect.width;
|
||||
if (EcsGUI.CloseButton(optionButton))
|
||||
{
|
||||
pool.Del(entityID);
|
||||
return;
|
||||
}
|
||||
//Edit script button
|
||||
if (ScriptsCache.TryGetScriptAsset(meta, out MonoScript script))
|
||||
{
|
||||
optionButton = EcsGUI.HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
|
||||
EcsGUI.ScriptAssetButton(optionButton, script);
|
||||
}
|
||||
//Description icon
|
||||
if (string.IsNullOrEmpty(meta.Description.Text) == false)
|
||||
{
|
||||
optionButton = EcsGUI.HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
|
||||
EcsGUI.DescriptionIcon(optionButton, meta.Description.Text);
|
||||
}
|
||||
|
||||
RuntimeComponentReflectionCache.FieldInfoData componentInfoData = new RuntimeComponentReflectionCache.FieldInfoData(null, componentType, meta.Name);
|
||||
|
||||
if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData, 0))
|
||||
{
|
||||
pool.SetRaw(entityID, resultData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region draw data
|
||||
private bool DrawRuntimeData(ref RuntimeComponentReflectionCache.FieldInfoData fieldInfoData, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData, int depth)
|
||||
{
|
||||
const int DEPTH_MAX = 24;
|
||||
|
||||
using (EcsGUI.CheckChanged())
|
||||
{
|
||||
|
||||
outData = data;
|
||||
object newData = data;
|
||||
Type type = data == null ? typeof(void) : data.GetType();
|
||||
bool isUnityObjectField = fieldInfoData.IsUnityObjectField;
|
||||
if (isUnityObjectField == false && data == null)
|
||||
{
|
||||
EditorGUILayout.TextField(label, "Null");
|
||||
return false;
|
||||
}
|
||||
|
||||
RuntimeComponentReflectionCache cache = fieldInfoData.GetReflectionCache(type);
|
||||
if (depth >= DEPTH_MAX || cache == null)
|
||||
{
|
||||
EditorGUILayout.TextField(label, "error");
|
||||
return false;
|
||||
}
|
||||
|
||||
ref bool isExpanded = ref expandMatrix.Down();
|
||||
bool childElementChanged = false;
|
||||
var eventType = Event.current.type;
|
||||
|
||||
var label2 = "-";
|
||||
var drawerType = cache.DrawerType;
|
||||
|
||||
if (isUnityObjectField)
|
||||
{
|
||||
drawerType = DrawerType.UnityObject;
|
||||
}
|
||||
switch (drawerType)
|
||||
{
|
||||
case DrawerType.UNDEFINED:
|
||||
EditorGUILayout.LabelField(label, label2);
|
||||
break;
|
||||
case DrawerType.Ignored:
|
||||
EditorGUILayout.LabelField(label, label2);
|
||||
break;
|
||||
case DrawerType.UnitySerializableComposite:
|
||||
|
||||
using (EcsGUI.CheckChanged())
|
||||
{
|
||||
RefEditorWrapper wrapper = cache.GetWrapper(_runtimeComponentsDepth);
|
||||
wrapper.data = data;
|
||||
wrapper.SO.Update();
|
||||
wrapper.IsExpanded = isExpanded;
|
||||
EditorGUILayout.PropertyField(wrapper.Property, label, true);
|
||||
|
||||
if (EcsGUI.Changed)
|
||||
{
|
||||
wrapper.SO.ApplyModifiedProperties();
|
||||
newData = wrapper.Data;
|
||||
childElementChanged = true;
|
||||
}
|
||||
isExpanded = wrapper.IsExpanded;
|
||||
}
|
||||
|
||||
break;
|
||||
case DrawerType.UnityNotSerializableComposite:
|
||||
|
||||
GUILayout.Space(EcsGUI.Spacing);
|
||||
var foldoutStyle = EditorStyles.foldout;
|
||||
Rect rect = GUILayoutUtility.GetRect(label, foldoutStyle);
|
||||
//rect.xMin += EcsGUI.Indent;
|
||||
isExpanded = EditorGUI.BeginFoldoutHeaderGroup(rect, isExpanded, label, foldoutStyle, null, null);
|
||||
EditorGUILayout.EndFoldoutHeaderGroup();
|
||||
|
||||
if (isExpanded)
|
||||
{
|
||||
using (EcsGUI.UpIndentLevel())
|
||||
{
|
||||
for (int j = 0, jMax = cache.Fields.Length; j < jMax; j++)
|
||||
{
|
||||
var field = cache.Fields[j];
|
||||
if (DrawRuntimeData(ref field, UnityEditorUtility.GetLabel(field.UnityFormatName), expandMatrix, field.FieldInfo.GetValue(data), out object fieldData, depth + 1))
|
||||
{
|
||||
field.FieldInfo.SetValue(data, fieldData);
|
||||
newData = data;
|
||||
childElementChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case DrawerType.UnityObject:
|
||||
|
||||
using (EcsGUI.CheckChanged())
|
||||
{
|
||||
var uobj = UnsafeUtility.As<object, UnityObject>(ref data);
|
||||
bool isComponent = typeof(UnityComponent).IsAssignableFrom(fieldInfoData.FieldType);
|
||||
var newuobj = EditorGUILayout.ObjectField(label, uobj, fieldInfoData.FieldType, true);
|
||||
|
||||
if (uobj != newuobj)
|
||||
{
|
||||
if (isComponent && newuobj is GameObject go)
|
||||
{
|
||||
newuobj = go.GetComponent(fieldInfoData.FieldType);
|
||||
}
|
||||
newData = newuobj;
|
||||
childElementChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case DrawerType.Enum:
|
||||
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
var enumData = UnsafeUtility.As<object, Enum>(ref data);
|
||||
newData = EditorGUILayout.EnumPopup(label, enumData);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.EnumPopup(label, default);
|
||||
}
|
||||
|
||||
break;
|
||||
case DrawerType.EnumFlags:
|
||||
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
var enumData = UnsafeUtility.As<object, Enum>(ref data);
|
||||
newData = EditorGUILayout.EnumFlagsField(label, enumData);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.EnumFlagsField(label, default);
|
||||
}
|
||||
|
||||
break;
|
||||
case DrawerType.Bool:
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
newData = EditorGUILayout.Toggle(label, (bool)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.Toggle(label, default);
|
||||
}
|
||||
break;
|
||||
case DrawerType.String:
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
newData = EditorGUILayout.TextField(label, (string)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.TextField(label, default);
|
||||
}
|
||||
break;
|
||||
case DrawerType.Float:
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
newData = EditorGUILayout.FloatField(label, (float)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.FloatField(label, default);
|
||||
}
|
||||
break;
|
||||
case DrawerType.Double:
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
newData = EditorGUILayout.DoubleField(label, (double)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.DoubleField(label, default);
|
||||
}
|
||||
break;
|
||||
case DrawerType.Byte:
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
newData = (byte)EditorGUILayout.IntField(label, (byte)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.IntField(label, default);
|
||||
}
|
||||
break;
|
||||
case DrawerType.SByte:
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
newData = (sbyte)EditorGUILayout.IntField(label, (sbyte)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.IntField(label, default);
|
||||
}
|
||||
break;
|
||||
case DrawerType.Short:
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
newData = (short)EditorGUILayout.IntField(label, (short)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.IntField(label, default);
|
||||
}
|
||||
break;
|
||||
case DrawerType.UShort:
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
newData = (ushort)EditorGUILayout.IntField(label, (ushort)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.IntField(label, default);
|
||||
}
|
||||
break;
|
||||
case DrawerType.Int:
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
newData = (int)EditorGUILayout.IntField(label, (int)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.IntField(label, default);
|
||||
}
|
||||
break;
|
||||
case DrawerType.UInt:
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
newData = (uint)EditorGUILayout.IntField(label, (int)(uint)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.IntField(label, default);
|
||||
}
|
||||
break;
|
||||
case DrawerType.Long:
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
newData = EditorGUILayout.LongField(label, (long)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LongField(label, default);
|
||||
}
|
||||
break;
|
||||
case DrawerType.ULong:
|
||||
if (eventType != EventType.Layout)
|
||||
{
|
||||
newData = (ulong)EditorGUILayout.LongField(label, (long)(ulong)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LongField(label, default);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
EditorGUILayout.LabelField(label, label2);
|
||||
break;
|
||||
}
|
||||
|
||||
expandMatrix.Up();
|
||||
if (childElementChanged || EcsGUI.Changed)
|
||||
{
|
||||
outData = newData;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public enum DrawerType
|
||||
{
|
||||
UNDEFINED = 0,
|
||||
Ignored,
|
||||
// Composite
|
||||
UnitySerializableComposite,
|
||||
UnityNotSerializableComposite,
|
||||
// Leaft types
|
||||
UnityObject,
|
||||
Enum,
|
||||
EnumFlags,
|
||||
Bool,
|
||||
String,
|
||||
Float,
|
||||
Double,
|
||||
Byte,
|
||||
SByte,
|
||||
Short,
|
||||
UShort,
|
||||
Int,
|
||||
UInt,
|
||||
Long,
|
||||
ULong,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
2
src/Internal/Editor/RuntimeComponentsDrawer.cs.meta
Normal file
2
src/Internal/Editor/RuntimeComponentsDrawer.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69581c5eb282d024baca88cb374bf5af
|
@ -17,7 +17,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
public abstract void Release();
|
||||
}
|
||||
[Serializable]
|
||||
internal abstract class WrapperBase<TSelf> : WrapperBase
|
||||
internal abstract class WrapperBase<TSelf> : WrapperBase, IDisposable
|
||||
where TSelf : WrapperBase<TSelf>
|
||||
{
|
||||
|
||||
@ -28,6 +28,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
private bool _isReleased = false;
|
||||
|
||||
private static Stack<TSelf> _wrappers = new Stack<TSelf>();
|
||||
public static void ResetStaticState()
|
||||
{
|
||||
foreach (var item in _wrappers)
|
||||
{
|
||||
UnityEngine.Object.DestroyImmediate(item);
|
||||
}
|
||||
_wrappers.Clear();
|
||||
}
|
||||
|
||||
public sealed override bool IsExpanded
|
||||
{
|
||||
@ -88,6 +96,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
Release((TSelf)this);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Dispose()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -235,6 +235,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
//private static Type[] _noHiddenSerializableTypes;
|
||||
private static GUIContent _singletonIconContent = null;
|
||||
private static GUIContent _singletonContent = null;
|
||||
private static GUIContent _singleton2Content = null;
|
||||
private static GUIStyle _inputFieldCenterAnhor = null;
|
||||
private static Dictionary<Type, MonoScript> _scriptsAssets = new Dictionary<Type, MonoScript>(256);
|
||||
|
||||
@ -312,8 +313,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
break;
|
||||
case SerializedPropertyType.Gradient:
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
property.gradientValue = new Gradient();;
|
||||
|
||||
property.gradientValue = new Gradient(); ;
|
||||
|
||||
#else
|
||||
Debug.LogWarning($"Unsupported SerializedPropertyType: {property.propertyType}");
|
||||
#endif
|
||||
@ -402,6 +403,22 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
_singletonContent.image = null;
|
||||
return _singletonContent;
|
||||
}
|
||||
public static GUIContent GetLabelOrNull(string name, string tooltip = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return GetLabel(name, tooltip);
|
||||
}
|
||||
public static GUIContent GetLabelOrNull(Texture value, string tooltip = null)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return GetLabel(value, tooltip);
|
||||
}
|
||||
public static GUIContent GetLabel(string name, string tooltip = null)
|
||||
{
|
||||
if (_singletonContent == null)
|
||||
@ -424,6 +441,17 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
_singletonIconContent.tooltip = tooltip;
|
||||
return _singletonIconContent;
|
||||
}
|
||||
public static GUIContent GetLabel2(string name, string tooltip = null)
|
||||
{
|
||||
if (_singleton2Content == null)
|
||||
{
|
||||
_singleton2Content = new GUIContent();
|
||||
}
|
||||
_singleton2Content.text = name;
|
||||
_singleton2Content.image = null;
|
||||
_singleton2Content.tooltip = tooltip;
|
||||
return _singleton2Content;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetDefaultStyle
|
||||
@ -507,9 +535,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
public struct WorldData
|
||||
{
|
||||
public RuntimeComponentDropDown addComponentGenericMenu;
|
||||
public RuntimeComponentsDropDown addComponentGenericMenu;
|
||||
public int poolsCount;
|
||||
public WorldData(RuntimeComponentDropDown addComponentGenericMenu, int poolsCount)
|
||||
public WorldData(RuntimeComponentsDropDown addComponentGenericMenu, int poolsCount)
|
||||
{
|
||||
this.addComponentGenericMenu = addComponentGenericMenu;
|
||||
this.poolsCount = poolsCount;
|
||||
@ -518,7 +546,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
//world id
|
||||
private static Dictionary<EcsWorld, WorldData> _worldDatas = new Dictionary<EcsWorld, WorldData>();
|
||||
|
||||
public static RuntimeComponentDropDown GetAddComponentGenericMenu(EcsWorld world)
|
||||
public static RuntimeComponentsDropDown GetAddComponentGenericMenu(EcsWorld world)
|
||||
{
|
||||
if (_worldDatas.TryGetValue(world, out WorldData data))
|
||||
{
|
||||
@ -541,7 +569,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
private static WorldData CreateWorldData(EcsWorld world)
|
||||
{
|
||||
IEnumerable<IEcsPool> pools = world.AllPools.ToArray().Where(o => o.IsNullOrDummy() == false);
|
||||
RuntimeComponentDropDown genericMenu = new RuntimeComponentDropDown(pools);
|
||||
RuntimeComponentsDropDown genericMenu = new RuntimeComponentsDropDown(pools);
|
||||
return new WorldData(genericMenu, world.PoolsCount);
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,11 @@ guid: 4f1ca6aa9d407844485856184c785946
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
@ -20,11 +20,12 @@ TextureImporter:
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMasterTextureLimit: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
@ -63,8 +64,10 @@ TextureImporter:
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
@ -74,9 +77,10 @@ TextureImporter:
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
@ -86,9 +90,10 @@ TextureImporter:
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
- serializedVersion: 4
|
||||
buildTarget: Server
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
@ -98,12 +103,27 @@ TextureImporter:
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
@ -113,10 +133,11 @@ TextureImporter:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
spritePackingTag:
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
BIN
src/Internal/Icons/HyperlinkIcon.png
Normal file
BIN
src/Internal/Icons/HyperlinkIcon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
130
src/Internal/Icons/HyperlinkIcon.png.meta
Normal file
130
src/Internal/Icons/HyperlinkIcon.png.meta
Normal file
@ -0,0 +1,130 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a89f8c59dad13641b9c51337e8fd7ad
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -43,7 +43,8 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
private Texture _labelIconType = null;
|
||||
[SerializeField]
|
||||
private Texture _labelIconMeta = null;
|
||||
|
||||
[SerializeField]
|
||||
private Texture _hyperlinkIcon = null;
|
||||
|
||||
private Texture2D _dummy;
|
||||
private Texture2D _dummyRed;
|
||||
@ -117,6 +118,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
internal Texture VisibilityIconOff { get { return _visibilityIconOff != null ? _visibilityIconOff : Dummy; } }
|
||||
internal Texture LabelIconType { get { return _labelIconType != null ? _labelIconType : Dummy; } }
|
||||
internal Texture LabelIconMeta { get { return _labelIconMeta != null ? _labelIconMeta : Dummy; } }
|
||||
internal Texture HyperlinkIcon { get { return _hyperlinkIcon != null ? _hyperlinkIcon : Dummy; } }
|
||||
#endif
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ MonoImporter:
|
||||
- _visibilityIconOff: {fileID: 2800000, guid: 1f25a5ca611092642a8ee4e08fafcd43, type: 3}
|
||||
- _labelIconType: {fileID: 2800000, guid: 5476d6e1435981e4cbc915a080f93ee6, type: 3}
|
||||
- _labelIconMeta: {fileID: 2800000, guid: ebb82b09315bde749a10dfa45e64067c, type: 3}
|
||||
- _hyperlinkIcon: {fileID: 2800000, guid: 2a89f8c59dad13641b9c51337e8fd7ad, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
|
@ -29,3 +29,4 @@ MonoBehaviour:
|
||||
_visibilityIconOff: {fileID: 2800000, guid: 1f25a5ca611092642a8ee4e08fafcd43, type: 3}
|
||||
_labelIconType: {fileID: 2800000, guid: 5476d6e1435981e4cbc915a080f93ee6, type: 3}
|
||||
_labelIconMeta: {fileID: 2800000, guid: ebb82b09315bde749a10dfa45e64067c, type: 3}
|
||||
_hyperlinkIcon: {fileID: 2800000, guid: 2a89f8c59dad13641b9c51337e8fd7ad, type: 3}
|
||||
|
@ -33,6 +33,20 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
{
|
||||
return self.IsSubclassOf(typeof(UnityObject));
|
||||
}
|
||||
|
||||
private static MethodInfo memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
internal static object Clone_Reflection(this object obj)
|
||||
{
|
||||
if (obj is ICloneable cloneable)
|
||||
{
|
||||
return cloneable.Clone();
|
||||
}
|
||||
return memberwiseCloneMethdo.Invoke(obj, null);
|
||||
}
|
||||
internal static object Clone_Reflection<T>(this T obj)
|
||||
{
|
||||
return Clone_Reflection((object)obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -346,6 +346,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
if (_serializableMetaIDScriptPathPairs == null) { return; }
|
||||
_metaIDScriptPathPairs.Clear();
|
||||
foreach (var item in _serializableMetaIDScriptPathPairs)
|
||||
{
|
||||
if (string.IsNullOrEmpty(item.scriptPath) == false)
|
||||
|
@ -5,7 +5,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
{
|
||||
internal readonly struct ReadOnlyList<T> : IEnumerable<T>, IReadOnlyList<T>
|
||||
{
|
||||
private readonly List<T> _list;
|
||||
private readonly List<T> _list;
|
||||
public ReadOnlyList(List<T> list)
|
||||
{
|
||||
_list = list;
|
||||
|
@ -62,7 +62,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
state ^= state >> 17;
|
||||
state ^= state << 5;
|
||||
return state;
|
||||
};
|
||||
}
|
||||
}
|
||||
public static void DebugRect_Editor(params Rect[] rects)
|
||||
{
|
||||
|
@ -249,17 +249,17 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
self._items[index] = item;
|
||||
}
|
||||
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
// public static bool TryDequeue_MultiAccess<T>(this ref StructList<T> self, T item)
|
||||
// {
|
||||
// var index = Interlocked.Increment(ref self._count);
|
||||
//
|
||||
//#if DEBUG
|
||||
// if (_count <= 0) { Throw.ArgumentOutOfRange(); }
|
||||
//#endif
|
||||
// T result = _items[--_count];
|
||||
// _items[_count] = default;
|
||||
// return result;
|
||||
// }
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
// public static bool TryDequeue_MultiAccess<T>(this ref StructList<T> self, T item)
|
||||
// {
|
||||
// var index = Interlocked.Increment(ref self._count);
|
||||
//
|
||||
//#if DEBUG
|
||||
// if (_count <= 0) { Throw.ArgumentOutOfRange(); }
|
||||
//#endif
|
||||
// T result = _items[--_count];
|
||||
// _items[_count] = default;
|
||||
// return result;
|
||||
// }
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
internal class ComponentTemplateReferenceDrawer : ExtendedPropertyDrawer<ComponentTemplateReferenceAttribute>
|
||||
{
|
||||
private const float DamagedComponentHeight = 18f * 2f;
|
||||
private static ComponentDropDown _componentDropDown;
|
||||
private static ComponentTemplatesDropDown _componentDropDown;
|
||||
|
||||
#region Properties
|
||||
private float SingleLineWithPadding => OneLineHeight + Padding * 4f;
|
||||
@ -41,15 +41,16 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
#region Init
|
||||
protected override void OnStaticInit()
|
||||
{
|
||||
_componentDropDown = new ComponentDropDown();
|
||||
_componentDropDown = new ComponentTemplatesDropDown();
|
||||
_componentDropDown.OnSelected += SelectComponent;
|
||||
}
|
||||
|
||||
[ThreadStatic]
|
||||
private static SerializedProperty currentProperty;
|
||||
private static void SelectComponent(ComponentDropDown.Item item)
|
||||
private static void SelectComponent(ComponentTemplatesDropDown.Item item)
|
||||
{
|
||||
currentProperty.managedReferenceValue = item.Obj.Clone();
|
||||
//EcsGUI.Changed = true;
|
||||
currentProperty.managedReferenceValue = item.Obj.Clone_Reflection();
|
||||
currentProperty.isExpanded = false;
|
||||
currentProperty.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
@ -9,10 +9,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
internal abstract class EntityTemplateEditorBase : ExtendedEditor<IEntityTemplateInternal>
|
||||
{
|
||||
private ComponentDropDown _componentDropDown;
|
||||
private ComponentTemplatesDropDown _componentDropDown;
|
||||
|
||||
private SerializedProperty _componentsProp;
|
||||
private ReorderableList _reorderableComponentsList;
|
||||
private int _reorderableComponentsListLastCount;
|
||||
|
||||
protected abstract bool IsSO { get; }
|
||||
|
||||
@ -22,7 +23,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
protected override bool IsInit { get { return _componentDropDown != null; } }
|
||||
protected override void OnInit()
|
||||
{
|
||||
_componentDropDown = new ComponentDropDown();
|
||||
_componentDropDown = new ComponentTemplatesDropDown();
|
||||
|
||||
_componentsProp = serializedObject.FindProperty(Target.ComponentsPropertyName);
|
||||
|
||||
@ -38,6 +39,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
_reorderableComponentsList.footerHeight = 0f;
|
||||
_reorderableComponentsList.headerHeight = 0f;
|
||||
_reorderableComponentsList.elementHeight = 0f;
|
||||
|
||||
_reorderableComponentsListLastCount = _reorderableComponentsList.count;
|
||||
}
|
||||
|
||||
#region ReorderableComponentsList
|
||||
@ -166,6 +169,15 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
GUILayout.Label("Multi-object editing not supported.", EditorStyles.helpBox);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//костыль который насильно заставляет _reorderableComponentsList пересчитать высоту
|
||||
if (_reorderableComponentsListLastCount != _reorderableComponentsList.count)
|
||||
{
|
||||
EcsGUI.Changed = true;
|
||||
_reorderableComponentsListLastCount = _reorderableComponentsList.count;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsMultipleTargets == false && SerializationUtility.HasManagedReferencesWithMissingTypes(target))
|
||||
{
|
||||
|
@ -87,6 +87,7 @@ namespace DCFApixels.DragonECS
|
||||
_defaultValueType = (T)field.GetValue(null);
|
||||
}
|
||||
}
|
||||
_defaultValueTypeInit = true;
|
||||
}
|
||||
return _defaultValueType;
|
||||
}
|
||||
@ -144,22 +145,6 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Internal
|
||||
{
|
||||
internal static class ComponentTemplateExtensions
|
||||
{
|
||||
private static MethodInfo memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
internal static IComponentTemplate Clone(this IComponentTemplate obj)
|
||||
{
|
||||
if(obj is ICloneable cloneable)
|
||||
{
|
||||
return (IComponentTemplate)cloneable.Clone();
|
||||
}
|
||||
return (IComponentTemplate)memberwiseCloneMethdo.Invoke(obj, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
@ -181,10 +166,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
Type interfaceType = typeof(IComponentTemplate);
|
||||
|
||||
_types = UnityEditorUtility._serializableTypes.Where(type => interfaceType.IsAssignableFrom(type)).ToArray();
|
||||
foreach (var type in _types)
|
||||
{
|
||||
EcsDebugUtility.GetTypeMeta(type);
|
||||
}
|
||||
//foreach (var type in _types)
|
||||
//{
|
||||
// EcsDebugUtility.GetTypeMeta(type);
|
||||
//}
|
||||
_dummies = new IComponentTemplate[_types.Length];
|
||||
|
||||
for (int i = 0; i < _types.Length; i++)
|
||||
|
@ -7,6 +7,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
@ -25,6 +26,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
[SerializeReference]
|
||||
[ReferenceButton(true, typeof(IComponentTemplate))]
|
||||
[FormerlySerializedAs("_components")]
|
||||
private IComponentTemplate[] _componentTemplates;
|
||||
|
||||
#region Properties
|
||||
|
@ -7,6 +7,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
@ -26,6 +27,7 @@ namespace DCFApixels.DragonECS
|
||||
private ScriptableEntityTemplateBase[] _templates;
|
||||
[SerializeReference]
|
||||
[ReferenceButton(true, typeof(IComponentTemplate))]
|
||||
[FormerlySerializedAs("_components")]
|
||||
private IComponentTemplate[] _componentTemplates;
|
||||
|
||||
#region Properties
|
||||
|
@ -21,7 +21,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
}
|
||||
}
|
||||
|
||||
using (EcsGUI.SetIndentLevel(IsArrayElement ? EditorGUI.indentLevel : EditorGUI.indentLevel + 1))
|
||||
using (EcsGUI.SetIndentLevel(IsArrayElement ? EcsGUI.IndentLevel : EcsGUI.IndentLevel + 1))
|
||||
{
|
||||
Rect subPosition = position;
|
||||
int depth = -1;
|
||||
|
@ -9,7 +9,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
internal class DeepDebuggerWindow : EditorWindow
|
||||
{
|
||||
public const string TITLE = "DeepDebuggerWindow";
|
||||
public const string TITLE = nameof(DeepDebuggerWindow);
|
||||
|
||||
#if DRAGONECS_DEEP_DEBUG
|
||||
[MenuItem("Tools/" + EcsConsts.FRAMEWORK_NAME + "/" + TITLE)]
|
||||
@ -43,7 +43,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawScriptsCache()
|
||||
{
|
||||
if (GUILayout.Button("Reset"))
|
||||
|
@ -363,7 +363,7 @@ namespace DCFApixels.DragonECS.Unity.Docs.Editors
|
||||
|
||||
if (_searchingSample.Length == 0)
|
||||
{
|
||||
EditorGUI.indentLevel = groupInfo.Depth;
|
||||
EcsGUI.IndentLevel = groupInfo.Depth;
|
||||
}
|
||||
|
||||
GUIContent label = UnityEditorUtility.GetLabel(_searchingSample.Length == 0 ? groupInfo.Name : groupInfo.Path);
|
||||
|
8
src/Tools/MetaIDgenerator.meta
Normal file
8
src/Tools/MetaIDgenerator.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97fdad78c98d48c43a73aeecf2083cbb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
src/Tools/MetaIDgenerator/Editors.meta
Normal file
8
src/Tools/MetaIDgenerator/Editors.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d73207c0a0e08c3479a7101a2090e17c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
42
src/Tools/MetaIDgenerator/Editors/MetaIDGenerator.cs
Normal file
42
src/Tools/MetaIDgenerator/Editors/MetaIDGenerator.cs
Normal file
@ -0,0 +1,42 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
|
||||
internal class MetaIDGenerator : EditorWindow
|
||||
{
|
||||
public const string TITLE = nameof(MetaIDGenerator);
|
||||
|
||||
[MenuItem("Tools/" + EcsConsts.FRAMEWORK_NAME + "/" + TITLE)]
|
||||
static void Open()
|
||||
{
|
||||
var wnd = GetWindow<MetaIDGenerator>();
|
||||
wnd.titleContent = new GUIContent(TITLE);
|
||||
wnd.minSize = new Vector2(100f, 120f);
|
||||
wnd.Show();
|
||||
}
|
||||
|
||||
|
||||
private string _lastID;
|
||||
private string _lastIDAttribute;
|
||||
private string _template;
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
EditorGUILayout.TextField("MetaID", _lastID);
|
||||
EditorGUILayout.TextField("Attribute", _lastIDAttribute);
|
||||
EditorGUILayout.TextField("Template Type", _template);
|
||||
|
||||
if (GUILayout.Button("Generate new MetaID"))
|
||||
{
|
||||
_lastID = MetaID.GenerateNewUniqueID();
|
||||
_lastIDAttribute = MetaID.IDToAttribute(_lastID);
|
||||
_template = "Tempalte" + MetaID.ConvertIDToTypeName(_lastID);
|
||||
GUI.FocusControl(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 63d0e9c5d1c44844abb3e6dc3c863668
|
@ -34,7 +34,7 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
|
||||
public bool TryGetMetaID(TypeData key, out string metaID)
|
||||
{
|
||||
bool result = _typeKeyMetaIDPairs.TryGetValue(key, out metaID);
|
||||
if(result && string.IsNullOrEmpty(metaID))
|
||||
if (result && string.IsNullOrEmpty(metaID))
|
||||
{
|
||||
result = false;
|
||||
_typeKeyMetaIDPairs.Remove(key);
|
||||
|
@ -79,12 +79,12 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Internal
|
||||
AssemblyName == other.AssemblyName;
|
||||
}
|
||||
public override bool Equals(object obj) { return Equals((TypeData)obj); }
|
||||
public override int GetHashCode()
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hash1 = ClassName.GetHashCode();
|
||||
int hash2 = NamespaceName.GetHashCode();
|
||||
int hash3 = AssemblyName.GetHashCode();
|
||||
return hash1 ^ hash2 ^ hash3;
|
||||
return hash1 ^ hash2 ^ hash3;
|
||||
}
|
||||
public override string ToString() { return $"{{{AssemblyName}, {NamespaceName}, {ClassName}}}"; }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user