I have some custom fields that were created and used before Unity 2023.2 and Unity 6, before the fancy UxmlElement attribute. So they have some custom properties that need to be carried over.
My fields are based on BaseField which now seems to want all the fields in a single property called value and use a UxmlAttributeConverter for serializing the value. That’s fine and neat. Not sure how that will work in the runtime since it’s an editor-only class, but sure.
But how do I transfer my old properties to this new singular value? Looking at Vector3Field I can see that it uses IUxmlSerializedDataCustomAttributeHandler for getting the old values and setting it to the new value property. That is so extremely useful! But of course, it’s internal. And not only is that interface internal, but the UxmlUtility class is also internal! That one I can recreate but come on! I can not stress enough how fed up I am with all the internal types in UI Toolkit.
Before I start ranting, let me ask the question clearly: How can I take my property1 and property2, combine them into the value property, and then remove the old properties?
<rant>
Let me preface this by saying that I make a lot of custom controls and obviously want them to look as native as possible to Unity fields. I’ve struggled my way through ImGUI in the past and I want to say that using UI Toolkit has been a joy. But it hasn’t. It gets a lot right, don’t get me wrong, but as soon as I want to make something look like it belongs, things get complicated. I’ve had to reinvent the wheel so many times and it’s exhausting.
Let’s say I want to make a composite field (a field with multiple inner fields, like a Vector3 field), I could use the publically available BaseCompositeField. It’s perfect! It does all the things I want and applies all the right styles! BUT NO! The DescribeFields method is internal for whatever reason so I can’t use it. Why? So now I’ve had to make my own composite field builder which is basically identical to the built-in one. If Unity changes something, I need to change mine and I don’t want to keep track of every single patch release, especially when this is for a package.
Now if I want to update my field properties from one Unity version to another I’m also stuck. See above issue because I can be bothered to repeat myself.
Some very useful events, like elementAdded and elementRemoved are also internal on VisualElement. Unless I’ve missed some super obvious event callback, you’d have to jerry-rig some event callback on geometry change just to listen if an element was added or removed. These events can be so useful when creating custom controls. I just wanted to add and remove styles when child elements were added ![]()
I’m sure there is more because I know I’ve been annoyed in the past when making controls, but I can’t remember anything else right now.
The versions in the past will be forever screwed due to this and all my packages will have to keep these workarounds that replicate internal methods, but in the future, please do better. My packages each have their own implementations of features that exist just an internal method away and I can’t keep up anymore to keep them all updated. I would use a shared library, but you can’t depend on git packages, which in itself is another annoying rant.
</rant>