Merge branch 'dev'

This commit is contained in:
Mikhail 2024-05-17 00:22:21 +08:00
commit 41b1ee96bf
30 changed files with 710 additions and 172 deletions

View File

@ -8,7 +8,7 @@
"displayName": "DragonECS-Unity",
"description": "Integration with Unity for DragonECS",
"unity": "2021.2",
"version": "0.3.16",
"version": "0.3.19",
"repository": {
"type": "git",
"url": "https://github.com/DCFApixels/DragonECS-Unity.git"

View File

@ -1,23 +1,27 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace DCFApixels.DragonECS
{
internal static class UnityComponentConsts
{
private const string UNITY_COMPONENT_NAME = "UnityComponent";
internal const string UNITY_COMPONENT_NAME = "UnityComponent";
public static readonly MetaGroup BaseGroup = new MetaGroup(UNITY_COMPONENT_NAME);
public static readonly MetaGroup ColliderGroup = new MetaGroup($"{UNITY_COMPONENT_NAME}/Collider/");
public static readonly MetaGroup JointGroup = new MetaGroup($"{UNITY_COMPONENT_NAME}/Joint/");
}
[Serializable]
[MetaColor(255 / 3, 255, 0)]
[MetaDescription(EcsConsts.AUTHOR, "Component-reference to Unity object for EcsPool")]
[MetaGroup(UnityComponentConsts.UNITY_COMPONENT_NAME)]
public struct UnityComponent<T> : IEcsComponent, IEnumerable<T>//IntelliSense hack
where T : Component
{
public T obj;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public UnityComponent(T obj)
{
this.obj = obj;
@ -30,6 +34,10 @@ namespace DCFApixels.DragonECS
{
throw new NotImplementedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator T(UnityComponent<T> a) { return a.obj; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator UnityComponent<T>(T a) { return new UnityComponent<T>(a); }
}
#region Unity Component Templates

View File

@ -1,8 +1,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using UnityEditor;
using UnityEngine;
#region UNITY_EDITOR
using UnityEditor;
#endregion
namespace DCFApixels.DragonECS
{
@ -172,6 +174,7 @@ namespace DCFApixels.DragonECS
internal void Autoset_Editor()
{
Autoset(this);
}
[ContextMenu("Autoset Cascade")]
internal void AutosetCascade_Editor()

View File

@ -29,7 +29,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
nameof(EcsConsts.DISABLE_DEBUG),
nameof(EcsConsts.ENABLE_DUMMY_SPAN),
nameof(EcsConsts.DISABLE_CATH_EXCEPTIONS),
"DEBUG",
};
for (int i = 0; i < _defineSymbols.Count; i++)
{
@ -61,24 +60,27 @@ namespace DCFApixels.DragonECS.Unity.Editors
GUILayout.BeginHorizontal();
settings.IsShowHidden = EditorGUILayout.Toggle(SettingsPrefs.instance.IsShowHidden, GUILayout.Width(checkBoxWidth));
GUILayout.Label(nameof(SettingsPrefs.IsShowHidden), GUILayout.ExpandWidth(false));
GUILayout.Label(UnityEditorUtility.TransformFieldName(nameof(SettingsPrefs.IsShowHidden)), GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
settings.IsShowInterfaces = EditorGUILayout.Toggle(SettingsPrefs.instance.IsShowInterfaces, GUILayout.Width(checkBoxWidth));
GUILayout.Label(nameof(SettingsPrefs.IsShowInterfaces), GUILayout.ExpandWidth(false));
GUILayout.Label(UnityEditorUtility.TransformFieldName(nameof(SettingsPrefs.IsShowInterfaces)), GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
settings.IsShowRuntimeComponents = EditorGUILayout.Toggle(SettingsPrefs.instance.IsShowRuntimeComponents, GUILayout.Width(checkBoxWidth));
GUILayout.Label(nameof(SettingsPrefs.IsShowRuntimeComponents), GUILayout.ExpandWidth(false));
GUILayout.Label(UnityEditorUtility.TransformFieldName(nameof(SettingsPrefs.IsShowRuntimeComponents)), GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal();
settings.AutoColorMode = (ComponentColorMode)EditorGUILayout.EnumPopup(UnityEditorUtility.TransformFieldName(nameof(SettingsPrefs.ComponentColorMode)), SettingsPrefs.instance.ComponentColorMode);
if (EditorGUI.EndChangeCheck())
{
SettingsPrefs.instance.IsShowHidden = settings.IsShowHidden;
SettingsPrefs.instance.IsShowInterfaces = settings.IsShowInterfaces;
SettingsPrefs.instance.IsShowRuntimeComponents = settings.IsShowRuntimeComponents;
SettingsPrefs.instance.ComponentColorMode = settings.AutoColorMode;
}
GUILayout.EndVertical();
@ -144,6 +146,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
public bool IsShowHidden;
public bool IsShowInterfaces;
public bool IsShowRuntimeComponents;
public ComponentColorMode AutoColorMode;
}
}
}

View File

@ -4,8 +4,14 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[FilePath(EcsConsts.FRAMEWORK_NAME + "/" + nameof(SettingsPrefs) + ".prefs", FilePathAttribute.Location.ProjectFolder)]
public class SettingsPrefs : ScriptableSingleton<SettingsPrefs>
internal enum ComponentColorMode
{
Generic = 0,
Auto = 1,
Rainbow = 2,
}
[FilePath(EcsConsts.AUTHOR + "/" + EcsConsts.FRAMEWORK_NAME + "/" + nameof(SettingsPrefs) + ".prefs", FilePathAttribute.Location.ProjectFolder)]
internal class SettingsPrefs : ScriptableSingleton<SettingsPrefs>
{
[SerializeField]
private bool _isShowInterfaces = false;
@ -52,6 +58,19 @@ namespace DCFApixels.DragonECS.Unity.Editors
Save(false);
}
}
[SerializeField]
private ComponentColorMode _componentColorMode = ComponentColorMode.Auto;
public ComponentColorMode ComponentColorMode
{
get => _componentColorMode;
set
{
_componentColorMode = value;
Save(false);
}
}
}
}
#endif

View File

@ -15,7 +15,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
bool isAlive = Target.Entity.TryUnpackForUnityEditor(out int id, out short gen, out short worldID, out EcsWorld world);
using (new EditorGUI.DisabledScope(!isAlive))
{
if (GUILayout.Button("Delete Entity"))
if (GUILayout.Button("Delete Entity", GUILayout.Height(36f)))
{
world.DelEntity(id);
}

View File

@ -0,0 +1,65 @@
using System;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace DCFApixels.DragonECS
{
[Serializable]
public struct ComponentTemplateProperty : IEquatable<ComponentTemplateProperty>
{
[SerializeReference]
private IComponentTemplate _template;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ComponentTemplateProperty(IComponentTemplate template)
{
_template = template;
}
public IComponentTemplate Template
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _template; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set { _template = value; }
}
public Type Type
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _template.Type; }
}
public bool IsNull
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _template == null; }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Apply(short worldID, int entityID) { _template.Apply(worldID, entityID); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public object GetRaw() { return _template.GetRaw(); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void OnGizmos(Transform transform, IComponentTemplate.GizmosMode mode) { _template.OnGizmos(transform, mode); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void OnValidate(UnityEngine.Object obj) { _template.OnValidate(obj); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetRaw(object raw) { _template.SetRaw(raw); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(ComponentTemplateProperty other) { return _template == other._template; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode() { return _template.GetHashCode(); }
public override bool Equals(object obj) { return obj is ComponentTemplateProperty other && Equals(other); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(ComponentTemplateProperty a, ComponentTemplateProperty b) { return a._template == b._template; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(ComponentTemplateProperty a, ComponentTemplateProperty b) { return a._template != b._template; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(ComponentTemplateProperty a, Null? b) { return a.IsNull; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Null? a, ComponentTemplateProperty b) { return b.IsNull; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(ComponentTemplateProperty a, Null? b) { return !a.IsNull; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Null? a, ComponentTemplateProperty b) { return !b.IsNull; }
public readonly struct Null { }
}
public sealed class ComponentTemplateReferenceAttribute : PropertyAttribute { }
}

View File

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

View File

@ -0,0 +1,253 @@
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomPropertyDrawer(typeof(ComponentTemplateProperty), true)]
internal class ComponentTemplatePropertyDrawer : PropertyDrawer
{
private ComponentTemplateReferenceDrawer _drawer = new ComponentTemplateReferenceDrawer();
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
property.Next(true);
return _drawer.GetPropertyHeight(property, label);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
property.Next(true);
_drawer.OnGUI(position, property, label);
}
}
[CustomPropertyDrawer(typeof(ComponentTemplateReferenceAttribute), true)]
internal class ComponentTemplateReferenceDrawer : PropertyDrawer
{
private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
private float Padding => EditorGUIUtility.standardVerticalSpacing;
private float SingleLineWithPadding => EditorGUIUtility.singleLineHeight + Padding * 4f;
private const float DamagedComponentHeight = 18f * 2f;
private static bool _isInit;
private static GenericMenu _genericMenu;
#region Init
private static void Init()
{
if (_genericMenu == null) { _isInit = false; }
if (_isInit) { return; }
_genericMenu = new GenericMenu();
var componentTemplateDummies = ComponentTemplateTypeCache.Dummies;
foreach (var dummy in componentTemplateDummies)
{
if (dummy.Type.GetCustomAttribute<SerializableAttribute>() == null)
{
Debug.LogWarning($"Type {dummy.Type.Name} does not have the [Serializable] attribute");
continue;
}
ITypeMeta meta = dummy is ITypeMeta metaOverride ? metaOverride : dummy.Type.ToMeta();
string name = meta.Name;
string description = meta.Description.Text;
MetaGroup group = meta.Group;
if (group.Name.Length > 0)
{
name = group.Name + name;
}
if (string.IsNullOrEmpty(description) == false)
{
name = $"{name} [i]";
}
_genericMenu.AddItem(new GUIContent(name, description), false, SelectComponent, dummy);
}
_isInit = true;
}
[ThreadStatic]
private static SerializedProperty currentProperty;
private static void SelectComponent(object dummy)
{
currentProperty.managedReferenceValue = ((IComponentTemplate)dummy).Clone();
currentProperty.isExpanded = false;
currentProperty.serializedObject.ApplyModifiedProperties();
}
#endregion
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
IComponentTemplate template = property.managedReferenceValue as IComponentTemplate;
if (template == null || property.managedReferenceValue == null)
{
return EditorGUIUtility.singleLineHeight + Padding * 2f;
}
try
{
ComponentTemplateBase customTemplate = property.managedReferenceValue as ComponentTemplateBase;
if (customTemplate != null)
{
property = property.FindPropertyRelative("component");
}
}
catch (Exception)
{
property = null;
}
if (property == null)
{
return DamagedComponentHeight;
}
int propCount = EcsGUI.GetChildPropertiesCount(property);
return (propCount <= 0 ? EditorGUIUtility.singleLineHeight : EditorGUI.GetPropertyHeight(property, label)) + Padding * 4f;
}
public override void OnGUI(Rect position, SerializedProperty componentRefProp, GUIContent label)
{
Init();
var counter = componentRefProp.Copy();
int positionCountr = int.MaxValue;
while (counter.NextVisible(false))
{
positionCountr--;
}
IComponentTemplate template = componentRefProp.managedReferenceValue as IComponentTemplate;
if (template == null || componentRefProp.managedReferenceValue == null)
{
DrawSelectionPopup(position, componentRefProp, label);
return;
}
Type componentType;
SerializedProperty componentProperty = componentRefProp;
try
{
ComponentTemplateBase customTemplate = componentProperty.managedReferenceValue as ComponentTemplateBase;
if (customTemplate != null)
{
componentProperty = componentRefProp.FindPropertyRelative("component");
componentType = customTemplate.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType;
}
else
{
componentType = componentProperty.managedReferenceValue.GetType();
}
if (componentType == null || componentProperty == null)
{
throw new NullReferenceException();
}
}
catch (Exception e)
{
Debug.LogException(e, componentRefProp.serializedObject.targetObject);
DrawDamagedComponent(position, "Damaged component template.");
return;
}
//сюда попадают уже валидные компоненты
ITypeMeta meta = template is ITypeMeta metaOverride ? metaOverride : template.Type.ToMeta();
string name = meta.Name;
string description = meta.Description.Text;
int propCount = EcsGUI.GetChildPropertiesCount(componentProperty);
Color panelColor = EcsGUI.SelectPanelColor(meta, positionCountr, -1).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
Color alphaPanelColor = panelColor;
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
EditorGUI.BeginChangeCheck();
EditorGUI.DrawRect(position, alphaPanelColor);
Rect paddingPosition = RectUtility.AddPadding(position, Padding * 2f);
#region Draw Component Block
Rect removeButtonRect = position;
removeButtonRect.center -= new Vector2(0, removeButtonRect.height);
removeButtonRect.yMin = removeButtonRect.yMax;
removeButtonRect.yMax += HeadIconsRect.height;
removeButtonRect.xMin = removeButtonRect.xMax - HeadIconsRect.width;
removeButtonRect.center += Vector2.up * Padding * 1f;
bool isRemoveComponent = EcsGUI.CloseButton(removeButtonRect);
if (propCount <= 0)
{
EcsGUI.DrawEmptyComponentProperty(paddingPosition, componentRefProp, label, false);
}
else
{
if (componentProperty.propertyType == SerializedPropertyType.Generic)
{
EditorGUI.PropertyField(paddingPosition, componentProperty, label, true);
}
else
{
Rect r = RectUtility.AddPadding(paddingPosition, 0, 20f, 0, 0);
EditorGUI.PropertyField(r, componentProperty, label, true);
}
}
if (string.IsNullOrEmpty(label.text))
{
EditorGUI.indentLevel++;
EditorGUI.PrefixLabel(position.AddPadding(0, 0, 0, position.height - SingleLineWithPadding), UnityEditorUtility.GetLabel(name));
EditorGUI.indentLevel--;
}
else
{
GUI.Label(position.AddPadding(EditorGUIUtility.labelWidth, 0, 0, position.height - SingleLineWithPadding), name);
}
if (isRemoveComponent)
{
componentRefProp.managedReferenceValue = null;
}
if (string.IsNullOrEmpty(description) == false)
{
Rect tooltipIconRect = HeadIconsRect;
tooltipIconRect.center = removeButtonRect.center;
tooltipIconRect.center -= Vector2.right * tooltipIconRect.width;
EcsGUI.DescriptionIcon(tooltipIconRect, description);
}
#endregion
if (EditorGUI.EndChangeCheck())
{
componentProperty.serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
}
}
private void DrawSelectionPopup(Rect position, SerializedProperty componentRefProp, GUIContent label)
{
EditorGUI.LabelField(position, label);
Rect buttonRect = RectUtility.AddPadding(position, EditorGUIUtility.labelWidth, 0f, 0f, 0f);
if (GUI.Button(buttonRect, "Select"))
{
currentProperty = componentRefProp;
_genericMenu.ShowAsContext();
}
}
private void DrawDamagedComponent(Rect position, string message)
{
EditorGUI.HelpBox(position, message, MessageType.Warning);
}
}
}
#endif

View File

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

View File

@ -9,39 +9,33 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
internal abstract class EntityTemplateEditorBase : Editor
{
private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 19f, 19f);
private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 19f, 19f);
private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
private GUIStyle _removeButtonStyle;
private GenericMenu _genericMenu;
private bool _isInit = false;
private static ComponentColorMode AutoColorMode
{
get { return SettingsPrefs.instance.ComponentColorMode; }
set { SettingsPrefs.instance.ComponentColorMode = value; }
}
#region Init
private void Init()
{
if (_genericMenu == null) { _isInit = false; }
if (_isInit) { return; }
var tmpstylebase = UnityEditorUtility.GetStyle(new Color(0.9f, 0f, 0.22f), 0.5f);
var tmpStyle = UnityEditorUtility.GetStyle(new Color(1f, 0.5f, 0.7f), 0.5f);
_removeButtonStyle = new GUIStyle(EditorStyles.linkLabel);
_removeButtonStyle.alignment = TextAnchor.MiddleCenter;
_removeButtonStyle.normal = tmpstylebase.normal;
_removeButtonStyle.hover = tmpStyle.normal;
_removeButtonStyle.active = tmpStyle.normal;
_removeButtonStyle.focused = tmpStyle.normal;
_removeButtonStyle.padding = new RectOffset(0, 0, 0, 0);
_removeButtonStyle.margin = new RectOffset(0, 0, 0, 0);
_removeButtonStyle.border = new RectOffset(0, 0, 0, 0);
_genericMenu = new GenericMenu();
var componentTemplateDummies = ComponentTemplateTypeCache.Dummies;
foreach (var dummy in componentTemplateDummies)
{
if (dummy.Type.GetCustomAttribute<SerializableAttribute>() == null)
{
Debug.LogWarning($"Type {dummy.Type.Name} does not have the [Serializable] attribute");
continue;
}
ITypeMeta meta = dummy is ITypeMeta metaOverride ? metaOverride : dummy.Type.ToMeta();
string name = meta.Name;
string description = meta.Description.Text;
@ -112,7 +106,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
GUILayout.Label("", GUILayout.Height(0), GUILayout.ExpandWidth(true));
for (int i = 0; i < componentsProp.arraySize; i++)
{
DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i);
DrawComponentData(componentsProp.GetArrayElementAtIndex(i), componentsProp.arraySize, i);
}
GUILayout.EndVertical();
}
@ -132,37 +126,56 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
}
private void DrawComponentData(SerializedProperty componentRefProp, int index)
private void DrawComponentData(SerializedProperty componentRefProp, int total, int index)
{
IComponentTemplate template = componentRefProp.managedReferenceValue as IComponentTemplate;
if (template == null || componentRefProp.managedReferenceValue == null)
{
DrawDamagedComponent(componentRefProp, index);
DrawDamagedComponent_Replaced(componentRefProp, index);
return;
}
Type componentType;
SerializedProperty componentProperty = componentRefProp;
try
{
ComponentTemplateBase customTemplate = componentProperty.managedReferenceValue as ComponentTemplateBase;
if (customTemplate != null)
{
componentProperty = componentRefProp.FindPropertyRelative("component");
componentType = customTemplate.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType;
}
else
{
componentType = componentProperty.managedReferenceValue.GetType();
}
if (componentType == null || componentProperty == null)
{
throw new NullReferenceException();
}
}
catch (Exception e)
{
Debug.LogException(e, serializedObject.targetObject);
DrawDamagedComponent(index, "Damaged component template.");
return;
}
Type componentType;
SerializedProperty componentProperty = componentRefProp;
ComponentTemplateBase customInitializer = componentProperty.managedReferenceValue as ComponentTemplateBase;
if (customInitializer != null)
{
componentProperty = componentRefProp.FindPropertyRelative("component");
componentType = customInitializer.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType;
}
else
{
componentType = componentProperty.managedReferenceValue.GetType(); ;
}
//сюда попадают уже валидные компоненты
ITypeMeta meta = template is ITypeMeta metaOverride ? metaOverride : template.Type.ToMeta();
string name = meta.Name;
string description = meta.Description.Text;
Color panelColor = meta.Color.ToUnityColor().Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
//GUIContent label = new GUIContent(name);
bool isEmpty = componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0;
int propCount = EcsGUI.GetChildPropertiesCount(componentProperty, componentType, out bool isEmpty);
float padding = EditorGUIUtility.standardVerticalSpacing;
Color panelColor = EcsGUI.SelectPanelColor(meta, index, total).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
Color alphaPanelColor = panelColor;
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
@ -171,26 +184,17 @@ namespace DCFApixels.DragonECS.Unity.Editors
EditorGUI.BeginChangeCheck();
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(alphaPanelColor));
#region Draw Component Block
bool isRemoveComponent = false;
removeButtonRect.yMin = removeButtonRect.yMax;
removeButtonRect.yMax += RemoveButtonRect.height;
removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width;
removeButtonRect.yMax += HeadIconsRect.height;
removeButtonRect.xMin = removeButtonRect.xMax - HeadIconsRect.width;
removeButtonRect.center += Vector2.up * padding * 2f;
if (EcsGUI.CloseButton(removeButtonRect))
{
isRemoveComponent = true;
}
bool isRemoveComponent = EcsGUI.CloseButton(removeButtonRect);
if (isEmpty)
if (propCount <= 0)
{
GUIContent label = UnityEditorUtility.GetLabel(name);
GUILayout.Label(label);
EditorGUI.BeginProperty(GUILayoutUtility.GetLastRect(), label, componentRefProp);
EditorGUI.EndProperty();
EcsGUI.Layout.DrawEmptyComponentProperty(componentRefProp, name, isEmpty);
}
else
{
@ -211,7 +215,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
if (string.IsNullOrEmpty(description) == false)
{
Rect tooltipIconRect = TooltipIconRect;
Rect tooltipIconRect = HeadIconsRect;
tooltipIconRect.center = removeButtonRect.center;
tooltipIconRect.center -= Vector2.right * tooltipIconRect.width;
EcsGUI.DescriptionIcon(tooltipIconRect, description);
@ -226,19 +230,28 @@ namespace DCFApixels.DragonECS.Unity.Editors
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
}
}
private void DrawDamagedComponent(SerializedProperty componentRefProp, int index)
private void DrawDamagedComponent_Replaced(SerializedProperty componentRefProp, int index)
{
DrawDamagedComponent(index, $"Damaged component template. If the problem occurred after renaming a component or initializer. use MovedFromAttrubute");
}
private void DrawDamagedComponent(int index, string message)
{
Rect removeButtonRect = GUILayoutUtility.GetLastRect();
GUILayout.BeginHorizontal();
EditorGUILayout.HelpBox($"Damaged component. If the problem occurred after renaming a component or initializer. use MovedFromAttrubute", MessageType.Warning);
float padding = EditorGUIUtility.standardVerticalSpacing;
Rect lastrect = GUILayoutUtility.GetLastRect();
Rect removeButtonRect = RemoveButtonRect;
removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f);
removeButtonRect.yMin = removeButtonRect.yMax;
removeButtonRect.yMax += HeadIconsRect.height;
removeButtonRect.xMin = removeButtonRect.xMax - HeadIconsRect.width;
removeButtonRect.center += Vector2.up * padding * 2f;
GUILayout.Label("", GUILayout.Width(removeButtonRect.width));
if (GUI.Button(removeButtonRect, "x", _removeButtonStyle))
bool isRemoveComponent = EcsGUI.CloseButton(removeButtonRect);
EditorGUILayout.HelpBox(message, MessageType.Warning);
if (isRemoveComponent)
{
OnRemoveComponentAt(index);
}

View File

@ -57,12 +57,12 @@ namespace DCFApixels.DragonECS
protected T component;
#region Properties
public override Type Type { get { return typeof(T); } }
public sealed override Type Type { get { return typeof(T); } }
public override string Name { get { return Meta.Name; } }
public override MetaColor Color { get { return Meta.Color; } }
public override MetaGroup Group { get { return Meta.Group; } }
public override MetaDescription Description { get { return Meta.Description; } }
public override IReadOnlyCollection<string> Tags { get { return Meta.Tags; } }
public override MetaColor Color { get { return Meta.Color; } }
#endregion
#region Methods
@ -129,7 +129,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
Type interfaceType = typeof(IComponentTemplate);
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var targetTypes = assembly.GetTypes().Where(type => !type.IsGenericType && !(type.IsAbstract || type.IsInterface) && type.GetCustomAttribute<SerializableAttribute>() != null);
var targetTypes = assembly.GetTypes().Where(type => !type.IsGenericType && !(type.IsAbstract || type.IsInterface) /*&& type.GetCustomAttribute<SerializableAttribute>() != null*/);
types.AddRange(targetTypes.Where(type => interfaceType.IsAssignableFrom(type)));

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -3,10 +3,10 @@ guid: 8f9fb2a8877577940971d81a98aeaaaa
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
@ -20,12 +20,11 @@ TextureImporter:
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
@ -52,7 +51,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
@ -64,20 +63,17 @@ TextureImporter:
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
resizeAlgorithm: 1
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
@ -90,7 +86,18 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
@ -107,8 +114,9 @@ TextureImporter:
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
src/Icons/AutosetIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -3,10 +3,10 @@ guid: d01e651682f48b548b597714f47e14b9
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
@ -20,12 +20,11 @@ TextureImporter:
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
@ -43,7 +42,7 @@ TextureImporter:
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
@ -52,7 +51,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
@ -64,20 +63,17 @@ TextureImporter:
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
resizeAlgorithm: 1
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
@ -90,7 +86,18 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
@ -99,7 +106,7 @@ TextureImporter:
outline: []
physicsShape: []
bones: []
spriteID:
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
@ -107,8 +114,9 @@ TextureImporter:
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

Before

Width:  |  Height:  |  Size: 379 B

After

Width:  |  Height:  |  Size: 379 B

View File

@ -3,10 +3,10 @@ guid: 8a708e50662813d4a99c107e6431a60b
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
@ -20,12 +20,11 @@ TextureImporter:
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
@ -52,7 +51,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
@ -64,20 +63,17 @@ TextureImporter:
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
resizeAlgorithm: 1
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
@ -90,7 +86,18 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
@ -107,8 +114,9 @@ TextureImporter:
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -3,10 +3,10 @@ guid: 6a1d402595b00c24db2ba647fed93a5c
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
@ -20,12 +20,11 @@ TextureImporter:
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
@ -52,7 +51,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
@ -64,20 +63,17 @@ TextureImporter:
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
resizeAlgorithm: 1
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
@ -90,7 +86,18 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
@ -107,8 +114,9 @@ TextureImporter:
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

Before

Width:  |  Height:  |  Size: 646 B

After

Width:  |  Height:  |  Size: 646 B

View File

@ -3,10 +3,10 @@ guid: e135cf23a5d53ce48a75e163b41e39d5
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
@ -20,12 +20,11 @@ TextureImporter:
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
@ -52,7 +51,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
@ -64,20 +63,17 @@ TextureImporter:
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
resizeAlgorithm: 1
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
@ -90,7 +86,18 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
@ -107,8 +114,9 @@ TextureImporter:
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
src/Icons/UnlinkIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 B

View File

@ -3,10 +3,10 @@ guid: 5baead89a941e034e9f44d63617d3246
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
@ -20,12 +20,11 @@ TextureImporter:
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
@ -52,7 +51,7 @@ TextureImporter:
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
@ -64,20 +63,17 @@ TextureImporter:
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
resizeAlgorithm: 1
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
@ -90,7 +86,18 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
@ -107,8 +114,9 @@ TextureImporter:
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 B

View File

@ -4,6 +4,8 @@ using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityObject = UnityEngine.Object;
using UnityComponent = UnityEngine.Component;
namespace DCFApixels.DragonECS.Unity.Editors
{
@ -26,6 +28,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
public struct ColorScope : IDisposable
{
private readonly Color _value;
public ColorScope(float r, float g, float b, float a = 1f) : this(new Color(r, g, b, a)) { }
public ColorScope(Color value)
{
_value = GUI.color;
@ -39,6 +42,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
public struct ContentColorScope : IDisposable
{
private readonly Color _value;
public ContentColorScope(float r, float g, float b, float a = 1f) : this(new Color(r, g, b, a)) { }
public ContentColorScope(Color value)
{
_value = GUI.contentColor;
@ -49,8 +53,17 @@ namespace DCFApixels.DragonECS.Unity.Editors
GUI.contentColor = _value;
}
}
private static ContentColorScope SetContentColor(Color value) => new ContentColorScope(value);
private static ContentColorScope SetContentColor(float r, float g, float b, float a = 1f) => new ContentColorScope(r, g, b, a);
private static ColorScope SetColor(Color value) => new ColorScope(value);
private static ColorScope SetColor(float r, float g, float b, float a = 1f) => new ColorScope(r, g, b, a);
private static EditorGUI.DisabledScope Enable => new EditorGUI.DisabledScope(false);
private static EditorGUI.DisabledScope Disable => new EditorGUI.DisabledScope(true);
private static EditorGUI.DisabledScope SetEnable(bool value) => new EditorGUI.DisabledScope(!value);
#endregion
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);
@ -60,6 +73,12 @@ namespace DCFApixels.DragonECS.Unity.Editors
public static float EntityBarHeight => EditorGUIUtility.singleLineHeight + 3f;
#region Properties
private static ComponentColorMode AutoColorMode
{
get { return SettingsPrefs.instance.ComponentColorMode; }
set { SettingsPrefs.instance.ComponentColorMode = value; }
}
private static bool IsShowHidden
{
get { return SettingsPrefs.instance.IsShowHidden; }
@ -70,7 +89,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
get { return SettingsPrefs.instance.IsShowRuntimeComponents; }
set { SettingsPrefs.instance.IsShowRuntimeComponents = value; }
}
#endregion
#region enums
public enum AddClearComponentButton : byte
{
None = 0,
@ -84,7 +105,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
Alive = 1 << 0,
Undefined = 1 << 1,
}
#endregion
#region HitTest
internal static bool HitTest(Rect rect)
{
return HitTest(rect, Event.current.mousePosition);
@ -102,11 +125,16 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
return point.x >= rect.xMin - (float)offset && point.x < rect.xMax + (float)offset && point.y >= rect.yMin - (float)offset && point.y < rect.yMax + (float)offset;
}
#endregion
#region small elems
public static void DrawIcon(Rect position, Texture icon, float iconPadding, string description)
{
GUI.Label(position, UnityEditorUtility.GetLabel(string.Empty, description));
GUI.DrawTexture(RectUtility.AddPadding(position, iconPadding), icon);
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);
}
}
public static (bool, bool) IconButtonGeneric(Rect position)
{
@ -163,8 +191,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
return IconButton(position, Icons.Instance.CloseIcon, 0f, "Delete Entity");
}
#endregion
#region entity bar
public static void EntityBarForAlive(Rect position, EntityStatus status, int id, short gen, short world)
{
EntityBar(position, status != EntityStatus.Alive, status, id, gen, world);
@ -242,7 +271,49 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
}
}
#endregion
internal static int GetChildPropertiesCount(SerializedProperty property, Type type, out bool isEmpty)
{
int result = GetChildPropertiesCount(property);
isEmpty = result <= 0 && type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0;
return result;
}
internal static int GetChildPropertiesCount(SerializedProperty property)
{
var propsCounter = property.Copy();
int lastDepth = propsCounter.depth;
bool next = propsCounter.Next(true) && lastDepth < propsCounter.depth;
int result = next ? -1 : 0;
while (next)
{
result++;
next = propsCounter.Next(false);
}
return result;
}
public static Color SelectPanelColor(ITypeMeta meta, int index, int total)
{
var trueMeta = meta.Type.ToMeta();
if (trueMeta.IsCustomColor || meta.Color != trueMeta.Color)
{
return meta.Color.ToUnityColor();
}
else
{
switch (AutoColorMode)
{
case ComponentColorMode.Auto:
return meta.Color.ToUnityColor().Desaturate(0.48f) / 1.18f; //.Desaturate(0.48f) / 1.18f;
case ComponentColorMode.Rainbow:
int localTotal = Mathf.Max(total, EscEditorConsts.AUTO_COLOR_RAINBOW_MIN_RANGE);
Color hsv = Color.HSVToRGB(1f / localTotal * (index % localTotal), 1, 1);
return hsv.Desaturate(0.48f) / 1.18f;
default:
return index % 2 == 0 ? new Color(0.40f, 0.40f, 0.40f) : new Color(0.54f, 0.54f, 0.54f);
}
}
}
public static bool AddComponentButtons(Rect position)
{
position = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f);
@ -264,8 +335,34 @@ namespace DCFApixels.DragonECS.Unity.Editors
return AddClearComponentButton.None;
}
public static void DrawEmptyComponentProperty(Rect position, SerializedProperty property, string name, bool isDisplayEmpty)
{
DrawEmptyComponentProperty(position, property, UnityEditorUtility.GetLabel(name), isDisplayEmpty);
}
public static void DrawEmptyComponentProperty(Rect position, SerializedProperty property, GUIContent label, bool isDisplayEmpty)
{
EditorGUI.LabelField(position, label);
if (isDisplayEmpty)
{
using (SetContentColor(1f, 1f, 1f, 0.4f))
{
GUI.Label(position.AddPadding(EditorGUIUtility.labelWidth, 0, 0, 0), "empty");
}
}
EditorGUI.BeginProperty(position, label, property);
EditorGUI.EndProperty();
}
public static class Layout
{
public static void DrawEmptyComponentProperty(SerializedProperty property, string name, bool isDisplayEmpty)
{
EcsGUI.DrawEmptyComponentProperty(GUILayoutUtility.GetRect(UnityEditorUtility.GetLabel(name), EditorStyles.label), property, name, isDisplayEmpty);
}
public static void DrawEmptyComponentProperty(SerializedProperty property, GUIContent label, bool isDisplayEmpty)
{
EcsGUI.DrawEmptyComponentProperty(GUILayoutUtility.GetRect(label, EditorStyles.label), property, label, isDisplayEmpty);
}
public static void DrawWorldBaseInfo(EcsWorld world)
{
bool isNull = world == null || world.IsDestroyed || world.id == 0;
@ -280,6 +377,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
EditorGUILayout.IntField("Leaked Entites", leakedEntitesCount, EditorStyles.boldLabel);
}
}
#region entity bar
public static void EntityBarForAlive(EntityStatus status, int id, short gen, short world)
{
float width = EditorGUIUtility.currentViewWidth;
@ -304,6 +403,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
float height = EntityBarHeight;
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height));
}
#endregion
public static bool AddComponentButtons()
{
@ -333,7 +433,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
if (isWithFoldout == false || IsShowRuntimeComponents)
{
if (EcsGUI.Layout.AddComponentButtons())
if (AddComponentButtons())
{
GenericMenu genericMenu = RuntimeComponentsUtility.GetAddComponentGenericMenu(world);
RuntimeComponentsUtility.CurrentEntityID = entityID;
@ -343,24 +443,25 @@ namespace DCFApixels.DragonECS.Unity.Editors
GUILayout.Box("", UnityEditorUtility.GetStyle(GUI.color, 0.16f), GUILayout.ExpandWidth(true));
IsShowHidden = EditorGUI.Toggle(GUILayoutUtility.GetLastRect(), "Show Hidden", IsShowHidden);
int i = 0;
foreach (var componentTypeID in componentTypeIDs)
{
var pool = world.GetPoolInstance(componentTypeID);
{
DrawRuntimeComponent(entityID, pool);
DrawRuntimeComponent(componentTypeIDs.Length, i++, entityID, pool);
}
}
}
GUILayout.EndVertical();
}
private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
private static void DrawRuntimeComponent(int entityID, IEcsPool pool)
private static void DrawRuntimeComponent(int total, int index, int entityID, IEcsPool pool)
{
var meta = pool.ComponentType.ToMeta();
if (meta.IsHidden == false || IsShowHidden)
{
object data = pool.GetRaw(entityID);
Color panelColor = meta.Color.ToUnityColor().Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
Color panelColor = SelectPanelColor(meta, index, total).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
float padding = EditorGUIUtility.standardVerticalSpacing;
Rect removeButtonRect = GUILayoutUtility.GetLastRect();
@ -373,7 +474,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
removeButtonRect.yMax += RemoveButtonRect.height;
removeButtonRect.xMin = removeButtonRect.xMax - RemoveButtonRect.width;
removeButtonRect.center += Vector2.up * padding * 2f;
if (EcsGUI.CloseButton(removeButtonRect))
if (CloseButton(removeButtonRect))
{
isRemoveComponent = true;
}
@ -398,7 +499,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
Rect tooltipIconRect = TooltipIconRect;
tooltipIconRect.center = removeButtonRect.center;
tooltipIconRect.center -= Vector2.right * tooltipIconRect.width;
EcsGUI.DescriptionIcon(tooltipIconRect, meta.Description.Text);
DescriptionIcon(tooltipIconRect, meta.Description.Text);
}
GUILayout.EndVertical();
@ -410,7 +511,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
outData = data;
Type type = data == null ? typeof(void) : data.GetType();
bool isUnityObject = typeof(UnityEngine.Object).IsAssignableFrom(fieldType);
bool isUnityObject = typeof(UnityObject).IsAssignableFrom(fieldType);
if (isUnityObject == false && data == null)
{
@ -447,12 +548,12 @@ namespace DCFApixels.DragonECS.Unity.Editors
if (isUnityObject)
{
EditorGUI.BeginChangeCheck();
var uobj = (UnityEngine.Object)data;
var uobj = (UnityObject)data;
bool isComponent = (typeof(UnityEngine.Component)).IsAssignableFrom(fieldType);
bool isComponent = typeof(UnityComponent).IsAssignableFrom(fieldType);
if (isComponent)
{
uobj = EditorGUILayout.ObjectField(label, uobj, typeof(UnityEngine.Object), true);
uobj = EditorGUILayout.ObjectField(label, uobj, typeof(UnityObject), true);
}
else
{

View File

@ -4,5 +4,6 @@
{
public const float COMPONENT_DRAWER_ALPHA = 0.26f;
public const float COMPONENT_DRAWER_DESATURATE = 0.86f;
public const int AUTO_COLOR_RAINBOW_MIN_RANGE = 7;
}
}

View File

@ -4,7 +4,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
{
internal static class RectUtility
{
public static (Rect, Rect) HorizontalSliceLerp(Rect rect, float t)
public static (Rect, Rect) HorizontalSliceLerp(in this Rect rect, float t)
{
Rect l = rect;
Rect r = rect;
@ -12,7 +12,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
r.xMin += rect.width * t;
return (l, r);
}
public static (Rect, Rect) HorizontalSliceLeft(Rect rect, float with)
public static (Rect, Rect) HorizontalSliceLeft(in this Rect rect, float with)
{
Rect l = rect;
Rect r = rect;
@ -20,7 +20,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
r.xMin += with;
return (l, r);
}
public static (Rect, Rect) HorizontalSliceRight(Rect rect, float with)
public static (Rect, Rect) HorizontalSliceRight(in this Rect rect, float with)
{
Rect l = rect;
Rect r = rect;
@ -29,7 +29,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
return (l, r);
}
public static (Rect, Rect) VerticalSliceTop(Rect rect, float height)
public static (Rect, Rect) VerticalSliceTop(in this Rect rect, float height)
{
Rect t = rect;
Rect b = rect;
@ -37,7 +37,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
b.yMin += height;
return (t, b);
}
public static (Rect, Rect) VerticalSliceBottom(Rect rect, float height)
public static (Rect, Rect) VerticalSliceBottom(in this Rect rect, float height)
{
Rect t = rect;
Rect b = rect;
@ -46,28 +46,30 @@ namespace DCFApixels.DragonECS.Unity.Internal
return (t, b);
}
public static Rect AddPadding(Rect rect, float verticalHorizontal)
public static Rect AddPadding(in this Rect rect, float verticalHorizontal)
{
return AddPadding(rect, verticalHorizontal, verticalHorizontal, verticalHorizontal, verticalHorizontal);
}
public static Rect AddPadding(Rect rect, float horizontal, float vertical)
public static Rect AddPadding(in this Rect rect, float horizontal, float vertical)
{
return AddPadding(rect, horizontal, horizontal, vertical, vertical);
}
public static Rect AddPadding(Rect rect, float left, float right, float top, float bottom)
public static Rect AddPadding(in this Rect rect, float left, float right, float top, float bottom)
{
rect.xMin += left;
rect.xMax -= right;
rect.yMin += top;
rect.yMax -= bottom;
Rect result = rect;
result.xMin += left;
result.xMax -= right;
result.yMin += top;
result.yMax -= bottom;
return result;
}
public static Rect Move(in this Rect rect, Vector2 addVector)
{
Rect result = rect;
result.center += addVector;
return rect;
}
public static Rect Move(Rect rect, Vector2 addVector)
{
rect.center += addVector;
return rect;
}
public static Rect Move(Rect rect, float addX, float addY)
public static Rect Move(in this Rect rect, float addX, float addY)
{
return Move(rect, new Vector2(addX, addY));
}