NaughtyAttributes icon indicating copy to clipboard operation
NaughtyAttributes copied to clipboard

Applying NaughtyAttribute's meta attributes to non-Unity Object derived types

Open lukepaw opened this issue 3 years ago • 1 comments

This PR adds implementation that allows serializable types not derived from UnityEngine.Object to utilise NaughtyAttribute's customization.

The result is that any type attributed with [Serializable] (that Unity can handle) should support NaughtyAttributes customization on its fields. This includes any form of nesting (direct, or list).

This is limited to meta attributes only - because the method is invoked per serialized property, rather than the object itself.

Implementation details: Added a new property drawer type: NaughtyPropertyDrawer.
It is injected into Unity's internals, so it can used as the default/fallback property drawer for any properties not handled by another drawer.

The drawer implements two methods: GetPropertyHeight and OnGUI.
Both are implemented to take into account NaughtyAttribute's customization, followed by invocation of Unity's original logic.

The Unity's original logic is available through the internal UnityEditor.PropertyHandler type. An instance of PropertyHandler is resolved using the internal static method UnityEditor.ScriptAttributeUtility.GetHandler(ScriptableProperty).

All internals and injections are done in the type's static constructor, triggered by [InitializeOnLoad].
Method calls to Unity's internals are compiled.

Modified the NaughtyEditorGUI class:
The PropertyField_Implementation method has been made public, as it is used from within the NaughtyPropertyDrawer.OnGUI method.

I tested whether the implementation works as expected on the following Unity versions: 2021.2.0b1 2021.1.13f1 2020.3.13f1 2019.4.28f1

Notes An alternative approach would be to register such a custom drawer for every type in the AppDomain. From my tests - this does not work well with nested properties - which is what the 'fallback' drawer injection resolves. It also would cause UI lag when an inspector is drawn - due to the size of the drawer resolution dictionary - which is why I use a hack with custom comparer injected into the dictionary.

This is my first attempt at a contribution, so if this should be done differently, lemme know.

lukepaw avatar Jul 04 '21 07:07 lukepaw

This is what i need, thanks.

zzmingo avatar Sep 22 '21 13:09 zzmingo