codewriter-packages / Tri-Inspector

Free inspector attributes for Unity [Custom Editor, Custom Inspector, Inspector Attributes, Attribute Extensions]
MIT License
989 stars 48 forks source link

Default Values not used #175

Open spellfusion opened 1 month ago

spellfusion commented 1 month ago

Describe the bug I have a List and TableList of classes in a scriptable object and the default values of the class (ex. public float Volume = 1f;) is not being used. All values are 0.

Expected behavior When I add a new item to the list, it should have the default values as defined in the C# file.

Code Sample

[Serializable]
    [DeclareFoldoutGroup("Settings")]
    public class Sound : ConfigEntry
    {

        [Group("Settings")]
        [MinMaxSlider(0.1f, 3f)] public Vector2 Pitch = Vector2.one;

        [Group("Settings")]
        public float Volume = 1f;

        [Group("Settings")]
        public bool UseVolumeRange = false;

        [Group("Settings")]
        [MinMaxSlider(0.1f, 3f), TriInspector.ShowIf(nameof(UseVolumeRange))]
        public Vector2 VolumeRange = Vector2.one;

        [Group("Settings")]
        public float MinDistance = 1f;
        [Group("Settings")]
        public float MaxDistance = 300f;
    }

Screenshots image

Desktop: Windows 11 Unity version: 6000.0.22f1 Tri Inspector version: 1.14.1

spellfusion commented 1 month ago

Fixed it with the following:

SoundConfig.cs

[ListDrawerSettings(DefaultValueType = typeof(Config.Sound))]
public List<Config.Sound> Sounds = new List<Config.Sound>();

ListDrawerSettings.cs

public class ListDrawerSettingsAttribute : Attribute
{
    public bool Draggable { get; set; } = true;
    public bool HideAddButton { get; set; }
    public bool HideRemoveButton { get; set; }
    public bool AlwaysExpanded { get; set; }
    public bool ShowElementLabels { get; set; }
    public Type DefaultValueType { get; set; } = null;
}

TriListElement.cs

public class TriListElement : TriElement
{
//...
private Type _fixDefaultValueType = null;
//...
  public TriListElement(TriProperty property)
  {
    // ...
    _fixDefaultValueType = settings?.DefaultValueType ?? null;
  }
  //...
  private void AddElementCallback(ReorderableList reorderableList, Object addedReferenceValue)
  {
    if (_property.TryGetSerializedProperty(out _))
    {
      ReorderableListProxy.DoAddButton(reorderableList, addedReferenceValue);

      if (_fixDefaultValueType != null)
      {
        reorderableList.serializedProperty.GetArrayElementAtIndex(reorderableList.index).boxedValue = Activator.CreateInstance(_fixDefaultValueType);
      }

      _property.NotifyValueChanged();
      return;
    }
 //...
 }
spellfusion commented 1 month ago

Found out that the Type is in _property.ArrayElementType, so I changed it to a boolean in the List settings

if (_fixDefaultValue)
{
    reorderableList.serializedProperty.GetArrayElementAtIndex(reorderableList.index).boxedValue = Activator.CreateInstance(_property.ArrayElementType);
}
[ListDrawerSettings(FixDefaultValue = true)]