Need ability to link a VisualTreeAsset to a (custom) VisualElement

I had made a custom element. It’s working great, however I wanted to be able to use and switch a VisualTreeAsset for generating it’s contents.

Currently the custom element creates a static set elements, though they are serializedProprertys so they can be customised by specifying property drawers, but that can be a pain, and not always straight forward. (i.e. property drawer from a string, you need to create your own class inherited from string and use the as the type argument for the CustomerPropertyDrawer attr).

I would really like to add a property to my VisualElement that links the VisualTreeAsset. The only way I see I can do this is to use a string property to provide path, store the asset GUID, and load the VisualTreeAsset from that when required.

Either that, or be able to get the GUID from the TemplateContainer inside the element, though I don’t even know how to get the internal TemplateContainers, iterating children doesn’t seem to iterate over them. I did try iterating CreationContext.templateDependencies, but there seems to be no way to find out which one is in what elements.

I simply want to be able to drop in a VisualTreeAsset under a node, detect that node and instantiate new ones when required. Or add the VisualTreeAsset as a property to my custom VisualElement so I can instantiate using that.

On another thought, Custom Inspectors for the UIBuilder would also be a way I could do this. (Add a object field, but set the underlying value to the GUID of the object). Probably the better feature request here.

Just to confirm, by “TemplateContainer” you mean “VisualTreeAsset/UXML file”? Because “TemplateContainer” is just a dummy VisualElement created to serve as the root element for all root elements in a “VisualTreeAsset/UXML file”. It does not have any reference back to the “VisualTreeAsset/UXML file”, so you wouldn’t be able to get any GUID from it even if you did find it.

Speaking of finding it, when you iterate through the hierarchy recursively using Children(), it will skip some elements that are a custom elements “shadow” hierarchy. Basically, a custom C# element can override a virtual property contentContainer and return one of its child elements instead of itself (the default). This will make it so myCustomElement.Children() will actually return the Children() of the myCustomElement.contentContainer element, not the myCustomElement itself. To get the “real” list of children, you need to use myCustomElement.hierarchy.Children(). Just thought I’d add some clarity there.

As for referencing UXML files, UIElements does not have great support for referencing them by GUID. Paths are king. In USS/UXML, you can use relative paths to get most of the portability problem solved. In C# custom elements, things a bit trickier if you want to keep things portable. It’s a good feature request and might be doable sooner than later in the UI Builder. I’ll see what I can do (but no promises).

In the meantime, you’ll have to rely on C# to feed your custom elements the UXML file references.

Thanks for the Reply.

Yes I was referring to the ‘TemplateContainer’ dummy, which may have been tied to the list of Template dependencies, which is linked to the file. using myCustomElement.hierarchy.Children() may get the TemplateContainer, but still don’t have access to what every property linked it to the associated template dependency in order to get the file.

Entering paths is less than ideal because it will break as soon as the file is moved within the project.
Currently I’ll still to my static elements, but it would be great if I could use a VisualTreeAsset property in order to load customise those elements in future. fingers crossed

I see.

All I can say is that we’re aware this is a limitation worth addressing.

1 Like