Forum

You need to log in to create posts and topics.

Using a PowerUI per game object

I'm trying to create a game that largely consists of UI elements which can be dragged around and interacted with via mouse.  There may end up being large numbers of such objects onscreen at once (e.g. when zoomed out).

I'm interested in using PowerUI not so much because I need a DOM (though having one is useful!), but moreso because it sounds like an easy way to make elements like buttons that can resize based on their interior content.  That said, the way I intend to use it will likely result in many, many individual In-Game UIs existing at the same time.

I have two questions:

1. Might I run into performance or memory issues with this?  I assume that basically every In-Game UI will have its own CSS styling engine (and possibly other stuff) since each one parses a full HTML file, and I'm not sure what the overhead of all of these will be.

2. When I write e.g. an 'onlick' receiver in C#, how do I know which GameObject it came from?  All of the examples I see call static methods, and that leaves my C# code with fairly little context to work with.  I tried looking at UI.GUINode, but it looks like that's just the '#PowerUI' object.

Hey Michael,

Yes it's definitely possible to use it like that - PowerUI is often used for large volumes of text in world space (e.g. text above player's heads) so there's no particular performance issues there. In World UI's come in two flavours - a "WorldUI" and a "FlatWorldUI" - so make sure you're using WorldUI's for this. To more directly answer those two questions:

1. Nope - just make sure you use new WorldUI() - see below for a quick example. PowerUI essentially outputs meshes which also batch together as they share materials and textures whenever possible. PowerUI also shares significant parts of the JS and CSS engine across all instances and only instances a JS scope at all if your UI uses JS. Under most circumstances, you'll often find hundreds of WorldUI's will still only cost 1 drawcall.

Quick side note: FlatWorldUI's generate the same mesh but then also use a RenderTexture, so they end up with the additional overhead of a texture and a drawcall per instance. Best avoided if the goal is for bulk.

2. All elements have a "rootGameObject" property and a worldUI property. For convenience, the Event object has been extended with a worldUI property too:

var myUI = new WorldUI();
var document = myUI.document;
// e.g. parent myUI.gameObject to something. Do this whenever you want - it won't affect the DOM or how it's rendered.
document.innerHTML = "<div>Hello world!</div>";

var firstDiv = document.getElementsByTagName("div")[0] as HtmlElement;

// firstDiv.rootGameObject == myUI.gameObject
// firstDiv.worldUI == myUI

firstDiv.onclick = (MouseEvent e) => {
// e.worldUI == myUI
};

If you find yourself needing to map the other way - from a gameobject to the WorldUI instance (this is used internally by PowerUI's input system to resolve clicks) - use the WorldUI.Find methods.

Thanks for the reply!  This all sounds promising.

Okay, I see now how these can be created in code.  Also, TIL C# has closures!  That certainly makes it a lot easier to reference the game object and its monobehaviors. Up until now I assumed the "PowerUI > In World GUI" was the primary way to make them, and I was busy messing around with those and mostly getting confused. (they're kind of peculiar in 2D projects, because they start out rotated into the YZ plane, but when you change the X rotation to 0, the preview rectangle in Scene view disappears!)

How do you do code snippets on this forum?

Want the latest updates? Check out the repositories.