Auto populate default values for unity-serialized fields

This commit is contained in:
VladV 2023-03-07 11:29:33 +04:00
parent 726ee9cfbc
commit 31f9a27877
2 changed files with 62 additions and 3 deletions

View File

@ -18,6 +18,7 @@ namespace TriInspector
private readonly List<string> _extensionErrors = new List<string>();
private readonly MemberInfo _memberInfo;
private readonly List<Attribute> _attributes;
private readonly bool _isNonPolymorphicSerializedByUnity;
private TriPropertyDefinition _arrayElementDefinitionBackingField;
@ -73,6 +74,10 @@ namespace TriInspector
_valueGetter = valueGetter;
_valueSetter = valueSetter;
_isNonPolymorphicSerializedByUnity = memberInfo is FieldInfo fi &&
TriUnitySerializationUtilities.IsSerializableByUnity(fi) &&
fi.GetCustomAttribute<SerializeReference>() == null;
Order = order;
IsReadOnly = _valueSetter == null || Attributes.TryGet(out ReadOnlyAttribute _);
@ -143,7 +148,19 @@ namespace TriInspector
public object GetValue(TriProperty property, int targetIndex)
{
return _valueGetter(property, targetIndex);
var value = _valueGetter(property, targetIndex);
if (value == null && _isNonPolymorphicSerializedByUnity)
{
value = TriUnitySerializationUtilities.PopulateUnityDefaultValueForType(FieldType);
if (value != null)
{
_valueSetter?.Invoke(property, targetIndex, value);
}
}
return value;
}
public bool SetValue(TriProperty property, object value, int targetIndex, out object parentValue)

View File

@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
@ -23,13 +24,13 @@ namespace TriInspector.Utilities
if (fieldInfo.IsPublic || fieldInfo.GetCustomAttribute<SerializeField>() != null)
{
return IsTypeSerializable(fieldInfo.FieldType, allowCollections: true);
return IsTypeSerializable(fieldInfo.FieldType);
}
return false;
}
private static bool IsTypeSerializable(Type type, bool allowCollections)
public static bool IsTypeSerializable(Type type, bool allowCollections = true)
{
if (type == typeof(object))
{
@ -97,6 +98,11 @@ namespace TriInspector.Utilities
}
}
if (typeof(IEnumerable).IsAssignableFrom(type))
{
return false;
}
if (type.GetCustomAttribute<SerializableAttribute>() != null)
{
return true;
@ -106,5 +112,41 @@ namespace TriInspector.Utilities
return false;
}
internal static object PopulateUnityDefaultValueForType(Type type)
{
if (type == typeof(string))
{
return string.Empty;
}
if (typeof(Object).IsAssignableFrom(type))
{
return null;
}
if (type.IsEnum)
{
var values = Enum.GetValues(type);
return values.Length > 0 ? values.GetValue(0) : Enum.ToObject(type, 0);
}
if (type.IsValueType)
{
return Activator.CreateInstance(type);
}
if (type.IsArray && type.GetElementType() is var elementType && elementType != null)
{
return Array.CreateInstance(elementType, 0);
}
if (type.GetConstructor(Type.EmptyTypes) != null)
{
return Activator.CreateInstance(type);
}
return null;
}
}
}