Instantiate and draw VisualElement from Scratch?

I’m trying to come up with a configurable and fool proof way to ensure that a specialized drag-item cursor can be rendered onto the screen at all times in all locations. To do this it seems I’d want to have some kind of VisualElement that is stretched to fill the whole screen and then make the cursor icon a child of that.

Now it is easy enough to create a dummy UIDocument asset, add a UIDocument component to a GameObject in the scene, and then pass that info to the cursor (or vice versa) so that it can be parented. But, since I’m working on a tool that for use by others I’d rather not force them to go through all that boilerplate. It would be better I think to just do all of that dynamically at runtime.That is to say, create the VisualTreeAsset at runtime, add the root visual element to it. Parent the cursor to that root visal element.

But it seems that creating a VisualTreeAsset from scratch is actually a rather complicated matter. I’ve been looking through the source code here on the github repo to get an idea of how the UIDocument monobehaviour does it but it also doesn’t show how the root VisualElements actually get registered for rendering. It seems like they are added to some kind of list but I have now idea where that information allows the UIToolkit to actually begin drawing the element.

Does anyone have some insight on how this could be accomplished dynamically without the use of linking assets and/or using the UIDocument monobehaviour?

This is what I’ve done, but I just wrote static methods that do this for you. Might require your visual tree assets in Resources folder, but for an asset store tool shouldn’t be a problem.

Eg, I have a generic ‘confirmation popup’ that works like this. And I can just call it from anywhere like so:

var popup = ConfirmationPopup.ShowPopup(text: "This is a popup!", confirmText: "Yes", cancelText: "No");
popup.OnConfirm += (result) => Debug.Log("You selected: " + result);

Under the hood it does what you describe, load the visual tree asset, make a game object with a UI document component, and uses that to draw the popup. Should possibly work in your situation too.

1 Like

Okay so then at least what I’ve been doing isn’t as hackish as I initially felt. Or if it is hackish at least I’m not the only one. Or if I am the only one at least I’m not… erm. Now I lost my train of thought.

So anyway, it seems like there aren’t any real nasty side effects outside of some dynamic asset loading. Good to know.