How should I tackle this problem: Property Drawer, Custom Editor or Attributes?

Hello Unity community, I’ve been using my own UI Animation system for long now, but I’ve never got to have an adequate inspector for it because I always get to a wall at some point when trying to:

The system is organized like this:
1- A Manager monobehaviour that controls the flow of the animations.
2- non-monobehaviour animations clases using inherintance. The base class is UIAnimation and then an example child class would be UIAnimation_Scale.
3- These UIAnimations can also have a base settings scriptable object, that when it is set, the rest of the parametters are ignored.
4- The Base Settings scriptable object, is just a holder for a UIAnimation class.
5- When declaring a public UIAnimation class, I need to be able to create/choose/add any of its child classes, not the parent class.

This is the BaseSettings class, that uses [SerializeReference] and a custom attribute from the package CareBoo to achieve it:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using CareBoo.Serially;

namespace UIAnimations
{
    [CreateAssetMenu(fileName = "New UIAnimation Base Settings", menuName = "UIAnimations/Base Settings")]
    public class UIAnimationBaseSettingData : ScriptableObject
    {
        [SerializeReference]
        [ShowSerializeReference]
        public UIAnimation baseUIAnimation;
    }
}

However, I wonder if there is a better way to do this. This is also the way I show the UIAnimation inside the inspector when inside another monobehaviour. It looks like this:

I would like to have a toggle/bool to show/hide some values to not make the inspector crowded with unnecessary info. such as the read only parametters, and some advanced options. (I tried with the “Show Advanced Options” bool as seen there, but is not functional).

On the other hand, I’ve tried some [ShowIf()] attributes that I saw around, but they do not work well when showing UnityEvents, which take a lof of the space.
Custom Editor doesn’t seem like a solution because I would have to write a new one with new code over and over again for every new monobehaviour that contains a UIAnimation. Property Drawer would work… but with these 2 attributes I wrote (and need) it does not work. Attributes are the only thing somehow working as I intend it to, but not completely, as the ShowIf[()] attributes that I saw posted around by different people don’t work with UnityEvents at all.

I’m really lost and I don’t know where I went wrong with this. Should I completely reestructure my code? How?
Is there some magic solution I’m missing?

I can’t find any information whatsoever for any of these problems and ChatGPT is completely clueless too. Please, help me!

I know you mention “for long” but nevertheless, animation is one of the strong points of UIElements. You can do animations simply via CSS (USS).

As to the Inspector, I can see two ways of improving this:

  • Group fields that belong together into serializable subclasses, and only have a single field of this class in the SO. This makes the class appear as a foldout in Inspector, and when expanded shows the fields of the class.
  • A custom editor window that works with a common object of yours (UIAnimationData). This gives you the option to leave only the most commonly edited fields in the Inspector, and to edit anything else you open a separate tool Window.

More about 2)

Users may dock the window and leave it open. This works well if the window code hooks into the Selection class’ events to update what the window shows, and if no valid selection then it will just show a “not available” label.

Also you can design that window rather quickly with UI Builder. This Asset Inspector I created a couple days ago is 100% handcrafted in UI Builder in negligible time compared to coded IMGUI craptastrophe:

Yes, there’s actually an image here but it’s cut off because my monitor real estate runs out past 1440 verticel pixels. :smile:

The foldouts here are Visual Elements, not what I described above with the nested serializable classes.

1 Like

Thank you very much for your insight. I didn’t know about UIElements animations, I will investigate more about it surely. On the other hand, I find the first solution really interesting, and feel a bit dumb I didn’t think of it earlier.
Solution 2 seems like the most profesional one, but even tho I’ve createe editor windows before, I’ve never created one for a specific class to edit a variable in a monobehaviour. i will read about it too.
Thank you for interest in helping! I will write here when I ger to try these options :slight_smile:

Worth noting that UnityEditor.Editors are for custom inspectors for UnityEngine.Objects. PropertyDrawers are for serializable C# classes or other non-Unity objects types that you serialise into Unity objects. Attributes are just meta data that other systems look for and react to. It’s not really an either-or situation, they are all used for different things.

So if you want to customise the display of a scriptable object, use an Editor. If it is a serialised C# classes or other specific type, use a property drawer.

Attributes are generally used with property drawers and decorator drawers to provide opt-in and configurable customised inspector drawing.

For this kind of thing an Editor Window might be more worthwhile. Or potentially investing in Odin Inspector which gives you pretty powerful attribute-based means of customising inspectors.

1 Like