diff --git a/Plugins/RuntimeInspector/Scripts/RuntimeInspector/Fields/ArrayField.cs b/Plugins/RuntimeInspector/Scripts/RuntimeInspector/Fields/ArrayField.cs index 8d4a7cd..c30b946 100644 --- a/Plugins/RuntimeInspector/Scripts/RuntimeInspector/Fields/ArrayField.cs +++ b/Plugins/RuntimeInspector/Scripts/RuntimeInspector/Fields/ArrayField.cs @@ -140,7 +140,13 @@ protected override void GenerateElements() if( i < elementsExpandedStates.Count && elementsExpandedStates[i] && elementDrawer is ExpandableInspectorField ) ( (ExpandableInspectorField) elementDrawer ).IsExpanded = true; - elementDrawer.NameRaw = Inspector.ArrayIndicesStartAtOne ? ( ( i + 1 ) + ":" ) : ( i + ":" ); + string nameRaw = Inspector.ArrayIndicesStartAtOne ? ((i + 1) + ": ") : (i + ": "); + + object currentListObject = array.GetValue(i); + if (currentListObject != null) + nameRaw += GetArrayElementPreviewText(currentListObject); + + elementDrawer.NameRaw = nameRaw; elements.Add( elementDrawer ); } } @@ -152,10 +158,15 @@ protected override void GenerateElements() InspectorField elementDrawer = Inspector.CreateDrawerForType( elementType, drawArea, Depth + 1 ); if( elementDrawer == null ) break; - - int j = i; - string variableName = Inspector.ArrayIndicesStartAtOne ? ( ( i + 1 ) + ":" ) : ( i + ":" ); - elementDrawer.BindTo( elementType, variableName, () => ( (IList) Value )[j], ( value ) => + + string variableName = Inspector.ArrayIndicesStartAtOne ? ( ( i + 1 ) + ": " ) : ( i + ": " ); + + object currentListObject = list[i]; + if (currentListObject != null) + variableName += GetArrayElementPreviewText(currentListObject); + + int j = i; + elementDrawer.BindTo( elementType, variableName, () => ( (IList) Value )[j], ( value ) => { IList _list = (IList) Value; _list[j] = value; @@ -173,6 +184,38 @@ protected override void GenerateElements() elementsExpandedStates.Clear(); } + string GetArrayElementPreviewText(object obj) + { + var type = obj.GetType(); + + // skip types that are displayed inline + if (obj is string || obj is Object || type.IsPrimitive || type.IsEnum) + return null; + + // it must have a [Serializable] attribute - this way we also exclude Unity built-in serializable types + if (!type.IsSerializable) + return null; + + var variables = type.GetAllVariables(); + if (variables.Length == 0) + return null; + + const int maxStringLength = 30; + + var nameVariable = Array.Find(variables, v => + v.GetVariableType() == typeof(string) + && (v.Name.Equals("name", StringComparison.OrdinalIgnoreCase) || v.Name.Equals("m_name", StringComparison.OrdinalIgnoreCase))); + + if (nameVariable != null) + return nameVariable.GetVariableValue(obj)?.ToString()?.SubstringMax(maxStringLength); + + var firstVariable = variables[0]; + if (firstVariable.GetVariableType() == typeof(string)) + return firstVariable.GetVariableValue(obj)?.ToString()?.SubstringMax(maxStringLength); + + return null; + } + void IDropHandler.OnDrop( PointerEventData eventData ) { object[] assignableObjects = RuntimeInspectorUtils.GetAssignableObjectsFromDraggedReferenceItem( eventData, elementType ); diff --git a/Plugins/RuntimeInspector/Scripts/RuntimeInspector/Helpers/RuntimeInspectorUtils.cs b/Plugins/RuntimeInspector/Scripts/RuntimeInspector/Helpers/RuntimeInspectorUtils.cs index 7873dda..d94f930 100644 --- a/Plugins/RuntimeInspector/Scripts/RuntimeInspector/Helpers/RuntimeInspectorUtils.cs +++ b/Plugins/RuntimeInspector/Scripts/RuntimeInspector/Helpers/RuntimeInspectorUtils.cs @@ -149,6 +149,11 @@ public static string ToTitleCase( this string str ) return stringBuilder.ToString(); } + public static string SubstringMax(this string str, int count) + { + return str[..Math.Min(count, str.Length)]; + } + public static string GetNameWithType( this object obj, Type defaultType = null ) { if( obj.IsNull() ) @@ -699,7 +704,29 @@ public static ExposedMethod[] GetExposedMethods( this Type type ) return result; } - private static bool IsSerializable( this Type type ) + public static object GetVariableValue(this MemberInfo memberInfo, object obj) + { + if (memberInfo is PropertyInfo propertyInfo) + return propertyInfo.GetValue(obj); + + if (memberInfo is FieldInfo fieldInfo) + return fieldInfo.GetValue(obj); + + throw new ArgumentException("Invalid MemberInfo type"); + } + + public static Type GetVariableType(this MemberInfo memberInfo) + { + if (memberInfo is PropertyInfo propertyInfo) + return propertyInfo.PropertyType; + + if (memberInfo is FieldInfo fieldInfo) + return fieldInfo.FieldType; + + throw new ArgumentException("Invalid MemberInfo type"); + } + + private static bool IsSerializable( this Type type ) { #if UNITY_EDITOR || !NETFX_CORE if( type.IsPrimitive || commonSerializableTypes.Contains( type ) || type.IsEnum )