Compare commits

..

No commits in common. "d21c65742b2e84d89a95a51f41703c1f4e003f28" and "14163956e02f6e00c348cfed66d8702c6b27b2ff" have entirely different histories.

3 changed files with 289 additions and 347 deletions

View File

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

View File

@ -15,8 +15,7 @@ namespace DCFApixels.DragonECS.Unity.Editors.X
{ {
internal class RuntimeComponentsDrawer internal class RuntimeComponentsDrawer
{ {
private const BindingFlags INSTANCE_FIELD_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetRuntimeComponentReflectionCache() private static void ResetRuntimeComponentReflectionCache()
{ {
@ -29,7 +28,6 @@ namespace DCFApixels.DragonECS.Unity.Editors.X
} }
private const int RuntimeComponentsMaxDepth = 2; private const int RuntimeComponentsMaxDepth = 2;
private const int RuntimeComponentsDepthRoot = -1; private const int RuntimeComponentsDepthRoot = -1;
private static RuntimeComponentsDrawer[] _drawers; private static RuntimeComponentsDrawer[] _drawers;
private static int _runtimeComponentsDepth = RuntimeComponentsDepthRoot; private static int _runtimeComponentsDepth = RuntimeComponentsDepthRoot;
static RuntimeComponentsDrawer() static RuntimeComponentsDrawer()
@ -65,11 +63,35 @@ namespace DCFApixels.DragonECS.Unity.Editors.X
internal class RuntimeComponentReflectionCache internal class RuntimeComponentReflectionCache
{ {
public readonly Type Type; public readonly Type Type;
public readonly bool IsUnityObjectType;
public readonly bool IsUnitySerializable;
public readonly bool IsCompositeType;
public readonly bool IsUnmanaged; public readonly bool IsUnmanaged;
public readonly DrawerType DrawerType;
public readonly bool IsLeaf;
public readonly LeafType LeafPropertyType;
public enum LeafType
{
NONE = 0,
Enum,
Bool,
String,
Float,
Double,
Byte,
SByte,
Short,
UShort,
Int,
UInt,
Long,
ULong,
}
public readonly FieldInfoData[] Fields; public readonly FieldInfoData[] Fields;
private RefEditorWrapper[] _wrappers = new RefEditorWrapper[RuntimeComponentsMaxDepth]; private RefEditorWrapper[] _wrappers = new RefEditorWrapper[2];
public RefEditorWrapper GetWrapper(int depth) public RefEditorWrapper GetWrapper(int depth)
{ {
return _wrappers[depth]; return _wrappers[depth];
@ -80,88 +102,87 @@ namespace DCFApixels.DragonECS.Unity.Editors.X
Type = type; Type = type;
ResetWrappers(); ResetWrappers();
IsUnmanaged = UnsafeUtility.IsUnmanaged(type); IsUnmanaged = UnsafeUtility.IsUnmanaged(type);
IsUnityObjectType = typeof(UnityObject).IsAssignableFrom(type);
bool isVoideType = type == typeof(void); LeafPropertyType = LeafType.NONE;
bool isUnityObjectType = typeof(UnityObject).IsAssignableFrom(type); IsLeaf = type.IsPrimitive || type == typeof(string) || type.IsEnum;
bool isLeaf = isUnityObjectType || type.IsPrimitive || type == typeof(string) || type.IsEnum;
DrawerType = DrawerType.UNDEFINED; if (IsLeaf)
if(type.IsArray || isVoideType)
{
DrawerType = DrawerType.Ignored;
}
if (DrawerType == DrawerType.UNDEFINED && isLeaf)
{ {
if (type.IsEnum) if (type.IsEnum)
{ {
DrawerType = type.HasAttribute<FlagsAttribute>() ? DrawerType.EnumFlags : DrawerType.Enum; LeafPropertyType = LeafType.Enum;
}
else if (isUnityObjectType)
{
DrawerType = DrawerType.UnityObject;
} }
else if (type == typeof(bool)) else if (type == typeof(bool))
{ {
DrawerType = DrawerType.Bool; LeafPropertyType = LeafType.Bool;
} }
else if (type == typeof(string)) else if (type == typeof(string))
{ {
DrawerType = DrawerType.String; LeafPropertyType = LeafType.String;
} }
else if (type == typeof(float)) else if (type == typeof(float))
{ {
DrawerType = DrawerType.Float; LeafPropertyType = LeafType.Float;
} }
else if (type == typeof(double)) else if (type == typeof(double))
{ {
DrawerType = DrawerType.Double; LeafPropertyType = LeafType.Double;
} }
else if (type == typeof(byte)) else if (type == typeof(byte))
{ {
DrawerType = DrawerType.Byte; LeafPropertyType = LeafType.Byte;
} }
else if (type == typeof(sbyte)) else if (type == typeof(sbyte))
{ {
DrawerType = DrawerType.SByte; LeafPropertyType = LeafType.SByte;
} }
else if (type == typeof(short)) else if (type == typeof(short))
{ {
DrawerType = DrawerType.Short; LeafPropertyType = LeafType.Short;
} }
else if (type == typeof(ushort)) else if (type == typeof(ushort))
{ {
DrawerType = DrawerType.UShort; LeafPropertyType = LeafType.UShort;
} }
else if (type == typeof(int)) else if (type == typeof(int))
{ {
DrawerType = DrawerType.Int; LeafPropertyType = LeafType.Int;
} }
else if (type == typeof(uint)) else if (type == typeof(uint))
{ {
DrawerType = DrawerType.UInt; LeafPropertyType = LeafType.UInt;
} }
else if (type == typeof(long)) else if (type == typeof(long))
{ {
DrawerType = DrawerType.Long; LeafPropertyType = LeafType.Long;
} }
else if (type == typeof(ulong)) else if (type == typeof(ulong))
{ {
DrawerType = DrawerType.ULong; LeafPropertyType = LeafType.ULong;
} }
} }
if (DrawerType == DrawerType.UNDEFINED)
{
DrawerType = type.IsGenericType ? DrawerType.UnityNotSerializableComposite : DrawerType.UnitySerializableComposite;
}
if (isVoideType) { return; } IsUnitySerializable =
IsUnityObjectType ||
//typeof(Array).IsAssignableFrom(type) ||
//(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) ||
//type.IsPrimitive ||
//type == typeof(string) ||
//type.IsEnum ||
(!type.IsGenericType && type.HasAttribute<System.SerializableAttribute>() && type.IsArray == false);
if (DrawerType == DrawerType.UnityNotSerializableComposite) IsCompositeType =
type.IsPrimitive == false &&
type.IsArray == false &&
type != typeof(string);
if (type == typeof(void)) { return; }
if (IsUnitySerializable == false)
{ {
var fieldInfos = type.GetFields(INSTANCE_FIELD_FLAGS); var fieldInfos = type.GetFields(fieldFlags);
Fields = new FieldInfoData[fieldInfos.Length]; Fields = new FieldInfoData[fieldInfos.Length];
for (int i = 0; i < fieldInfos.Length; i++) for (int i = 0; i < fieldInfos.Length; i++)
{ {
@ -183,7 +204,6 @@ namespace DCFApixels.DragonECS.Unity.Editors.X
public readonly bool IsUnityObjectField; public readonly bool IsUnityObjectField;
public readonly bool IsPassToUnitySerialize; public readonly bool IsPassToUnitySerialize;
public readonly RuntimeComponentReflectionCache ValueTypeReflectionCache; public readonly RuntimeComponentReflectionCache ValueTypeReflectionCache;
public FieldInfoData(FieldInfo fieldInfo) public FieldInfoData(FieldInfo fieldInfo)
{ {
FieldInfo = fieldInfo; FieldInfo = fieldInfo;
@ -428,301 +448,266 @@ namespace DCFApixels.DragonECS.Unity.Editors.X
#region draw data #region draw data
private bool DrawRuntimeData(ref RuntimeComponentReflectionCache.FieldInfoData fieldInfoData, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData, int depth) private bool DrawRuntimeData(ref RuntimeComponentReflectionCache.FieldInfoData fieldInfoData, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData, int depth)
{ {
const int DEPTH_MAX = 24; const int DEPTH_MAX = 64;
outData = data;
Type type = data == null ? typeof(void) : data.GetType();
using (EcsGUI.CheckChanged()) RuntimeComponentReflectionCache cache = fieldInfoData.GetReflectionCache(type);
bool isUnityObjectField = fieldInfoData.IsUnityObjectField;
if (isUnityObjectField == false && data == null)
{ {
EditorGUILayout.TextField(label, "Null");
return false;
}
if (depth >= DEPTH_MAX || cache == null)
{
EditorGUILayout.TextField(label, "error");
return false;
}
bool isUnityObjectType = cache.IsUnityObjectType;
outData = data; ref bool isExpanded = ref expandMatrix.Down();
object newData = data; bool changed = false;
Type type = data == null ? typeof(void) : data.GetType();
bool isUnityObjectField = fieldInfoData.IsUnityObjectField; if (cache.IsUnitySerializable == false && cache.IsCompositeType)
if (isUnityObjectField == false && data == null) {
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)
{ {
EditorGUILayout.TextField(label, "Null"); using (EcsGUI.UpIndentLevel())
return false; {
} for (int j = 0, jMax = cache.Fields.Length; j < jMax; j++)
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 = UnityEditorUtility.GetLabel2(cache.Type.FullName + " " + type.FullName);
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); var field = cache.Fields[j];
wrapper.data = data; if (DrawRuntimeData(ref field, UnityEditorUtility.GetLabel(field.UnityFormatName), expandMatrix, field.FieldInfo.GetValue(data), out object fieldData, depth + 1))
wrapper.SO.Update();
wrapper.IsExpanded = isExpanded;
EditorGUILayout.PropertyField(wrapper.Property, label, true);
if (EcsGUI.Changed)
{ {
wrapper.SO.ApplyModifiedProperties(); field.FieldInfo.SetValue(data, fieldData);
newData = wrapper.Data; outData = data;
childElementChanged = true; changed = true;
} }
isExpanded = wrapper.IsExpanded; }
}
}
}
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);
} }
break; outData = uobj;
case DrawerType.UnityNotSerializableComposite: changed = true;
}
}
else
{
EditorGUI.BeginChangeCheck();
RefEditorWrapper wrapper = cache.GetWrapper(_runtimeComponentsDepth);
wrapper.data = data;
GUILayout.Space(EcsGUI.Spacing); try
var foldoutStyle = EditorStyles.foldout; {
Rect rect = GUILayoutUtility.GetRect(label, foldoutStyle); if (fieldInfoData.IsPassToUnitySerialize)
//rect.xMin += EcsGUI.Indent;
isExpanded = EditorGUI.BeginFoldoutHeaderGroup(rect, isExpanded, label, foldoutStyle, null, null);
EditorGUILayout.EndFoldoutHeaderGroup();
if (isExpanded)
{ {
using (EcsGUI.UpIndentLevel()) if (cache.IsCompositeType)
{ {
for (int j = 0, jMax = cache.Fields.Length; j < jMax; j++) wrapper.SO.Update();
wrapper.IsExpanded = isExpanded;
EditorGUILayout.PropertyField(wrapper.Property, label, true);
if (GUI.changed)
{ {
var field = cache.Fields[j]; wrapper.SO.ApplyModifiedProperties();
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;
}
} }
} }
} else if (cache.IsLeaf)
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) var eventType = Event.current.type;
switch (cache.LeafPropertyType)
{ {
newuobj = go.GetComponent(fieldInfoData.FieldType); //case RuntimeComponentReflectionCache.LeafType.Enum:
// break;
case RuntimeComponentReflectionCache.LeafType.Bool:
if (eventType != EventType.Layout)
{
wrapper.data = EditorGUILayout.Toggle(label, (bool)data);
}
else
{
EditorGUILayout.Toggle(label, default);
}
break;
case RuntimeComponentReflectionCache.LeafType.String:
if (eventType != EventType.Layout)
{
wrapper.data = EditorGUILayout.TextField(label, (string)data);
}
else
{
EditorGUILayout.TextField(label, default);
}
break;
case RuntimeComponentReflectionCache.LeafType.Float:
if (eventType != EventType.Layout)
{
wrapper.data = EditorGUILayout.FloatField(label, (float)data);
}
else
{
EditorGUILayout.FloatField(label, default);
}
break;
case RuntimeComponentReflectionCache.LeafType.Double:
if (eventType != EventType.Layout)
{
wrapper.data = EditorGUILayout.DoubleField(label, (double)data);
}
else
{
EditorGUILayout.DoubleField(label, default);
}
break;
case RuntimeComponentReflectionCache.LeafType.Byte:
if (eventType != EventType.Layout)
{
wrapper.data = (byte)EditorGUILayout.IntField(label, (byte)data);
}
else
{
EditorGUILayout.IntField(label, default);
}
break;
case RuntimeComponentReflectionCache.LeafType.SByte:
if (eventType != EventType.Layout)
{
wrapper.data = (sbyte)EditorGUILayout.IntField(label, (sbyte)data);
}
else
{
EditorGUILayout.IntField(label, default);
}
break;
case RuntimeComponentReflectionCache.LeafType.Short:
if (eventType != EventType.Layout)
{
wrapper.data = (short)EditorGUILayout.IntField(label, (short)data);
}
else
{
EditorGUILayout.IntField(label, default);
}
break;
case RuntimeComponentReflectionCache.LeafType.UShort:
if (eventType != EventType.Layout)
{
wrapper.data = (ushort)EditorGUILayout.IntField(label, (ushort)data);
}
else
{
EditorGUILayout.IntField(label, default);
}
break;
case RuntimeComponentReflectionCache.LeafType.Int:
if (eventType != EventType.Layout)
{
wrapper.data = (int)EditorGUILayout.IntField(label, (int)data);
}
else
{
EditorGUILayout.IntField(label, default);
}
break;
case RuntimeComponentReflectionCache.LeafType.UInt:
if (eventType != EventType.Layout)
{
wrapper.data = (uint)EditorGUILayout.IntField(label, (int)(uint)data);
}
else
{
EditorGUILayout.IntField(label, default);
}
break;
case RuntimeComponentReflectionCache.LeafType.Long:
if (eventType != EventType.Layout)
{
wrapper.data = EditorGUILayout.LongField(label, (long)data);
}
else
{
EditorGUILayout.LongField(label, default);
}
break;
case RuntimeComponentReflectionCache.LeafType.ULong:
if (eventType != EventType.Layout)
{
wrapper.data = (ulong)EditorGUILayout.LongField(label, (long)(ulong)data);
}
else
{
EditorGUILayout.LongField(label, default);
}
break;
default:
EditorGUILayout.LabelField(label);
break;
} }
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 else
{ {
EditorGUILayout.EnumPopup(label, default); EditorGUILayout.LabelField(label);
} }
}
break; catch (ArgumentException)
case DrawerType.EnumFlags: {
if (Event.current.type != EventType.Repaint)
if (eventType != EventType.Layout)
{ {
var enumData = UnsafeUtility.As<object, Enum>(ref data); throw;
newData = EditorGUILayout.EnumFlagsField(label, enumData);
} }
else }
finally
{
if (EditorGUI.EndChangeCheck())
{ {
EditorGUILayout.EnumFlagsField(label, default); outData = wrapper.Data;
changed = true;
} }
isExpanded = wrapper.IsExpanded;
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; expandMatrix.Up();
return changed;
} }
#endregion #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 #endif

View File

@ -235,7 +235,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
//private static Type[] _noHiddenSerializableTypes; //private static Type[] _noHiddenSerializableTypes;
private static GUIContent _singletonIconContent = null; private static GUIContent _singletonIconContent = null;
private static GUIContent _singletonContent = null; private static GUIContent _singletonContent = null;
private static GUIContent _singleton2Content = null;
private static GUIStyle _inputFieldCenterAnhor = null; private static GUIStyle _inputFieldCenterAnhor = null;
private static Dictionary<Type, MonoScript> _scriptsAssets = new Dictionary<Type, MonoScript>(256); private static Dictionary<Type, MonoScript> _scriptsAssets = new Dictionary<Type, MonoScript>(256);
@ -441,17 +440,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
_singletonIconContent.tooltip = tooltip; _singletonIconContent.tooltip = tooltip;
return _singletonIconContent; 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 #endregion
#region GetDefaultStyle #region GetDefaultStyle
@ -529,37 +517,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
return result; return result;
} }
#endregion #endregion
//private static StructList<GUIContent> _stackLabels = new StructList<GUIContent>(4);
//public static StackTempLabelScope GetStackLabel(string text, string tooltip = null)
//{
// StackTempLabelScope result = default;
// if (_stackLabels.Count <= 0)
// {
// result = new StackTempLabelScope(new GUIContent());
// }
// else
// {
// var l = _stackLabels[_stackLabels.Count - 1];
// _stackLabels.RemoveAt(_stackLabels.Count - 1);
// result = new StackTempLabelScope(l);
// }
// result.Label.text = text;
// result.Label.tooltip = tooltip;
// return result;
//}
//private static void ReturnStackLabel(GUIContent label)
//{
// _stackLabels.Add(label);
//}
//public readonly struct StackTempLabelScope : IDisposable
//{
// public readonly GUIContent Label;
// public StackTempLabelScope(GUIContent label) { Label = label; }
// public void Dispose() { ReturnStackLabel(Label); }
// public static implicit operator GUIContent(StackTempLabelScope a) { return a.Label; }
//}
} }
internal static class RuntimeComponentsUtility internal static class RuntimeComponentsUtility