<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://powerui.kulestar.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bablakeluke</id>
		<title>PowerUI - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://powerui.kulestar.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bablakeluke"/>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Special:Contributions/Bablakeluke"/>
		<updated>2026-06-04T02:14:15Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.28.0</generator>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Browsers&amp;diff=3421</id>
		<title>Browsers</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Browsers&amp;diff=3421"/>
				<updated>2018-12-06T23:21:12Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Websites vs UI&amp;#039;s */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;PowerUI is not a web browser - it&amp;#039;s a UI framework.&amp;#039;&amp;#039;&amp;#039; PowerUI isn&amp;#039;t simply a wrapper for Chrome - it&amp;#039;s been built from scratch and it&amp;#039;s now rapidly becoming the newest web engine in nearly 15 years. Standing at nearly 300,000 lines of code, PowerUI is a massive toolbox for all your UI needs. As it&amp;#039;s also based on widely used standard technology, getting started with it is as simple as it gets!&lt;br /&gt;
&lt;br /&gt;
== Websites vs UI&amp;#039;s ==&lt;br /&gt;
Every now and then, people ask why PowerUI isn&amp;#039;t just a wrapper for some existing web engine. Why are we going to the effort of building an entirely new one &amp;#039;inside&amp;#039; Unity. It&amp;#039;s because websites and user interfaces have extremely different requirements. Consider this:&lt;br /&gt;
&lt;br /&gt;
=== A browser must.. ===&lt;br /&gt;
&lt;br /&gt;
* Load a website as fast as possible&lt;br /&gt;
* Display very static websites; load time is more important than runtime performance&lt;br /&gt;
* Be extremely secure&lt;br /&gt;
&lt;br /&gt;
=== A UI must.. ===&lt;br /&gt;
&lt;br /&gt;
* Tightly integrate with your code and the engine &amp;#039;&amp;#039;(opposite of secure!)&amp;#039;&amp;#039;&lt;br /&gt;
* Be very dynamic - UI&amp;#039;s are not static at all and can acceptably spend more time loading &amp;#039;&amp;#039;(opposite of the loading focus of a browser!)&amp;#039;&amp;#039;&lt;br /&gt;
* Be easy to extend in order to represent as many UI concepts as possible&lt;br /&gt;
* Not have awkward platform barriers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ideally we also shouldn&amp;#039;t need to introduce 400mb+ of bloat in a project just for UIs; PowerUI is essentially designed to be ultra compact and modular in order to simply remove features that aren&amp;#039;t needed.&lt;br /&gt;
&lt;br /&gt;
== What PowerUI can do ==&lt;br /&gt;
&lt;br /&gt;
PowerUI focuses on the goals of a UI framework. As a result it can:&lt;br /&gt;
&lt;br /&gt;
* Just work (and be exactly the same) on any platform&lt;br /&gt;
* Advanced text formatting (like knockout text)&lt;br /&gt;
* Shading/ Lighting&lt;br /&gt;
* 3D text&lt;br /&gt;
* Widget system&lt;br /&gt;
* Context menu&amp;#039;s&lt;br /&gt;
* Style scrollbars and carets&lt;br /&gt;
* Dialogue system&lt;br /&gt;
* Easy to localise&lt;br /&gt;
* Extremely customisable - design a new html element etc&lt;br /&gt;
* Particle systems and camera&amp;#039;s on your UI&lt;br /&gt;
* Use any part of the engine anywhere (It&amp;#039;s all C# after all!). GIF&amp;#039;s/ SVG&amp;#039;s on meshes, or on other UI frameworks, for example.&lt;br /&gt;
* Lots more!&lt;br /&gt;
&lt;br /&gt;
Many of these things are difficult or simply impossible for an embedded browser.&lt;br /&gt;
&lt;br /&gt;
== So can I use it like a browser? ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Sort of&amp;#039;&amp;#039;, but that&amp;#039;s not what it&amp;#039;s designed for. PowerUI has extremely broad coverage of web technologies, but these things currently limit it from being a general purpose browser:&lt;br /&gt;
&lt;br /&gt;
* Stacking contexts aren&amp;#039;t supported (for runtime performance reasons). This will make some elements on the web stack in strange orders.&lt;br /&gt;
* Flexbox/ grid aren&amp;#039;t supported yet.&lt;br /&gt;
* JavaScript - Due to limitations on iOS and many consoles, PowerUI has a custom variant of JS called Nitro. We&amp;#039;re now experimenting with fully compliant Javascript at the moment which you can get from the [[Source Control (GIT)|PowerUI source repository]].&lt;br /&gt;
&lt;br /&gt;
Currently, these things are all being worked on - PowerUI compiles in under 10 seconds, so we can iterate on new features much, much faster than any conventional browser can (and we don&amp;#039;t have the weight of a massive userbase limiting awesome new features either!).&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Throttling&amp;diff=3420</id>
		<title>Throttling</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Throttling&amp;diff=3420"/>
				<updated>2018-11-29T22:25:26Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;By default, PowerUI will dispatch all web requests immediately. This can result in scenarios where large amounts of UI&amp;#039;s being created at once can hit a server hard, and potentially result in the server throttling your requests or outright rejecting them. You can limit this using the built in max request limit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// During setup&lt;br /&gt;
PowerUI.Http.Web.MaxSimultaneousRequests = 6;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using &amp;#039;6&amp;#039; essentially matches Chrome. This will restrict the maximum number of simultaneous HTTP/S requests leaving PowerUI to the number you specify. The default is -1 meaning no limit. Any additional requests made will simply wait in a queue until prior requests complete.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Throttling&amp;diff=3419</id>
		<title>Throttling</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Throttling&amp;diff=3419"/>
				<updated>2018-11-29T22:22:46Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: Created page with &amp;quot;By default, PowerUI will dispatch all web requests immediately. This can result in scenarios where large amounts of UI&amp;#039;s being created at once can hit a server hard, and poten...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;By default, PowerUI will dispatch all web requests immediately. This can result in scenarios where large amounts of UI&amp;#039;s being created at once can hit a server hard, and potentially result in the server throttling your requests or outright rejecting them. You can limit this using the built in max request limit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxHighlighting lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
// During setup&lt;br /&gt;
PowerUI.Http.Web.MaxSimultaneousRequests = 6;&lt;br /&gt;
&amp;lt;/syntaxHighlighting&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using &amp;#039;6&amp;#039; essentially matches Chrome. This will restrict the maximum number of simultaneous HTTP/S requests leaving PowerUI to the number you specify. The default is -1 meaning no limit. Any additional requests made will simply wait in a queue until prior requests complete.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=World_UI&amp;diff=813</id>
		<title>World UI</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=World_UI&amp;diff=813"/>
				<updated>2018-04-02T16:14:56Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Flat World UI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Sometimes you might want to create something 2D in your 3D world - for example, showing health above a player, a tv screen, integration with NGUI, billboards or something a little more, well, original.. &lt;br /&gt;
&lt;br /&gt;
[[File:WorldUI-Intro.png]]&lt;br /&gt;
&lt;br /&gt;
They come in two flavours:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ordinary World UI ==&lt;br /&gt;
&lt;br /&gt;
These are true 3D and are typically what you&amp;#039;d use if you want to make use of the [[Text Extrude|text-extrude CSS property]]. If you want to make one in the editor, go to:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;GameObject &amp;gt; UI &amp;gt; PowerUI &amp;gt; In World UI&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll then get a previewer which will show you where the UI will appear. Note that the &amp;quot;WorldUI Helper&amp;quot; component is intended to be more of a guideline so it&amp;#039;s recommended to take a look at the source.&lt;br /&gt;
&lt;br /&gt;
You can then access the DOM dynamically via a WorldUIHelper like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Get that created gameobject via any regular Unity method:&lt;br /&gt;
var myWorldUI = GameObject.Find(&amp;quot;My WorldUI GameObject&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Get the doc from it:&lt;br /&gt;
var document = myWorldUI.GetComponent&amp;lt;WorldUIHelper&amp;gt;().document;&lt;br /&gt;
&lt;br /&gt;
// use the standard Web API&amp;#039;s from here:&lt;br /&gt;
document.getElementById(&amp;quot;hello-all&amp;quot;).innerHTML = &amp;quot;Hello World!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Typically these WorldUI&amp;#039;s are instanced dynamically, so to do this either parent the above to a Unity prefab and [https://docs.unity3d.com/Manual/InstantiatingPrefabs.html instantiate the prefab like normal], or directly use the [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html WorldUI scripting class]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Create a WorldUI:&lt;br /&gt;
WorldUI myWorldUI = new WorldUI(&amp;quot;optional-name&amp;quot;, 200, 30);&lt;br /&gt;
&lt;br /&gt;
// Auto pixel perfect scaling:&lt;br /&gt;
myWorldUI.PixelPerfect = true;&lt;br /&gt;
&lt;br /&gt;
// Either write to innerHTML or navigate it:&lt;br /&gt;
myWorldUI.document.innerHTML=&amp;quot;Hello world (literally!)&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that with these true 3D World UI&amp;#039;s, you must be &amp;#039;&amp;#039;&amp;#039;very careful with the gameObject&amp;#039;s scale on the z axis (its depth - the depth spacing between your UI elements)&amp;#039;&amp;#039;&amp;#039;. If you set it too small, or even zero, you&amp;#039;ll start experiencing [https://en.wikipedia.org/wiki/Z-fighting z-fighting] which means the UI will flicker. You can also use this to your advantage however - setting the z scale quite high gives a very unique looking perspective effect which is particularly powerful in VR. If you want it to be completely flat, create a &amp;quot;flat&amp;quot; WorldUI instead (below).&lt;br /&gt;
&lt;br /&gt;
== Flat World UI ==&lt;br /&gt;
&lt;br /&gt;
These are your more traditional in world UI&amp;#039;s where it&amp;#039;s rendered to an image, then the image is displayed in the gameworld however you wish. They are slower than ordinary WorldUI&amp;#039;s because of that extra texture step, but they are a lot more flexible in terms of how they can be displayed. To create one:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;GameObject &amp;gt; UI &amp;gt; PowerUI &amp;gt; In World UI&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Then tick the &amp;quot;Make it flat&amp;quot; checkbox. Alternatively, like with 3D WorldUI&amp;#039;s, you can also make them programattically too:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Create a FlatWorldUI (200px x 200px):&lt;br /&gt;
FlatWorldUI ui = new FlatWorldUI(&amp;quot;optional-name&amp;quot;, 200, 200);&lt;br /&gt;
&lt;br /&gt;
// Set the innerHTML however you&amp;#039;d like (e.g. via this helper, or write, or doc.location etc).&lt;br /&gt;
ui.document.innerHTML=&amp;quot;Hello flat world!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As the surface can be literally any shape, they require slightly specialized input handling. Use [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html#a9ffa3ae9d8b52a0fa33f810d54048d3a ResolvePoint] if you&amp;#039;d like to map a ray hit to a point in pixels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// RaycastHit aRayHit;&lt;br /&gt;
// FlatWorldUI myUI;&lt;br /&gt;
&lt;br /&gt;
// The point in pixels:&lt;br /&gt;
Vector2 pointInPixels = myUI.ResolvePoint(aRayHit);&lt;br /&gt;
&lt;br /&gt;
// E.g. get an element at that point using the standard web API method:&lt;br /&gt;
var element = document.elementFromPoint(pointInPixels.x, pointInPixels.y);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Destroying a WorldUI ==&lt;br /&gt;
&lt;br /&gt;
[[File:WorldUI-Destroy.png]]&lt;br /&gt;
&lt;br /&gt;
You can destroy a WorldUI by simply destroying its GameObject, or call [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html#ad5552c4e2e56cfaf567c9392317988f6 Destroy] on the WorldUI or FlatWorldUI instance.&lt;br /&gt;
&lt;br /&gt;
== WorldUI Origin ==&lt;br /&gt;
&lt;br /&gt;
[[File:WorldUI-Origin.png]]&lt;br /&gt;
&lt;br /&gt;
By default the origin of an ordinary (not flat) WorldUI is right in the middle. You can move it with [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html#a15f5d652a8c01b6ecf3e8db7216b2e01 SetOrigin]: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Change its origin:&lt;br /&gt;
myWorldUI.SetOrigin(1f, 1f);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Text_Extrude&amp;diff=812</id>
		<title>Text Extrude</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Text_Extrude&amp;diff=812"/>
				<updated>2018-04-02T16:13:55Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI&amp;#039;s text library [[InfiniText]] loads fonts directly which gives it full access to all of the glyphs. There&amp;#039;s lots of ways in which that can be exploited, and one example is the non-standard CSS text-extrude property. It is designed for use on a [[World UI]] so you can, for example, display e.g. &amp;quot;CITY LIBRARY&amp;quot; in localized, formatted, 3D text within your game.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s as simple as declaring a CSS property:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
text-extrude: &amp;lt;length&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The length is how far, in world units, to extrude the text. Other formatting, such as bold/ italic/ underlines and the colour will all be adopted by the 3D variant. It will also be located exactly where the flat version of the text would&amp;#039;ve been, so you can use any positioning that you wish with it.&lt;br /&gt;
&lt;br /&gt;
Essentially, 3D text with the complete power of a layout engine.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=World_UI&amp;diff=811</id>
		<title>World UI</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=World_UI&amp;diff=811"/>
				<updated>2018-04-02T16:12:17Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Ordinary World UI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Sometimes you might want to create something 2D in your 3D world - for example, showing health above a player, a tv screen, integration with NGUI, billboards or something a little more, well, original.. &lt;br /&gt;
&lt;br /&gt;
[[File:WorldUI-Intro.png]]&lt;br /&gt;
&lt;br /&gt;
They come in two flavours:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ordinary World UI ==&lt;br /&gt;
&lt;br /&gt;
These are true 3D and are typically what you&amp;#039;d use if you want to make use of the [[Text Extrude|text-extrude CSS property]]. If you want to make one in the editor, go to:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;GameObject &amp;gt; UI &amp;gt; PowerUI &amp;gt; In World UI&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll then get a previewer which will show you where the UI will appear. Note that the &amp;quot;WorldUI Helper&amp;quot; component is intended to be more of a guideline so it&amp;#039;s recommended to take a look at the source.&lt;br /&gt;
&lt;br /&gt;
You can then access the DOM dynamically via a WorldUIHelper like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Get that created gameobject via any regular Unity method:&lt;br /&gt;
var myWorldUI = GameObject.Find(&amp;quot;My WorldUI GameObject&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Get the doc from it:&lt;br /&gt;
var document = myWorldUI.GetComponent&amp;lt;WorldUIHelper&amp;gt;().document;&lt;br /&gt;
&lt;br /&gt;
// use the standard Web API&amp;#039;s from here:&lt;br /&gt;
document.getElementById(&amp;quot;hello-all&amp;quot;).innerHTML = &amp;quot;Hello World!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Typically these WorldUI&amp;#039;s are instanced dynamically, so to do this either parent the above to a Unity prefab and [https://docs.unity3d.com/Manual/InstantiatingPrefabs.html instantiate the prefab like normal], or directly use the [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html WorldUI scripting class]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Create a WorldUI:&lt;br /&gt;
WorldUI myWorldUI = new WorldUI(&amp;quot;optional-name&amp;quot;, 200, 30);&lt;br /&gt;
&lt;br /&gt;
// Auto pixel perfect scaling:&lt;br /&gt;
myWorldUI.PixelPerfect = true;&lt;br /&gt;
&lt;br /&gt;
// Either write to innerHTML or navigate it:&lt;br /&gt;
myWorldUI.document.innerHTML=&amp;quot;Hello world (literally!)&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that with these true 3D World UI&amp;#039;s, you must be &amp;#039;&amp;#039;&amp;#039;very careful with the gameObject&amp;#039;s scale on the z axis (its depth - the depth spacing between your UI elements)&amp;#039;&amp;#039;&amp;#039;. If you set it too small, or even zero, you&amp;#039;ll start experiencing [https://en.wikipedia.org/wiki/Z-fighting z-fighting] which means the UI will flicker. You can also use this to your advantage however - setting the z scale quite high gives a very unique looking perspective effect which is particularly powerful in VR. If you want it to be completely flat, create a &amp;quot;flat&amp;quot; WorldUI instead (below).&lt;br /&gt;
&lt;br /&gt;
== Flat World UI ==&lt;br /&gt;
&lt;br /&gt;
These are your more traditional in world UI&amp;#039;s where it&amp;#039;s rendered to an image, then the image is displayed in the gameworld however you wish. They are slower than ordinary WorldUI&amp;#039;s because of that extra texture step, but they are a lot more flexible in terms of how they can be displayed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Create a FlatWorldUI (200px x 200px):&lt;br /&gt;
FlatWorldUI ui = new FlatWorldUI(&amp;quot;optional-name&amp;quot;, 200, 200);&lt;br /&gt;
&lt;br /&gt;
// Set the innerHTML however you&amp;#039;d like (e.g. via this helper, or write, or doc.location etc).&lt;br /&gt;
ui.document.innerHTML=&amp;quot;Hello flat world!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As the surface can be literally any shape, they require slightly specialized input handling. Use [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html#a9ffa3ae9d8b52a0fa33f810d54048d3a ResolvePoint] if you&amp;#039;d like to map a ray hit to a point in pixels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// RaycastHit aRayHit;&lt;br /&gt;
// FlatWorldUI myUI;&lt;br /&gt;
&lt;br /&gt;
// The point in pixels:&lt;br /&gt;
Vector2 pointInPixels = myUI.ResolvePoint(aRayHit);&lt;br /&gt;
&lt;br /&gt;
// E.g. get an element at that point using the standard web API method:&lt;br /&gt;
var element = document.elementFromPoint(pointInPixels.x, pointInPixels.y);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Destroying a WorldUI ==&lt;br /&gt;
&lt;br /&gt;
[[File:WorldUI-Destroy.png]]&lt;br /&gt;
&lt;br /&gt;
You can destroy a WorldUI by simply destroying its GameObject, or call [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html#ad5552c4e2e56cfaf567c9392317988f6 Destroy] on the WorldUI or FlatWorldUI instance.&lt;br /&gt;
&lt;br /&gt;
== WorldUI Origin ==&lt;br /&gt;
&lt;br /&gt;
[[File:WorldUI-Origin.png]]&lt;br /&gt;
&lt;br /&gt;
By default the origin of an ordinary (not flat) WorldUI is right in the middle. You can move it with [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html#a15f5d652a8c01b6ecf3e8db7216b2e01 SetOrigin]: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Change its origin:&lt;br /&gt;
myWorldUI.SetOrigin(1f, 1f);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=World_UI&amp;diff=810</id>
		<title>World UI</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=World_UI&amp;diff=810"/>
				<updated>2018-04-02T16:06:34Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Ordinary World UI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Sometimes you might want to create something 2D in your 3D world - for example, showing health above a player, a tv screen, integration with NGUI, billboards or something a little more, well, original.. &lt;br /&gt;
&lt;br /&gt;
[[File:WorldUI-Intro.png]]&lt;br /&gt;
&lt;br /&gt;
They come in two flavours:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ordinary World UI ==&lt;br /&gt;
&lt;br /&gt;
These are true 3D and are typically what you&amp;#039;d use if you want to make use of the [[Text Extrude|text-extrude CSS property]]. If you want to make one in the editor, go to:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;GameObject &amp;gt; UI &amp;gt; PowerUI &amp;gt; In World UI&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll then get a previewer which will show you where the UI will appear. Note that the &amp;quot;WorldUI Helper&amp;quot; component is intended to be more of a guideline so it&amp;#039;s recommended to take a look at the source.&lt;br /&gt;
&lt;br /&gt;
You can then access the DOM dynamically via a WorldUIHelper like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Get that created gameobject via any regular Unity method:&lt;br /&gt;
var myWorldUI = GameObject.Find(&amp;quot;My WorldUI GameObject&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Get the doc from it:&lt;br /&gt;
var document = myWorldUI.GetComponent&amp;lt;WorldUIHelper&amp;gt;().document;&lt;br /&gt;
&lt;br /&gt;
// use the standard Web API&amp;#039;s from here:&lt;br /&gt;
document.getElementById(&amp;quot;hello-all&amp;quot;).innerHTML = &amp;quot;Hello World!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Typically these WorldUI&amp;#039;s are instanced dynamically, so to do this either parent the above to a Unity prefab and [https://docs.unity3d.com/Manual/InstantiatingPrefabs.html instantiate the prefab like normal], or directly use the [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html WorldUI scripting class]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Create a WorldUI:&lt;br /&gt;
WorldUI myWorldUI = new WorldUI(&amp;quot;optional-name&amp;quot;, 200, 30);&lt;br /&gt;
&lt;br /&gt;
// Auto pixel perfect scaling:&lt;br /&gt;
myWorldUI.PixelPerfect = true;&lt;br /&gt;
&lt;br /&gt;
// Either write to innerHTML or navigate it:&lt;br /&gt;
myWorldUI.document.innerHTML=&amp;quot;Hello world (literally!)&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Flat World UI ==&lt;br /&gt;
&lt;br /&gt;
These are your more traditional in world UI&amp;#039;s where it&amp;#039;s rendered to an image, then the image is displayed in the gameworld however you wish. They are slower than ordinary WorldUI&amp;#039;s because of that extra texture step, but they are a lot more flexible in terms of how they can be displayed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Create a FlatWorldUI (200px x 200px):&lt;br /&gt;
FlatWorldUI ui = new FlatWorldUI(&amp;quot;optional-name&amp;quot;, 200, 200);&lt;br /&gt;
&lt;br /&gt;
// Set the innerHTML however you&amp;#039;d like (e.g. via this helper, or write, or doc.location etc).&lt;br /&gt;
ui.document.innerHTML=&amp;quot;Hello flat world!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As the surface can be literally any shape, they require slightly specialized input handling. Use [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html#a9ffa3ae9d8b52a0fa33f810d54048d3a ResolvePoint] if you&amp;#039;d like to map a ray hit to a point in pixels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// RaycastHit aRayHit;&lt;br /&gt;
// FlatWorldUI myUI;&lt;br /&gt;
&lt;br /&gt;
// The point in pixels:&lt;br /&gt;
Vector2 pointInPixels = myUI.ResolvePoint(aRayHit);&lt;br /&gt;
&lt;br /&gt;
// E.g. get an element at that point using the standard web API method:&lt;br /&gt;
var element = document.elementFromPoint(pointInPixels.x, pointInPixels.y);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Destroying a WorldUI ==&lt;br /&gt;
&lt;br /&gt;
[[File:WorldUI-Destroy.png]]&lt;br /&gt;
&lt;br /&gt;
You can destroy a WorldUI by simply destroying its GameObject, or call [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html#ad5552c4e2e56cfaf567c9392317988f6 Destroy] on the WorldUI or FlatWorldUI instance.&lt;br /&gt;
&lt;br /&gt;
== WorldUI Origin ==&lt;br /&gt;
&lt;br /&gt;
[[File:WorldUI-Origin.png]]&lt;br /&gt;
&lt;br /&gt;
By default the origin of an ordinary (not flat) WorldUI is right in the middle. You can move it with [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html#a15f5d652a8c01b6ecf3e8db7216b2e01 SetOrigin]: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Change its origin:&lt;br /&gt;
myWorldUI.SetOrigin(1f, 1f);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=World_UI&amp;diff=809</id>
		<title>World UI</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=World_UI&amp;diff=809"/>
				<updated>2018-04-02T16:05:03Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Ordinary World UI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Sometimes you might want to create something 2D in your 3D world - for example, showing health above a player, a tv screen, integration with NGUI, billboards or something a little more, well, original.. &lt;br /&gt;
&lt;br /&gt;
[[File:WorldUI-Intro.png]]&lt;br /&gt;
&lt;br /&gt;
They come in two flavours:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ordinary World UI ==&lt;br /&gt;
&lt;br /&gt;
These are true 3D and are typically what you&amp;#039;d use if you want to make use of the [[Text Extrude|text-extrude CSS property]]. If you want to make one in the editor, go to:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;GameObject &amp;gt; UI &amp;gt; PowerUI &amp;gt; In World UI&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll then get a previewer which will show you where the UI will appear. Note that the &amp;quot;WorldUI Helper&amp;quot; component is intended to be more of a guideline so it&amp;#039;s recommended to take a look at the source.&lt;br /&gt;
&lt;br /&gt;
You can then access the DOM dynamically via a WorldUIHelper like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Get that created gameobject via any regular Unity method:&lt;br /&gt;
var myWorldUI = GameObject.Find(&amp;quot;My WorldUI GameObject&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Get the doc from it:&lt;br /&gt;
var document = myWorldUI.GetComponent&amp;lt;WorldUIHelper&amp;gt;().document;&lt;br /&gt;
&lt;br /&gt;
// use the standard Web API&amp;#039;s from here:&lt;br /&gt;
document.getElementById(&amp;quot;hello-all&amp;quot;).innerHTML = &amp;quot;Hello World!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Typically they&amp;#039;re instanced dynamically anyway (such as for 3D chat bubbles etc) so for that you&amp;#039;ll want to look at the [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html WorldUI scripting class]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Create a WorldUI:&lt;br /&gt;
WorldUI myWorldUI = new WorldUI(&amp;quot;optional-name&amp;quot;, 200, 30);&lt;br /&gt;
&lt;br /&gt;
// Auto pixel perfect scaling:&lt;br /&gt;
myWorldUI.PixelPerfect = true;&lt;br /&gt;
&lt;br /&gt;
// Either write to innerHTML or navigate it:&lt;br /&gt;
myWorldUI.document.innerHTML=&amp;quot;Hello world (literally!)&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Flat World UI ==&lt;br /&gt;
&lt;br /&gt;
These are your more traditional in world UI&amp;#039;s where it&amp;#039;s rendered to an image, then the image is displayed in the gameworld however you wish. They are slower than ordinary WorldUI&amp;#039;s because of that extra texture step, but they are a lot more flexible in terms of how they can be displayed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Create a FlatWorldUI (200px x 200px):&lt;br /&gt;
FlatWorldUI ui = new FlatWorldUI(&amp;quot;optional-name&amp;quot;, 200, 200);&lt;br /&gt;
&lt;br /&gt;
// Set the innerHTML however you&amp;#039;d like (e.g. via this helper, or write, or doc.location etc).&lt;br /&gt;
ui.document.innerHTML=&amp;quot;Hello flat world!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As the surface can be literally any shape, they require slightly specialized input handling. Use [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html#a9ffa3ae9d8b52a0fa33f810d54048d3a ResolvePoint] if you&amp;#039;d like to map a ray hit to a point in pixels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// RaycastHit aRayHit;&lt;br /&gt;
// FlatWorldUI myUI;&lt;br /&gt;
&lt;br /&gt;
// The point in pixels:&lt;br /&gt;
Vector2 pointInPixels = myUI.ResolvePoint(aRayHit);&lt;br /&gt;
&lt;br /&gt;
// E.g. get an element at that point using the standard web API method:&lt;br /&gt;
var element = document.elementFromPoint(pointInPixels.x, pointInPixels.y);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Destroying a WorldUI ==&lt;br /&gt;
&lt;br /&gt;
[[File:WorldUI-Destroy.png]]&lt;br /&gt;
&lt;br /&gt;
You can destroy a WorldUI by simply destroying its GameObject, or call [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html#ad5552c4e2e56cfaf567c9392317988f6 Destroy] on the WorldUI or FlatWorldUI instance.&lt;br /&gt;
&lt;br /&gt;
== WorldUI Origin ==&lt;br /&gt;
&lt;br /&gt;
[[File:WorldUI-Origin.png]]&lt;br /&gt;
&lt;br /&gt;
By default the origin of an ordinary (not flat) WorldUI is right in the middle. You can move it with [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1WorldUI.html#a15f5d652a8c01b6ecf3e8db7216b2e01 SetOrigin]: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Change its origin:&lt;br /&gt;
myWorldUI.SetOrigin(1f, 1f);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Event_Flow&amp;diff=808</id>
		<title>Event Flow</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Event_Flow&amp;diff=808"/>
				<updated>2018-03-21T18:55:28Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Template */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events occur when something important happens. You can dispatch a custom event or listen to any event using the standard EventTarget interface. PowerUI follows the [https://www.w3.org/TR/uievents/#event-flow standard W3C event flow] which occurs in three phases - &amp;#039;&amp;#039;capture&amp;#039;&amp;#039;, &amp;#039;&amp;#039;target&amp;#039;&amp;#039; then &amp;#039;&amp;#039;bubble&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Unhandled Events ==&lt;br /&gt;
&lt;br /&gt;
Whenever an event is going to be wasted, such as clicking on nothing, PowerUI dispatches the event to a special handler so you can still respond to it. That handler is [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a573d05035b63bd0f263775209b4109c6 PowerUI.Input.Unhandled].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Adding a listener to the unhandled target:&lt;br /&gt;
&lt;br /&gt;
PowerUI.Input.Unhandled.addEventListener(&amp;quot;mousedown&amp;quot;,delegate(MouseEvent e){&lt;br /&gt;
    &lt;br /&gt;
    // They clicked on *nothing!* (straight &amp;#039;through&amp;#039; the UI).&lt;br /&gt;
    &lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that due to the way how the event flow and bubbling works, you can get the opposite situation at the root of the DOM:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Adding a listener to the document:&lt;br /&gt;
&lt;br /&gt;
UI.document.addEventListener(&amp;quot;mousedown&amp;quot;,delegate(MouseEvent e){&lt;br /&gt;
    &lt;br /&gt;
    // They clicked on *anything!* (and the event bubbled to the document, or the window).&lt;br /&gt;
    &lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Source locations ==&lt;br /&gt;
&lt;br /&gt;
Events occur in multiple different modules of PowerUI so the source is a little spread out. Here&amp;#039;s the important parts:&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Dom/Events - &amp;#039;&amp;#039;In here is the very bottom of the event hierarchy; the EventTarget, EventListener and &amp;#039;Event&amp;#039; .&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Engine/Events - &amp;#039;&amp;#039;More abstract events - KeyboardEvent, UIEvent, MouseEvent can all be found in here. The bulk of them are in the Events.cs file.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Defining custom events ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;d like to define a custom event, you could just create a class which inherits from some other Event type and be done, however, if you want perfect integration then there are 2 things you need to define:&lt;br /&gt;
&lt;br /&gt;
* The Event class itself (define an event and inherit from e.g. Dom.Event)&lt;br /&gt;
* The addEventListener method on EventTarget which accepts your delegate and creates a listener for your custom type&lt;br /&gt;
&lt;br /&gt;
=== Naming conventions ===&lt;br /&gt;
&lt;br /&gt;
Events should represent a &amp;#039;&amp;#039;broad category of things&amp;#039;&amp;#039; - for example, a MouseEvent rather than LeftClickEvent / RightClickEvent. A ScoreEvent and a MissionEvent rather than a PointsGainedFromMissionEvent or a MissionStartedEvent and a MissionCompletedEvent. Use type to define what the event actually is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Mission complete! Fire a complete event:&lt;br /&gt;
MissionEvent e=new MissionEvent(&amp;quot;complete&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Dispatch to e.g. the main UI document:&lt;br /&gt;
UI.document.dispatchEvent(e);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This avoids having hundreds of very specific rare events which would become difficult to maintain. You want to make it easy for yourself to fire off an event because of how useful they are (i.e. you don&amp;#039;t want to be put off because you have to define a whole new event type!)&lt;br /&gt;
&lt;br /&gt;
=== Template ===&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a convenient template which defines everything you need to declare a new event type which &amp;#039;just works&amp;#039;. Just find-and-replace {NAME} with the name you&amp;#039;d like to use for your event name, and {LOWERNAME} with the lowercase version.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;For example, find and replace {NAME} with Mission, and {LOWERNAME} with mission&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;Your event object itself.&lt;br /&gt;
/// Add whatever properties you&amp;#039;d like to this.&lt;br /&gt;
/// Optionally swap Dom.Event for something more appropriate.&amp;lt;/summary&amp;gt;&lt;br /&gt;
public class {NAME}Event : Dom.Event{&lt;br /&gt;
    &lt;br /&gt;
    public class {NAME}Event(string type):base(&amp;quot;{LOWERNAME}&amp;quot; + type){}&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace Dom{&lt;br /&gt;
    &lt;br /&gt;
    public partial class EventTarget{&lt;br /&gt;
        &lt;br /&gt;
        /// &amp;lt;summary&amp;gt;Add an event listener for a {NAME}Event type of event.&amp;lt;/summary&amp;gt;&lt;br /&gt;
        public void addEventListener(string name,Action&amp;lt;{NAME}Event&amp;gt; method){&lt;br /&gt;
            addEventListener(name,new EventListener&amp;lt;{NAME}Event&amp;gt;(method));&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want something to look at then the best example is WidgetEvent - it contains everything in a single file for you:&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Extras/Widgets/WidgetEvent.cs&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Event_Flow&amp;diff=807</id>
		<title>Event Flow</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Event_Flow&amp;diff=807"/>
				<updated>2018-03-21T18:52:41Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Unhandled Events */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events occur when something important happens. You can dispatch a custom event or listen to any event using the standard EventTarget interface. PowerUI follows the [https://www.w3.org/TR/uievents/#event-flow standard W3C event flow] which occurs in three phases - &amp;#039;&amp;#039;capture&amp;#039;&amp;#039;, &amp;#039;&amp;#039;target&amp;#039;&amp;#039; then &amp;#039;&amp;#039;bubble&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Unhandled Events ==&lt;br /&gt;
&lt;br /&gt;
Whenever an event is going to be wasted, such as clicking on nothing, PowerUI dispatches the event to a special handler so you can still respond to it. That handler is [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a573d05035b63bd0f263775209b4109c6 PowerUI.Input.Unhandled].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Adding a listener to the unhandled target:&lt;br /&gt;
&lt;br /&gt;
PowerUI.Input.Unhandled.addEventListener(&amp;quot;mousedown&amp;quot;,delegate(MouseEvent e){&lt;br /&gt;
    &lt;br /&gt;
    // They clicked on *nothing!* (straight &amp;#039;through&amp;#039; the UI).&lt;br /&gt;
    &lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that due to the way how the event flow and bubbling works, you can get the opposite situation at the root of the DOM:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Adding a listener to the document:&lt;br /&gt;
&lt;br /&gt;
UI.document.addEventListener(&amp;quot;mousedown&amp;quot;,delegate(MouseEvent e){&lt;br /&gt;
    &lt;br /&gt;
    // They clicked on *anything!* (and the event bubbled to the document, or the window).&lt;br /&gt;
    &lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Source locations ==&lt;br /&gt;
&lt;br /&gt;
Events occur in multiple different modules of PowerUI so the source is a little spread out. Here&amp;#039;s the important parts:&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Dom/Events - &amp;#039;&amp;#039;In here is the very bottom of the event hierarchy; the EventTarget, EventListener and &amp;#039;Event&amp;#039; .&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Engine/Events - &amp;#039;&amp;#039;More abstract events - KeyboardEvent, UIEvent, MouseEvent can all be found in here. The bulk of them are in the Events.cs file.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Defining custom events ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;d like to define a custom event, you could just create a class which inherits from some other Event type and be done, however, if you want perfect integration then there are 2 things you need to define:&lt;br /&gt;
&lt;br /&gt;
* The Event class itself (define an event and inherit from e.g. Dom.Event)&lt;br /&gt;
* The addEventListener method on EventTarget which accepts your delegate and creates a listener for your custom type&lt;br /&gt;
&lt;br /&gt;
=== Naming conventions ===&lt;br /&gt;
&lt;br /&gt;
Events should represent a &amp;#039;&amp;#039;broad category of things&amp;#039;&amp;#039; - for example, a MouseEvent rather than LeftClickEvent / RightClickEvent. A ScoreEvent and a MissionEvent rather than a PointsGainedFromMissionEvent or a MissionStartedEvent and a MissionCompletedEvent. Use type to define what the event actually is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Mission complete! Fire a complete event:&lt;br /&gt;
MissionEvent e=new MissionEvent(&amp;quot;complete&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Dispatch to e.g. the main UI document:&lt;br /&gt;
UI.document.dispatchEvent(e);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This avoids having hundreds of very specific rare events which would become difficult to maintain. You want to make it easy for yourself to fire off an event because of how useful they are (i.e. you don&amp;#039;t want to be put off because you have to define a whole new event type!)&lt;br /&gt;
&lt;br /&gt;
=== Template ===&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a convenient template which defines everything you need to declare a new event type which &amp;#039;just works&amp;#039;. Just find-and-replace {NAME} with the name you&amp;#039;d like to use for your event name.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;For example, find and replace {NAME} with Mission&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;Your event object itself.&lt;br /&gt;
/// Add whatever properties you&amp;#039;d like to this.&lt;br /&gt;
/// Optionally swap Dom.Event for something more appropriate.&amp;lt;/summary&amp;gt;&lt;br /&gt;
public class {NAME}Event : Dom.Event{&lt;br /&gt;
    &lt;br /&gt;
    public class {NAME}Event(string type):base(type){}&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace Dom{&lt;br /&gt;
    &lt;br /&gt;
    public partial class EventTarget{&lt;br /&gt;
        &lt;br /&gt;
        /// &amp;lt;summary&amp;gt;Add an event listener for a {NAME}Event type of event.&amp;lt;/summary&amp;gt;&lt;br /&gt;
        public void addEventListener(string name,Action&amp;lt;{NAME}Event&amp;gt; method){&lt;br /&gt;
            addEventListener(name,new EventListener&amp;lt;{NAME}Event&amp;gt;(method));&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want something to look at then the best example is WidgetEvent - it contains everything in a single file for you:&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Extras/Widgets/WidgetEvent.cs&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Event_Flow&amp;diff=806</id>
		<title>Event Flow</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Event_Flow&amp;diff=806"/>
				<updated>2018-03-21T18:52:34Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Unhandled Events */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events occur when something important happens. You can dispatch a custom event or listen to any event using the standard EventTarget interface. PowerUI follows the [https://www.w3.org/TR/uievents/#event-flow standard W3C event flow] which occurs in three phases - &amp;#039;&amp;#039;capture&amp;#039;&amp;#039;, &amp;#039;&amp;#039;target&amp;#039;&amp;#039; then &amp;#039;&amp;#039;bubble&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Unhandled Events ==&lt;br /&gt;
&lt;br /&gt;
Whenever an event ia going to be wasted, such as clicking on nothing, PowerUI dispatches the event to a special handler so you can still respond to it. That handler is [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a573d05035b63bd0f263775209b4109c6 PowerUI.Input.Unhandled].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Adding a listener to the unhandled target:&lt;br /&gt;
&lt;br /&gt;
PowerUI.Input.Unhandled.addEventListener(&amp;quot;mousedown&amp;quot;,delegate(MouseEvent e){&lt;br /&gt;
    &lt;br /&gt;
    // They clicked on *nothing!* (straight &amp;#039;through&amp;#039; the UI).&lt;br /&gt;
    &lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that due to the way how the event flow and bubbling works, you can get the opposite situation at the root of the DOM:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Adding a listener to the document:&lt;br /&gt;
&lt;br /&gt;
UI.document.addEventListener(&amp;quot;mousedown&amp;quot;,delegate(MouseEvent e){&lt;br /&gt;
    &lt;br /&gt;
    // They clicked on *anything!* (and the event bubbled to the document, or the window).&lt;br /&gt;
    &lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Source locations ==&lt;br /&gt;
&lt;br /&gt;
Events occur in multiple different modules of PowerUI so the source is a little spread out. Here&amp;#039;s the important parts:&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Dom/Events - &amp;#039;&amp;#039;In here is the very bottom of the event hierarchy; the EventTarget, EventListener and &amp;#039;Event&amp;#039; .&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Engine/Events - &amp;#039;&amp;#039;More abstract events - KeyboardEvent, UIEvent, MouseEvent can all be found in here. The bulk of them are in the Events.cs file.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Defining custom events ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;d like to define a custom event, you could just create a class which inherits from some other Event type and be done, however, if you want perfect integration then there are 2 things you need to define:&lt;br /&gt;
&lt;br /&gt;
* The Event class itself (define an event and inherit from e.g. Dom.Event)&lt;br /&gt;
* The addEventListener method on EventTarget which accepts your delegate and creates a listener for your custom type&lt;br /&gt;
&lt;br /&gt;
=== Naming conventions ===&lt;br /&gt;
&lt;br /&gt;
Events should represent a &amp;#039;&amp;#039;broad category of things&amp;#039;&amp;#039; - for example, a MouseEvent rather than LeftClickEvent / RightClickEvent. A ScoreEvent and a MissionEvent rather than a PointsGainedFromMissionEvent or a MissionStartedEvent and a MissionCompletedEvent. Use type to define what the event actually is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Mission complete! Fire a complete event:&lt;br /&gt;
MissionEvent e=new MissionEvent(&amp;quot;complete&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Dispatch to e.g. the main UI document:&lt;br /&gt;
UI.document.dispatchEvent(e);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This avoids having hundreds of very specific rare events which would become difficult to maintain. You want to make it easy for yourself to fire off an event because of how useful they are (i.e. you don&amp;#039;t want to be put off because you have to define a whole new event type!)&lt;br /&gt;
&lt;br /&gt;
=== Template ===&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a convenient template which defines everything you need to declare a new event type which &amp;#039;just works&amp;#039;. Just find-and-replace {NAME} with the name you&amp;#039;d like to use for your event name.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;For example, find and replace {NAME} with Mission&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;Your event object itself.&lt;br /&gt;
/// Add whatever properties you&amp;#039;d like to this.&lt;br /&gt;
/// Optionally swap Dom.Event for something more appropriate.&amp;lt;/summary&amp;gt;&lt;br /&gt;
public class {NAME}Event : Dom.Event{&lt;br /&gt;
    &lt;br /&gt;
    public class {NAME}Event(string type):base(type){}&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace Dom{&lt;br /&gt;
    &lt;br /&gt;
    public partial class EventTarget{&lt;br /&gt;
        &lt;br /&gt;
        /// &amp;lt;summary&amp;gt;Add an event listener for a {NAME}Event type of event.&amp;lt;/summary&amp;gt;&lt;br /&gt;
        public void addEventListener(string name,Action&amp;lt;{NAME}Event&amp;gt; method){&lt;br /&gt;
            addEventListener(name,new EventListener&amp;lt;{NAME}Event&amp;gt;(method));&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want something to look at then the best example is WidgetEvent - it contains everything in a single file for you:&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Extras/Widgets/WidgetEvent.cs&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=805</id>
		<title>Performance</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=805"/>
				<updated>2018-03-21T18:51:39Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Go event based - avoid spamming your UI in Update */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI puts performance first. A user interface has very different requirements from a web browser - compare the UI of your favourite games with just how stationary this wiki is, for example. A web browser focuses on making a page show up quickly where as a game will spend time loading to make sure it &amp;#039;&amp;#039;runs&amp;#039;&amp;#039; quickly. PowerUI has been built from scratch to fit the requirements of a high performance UI framework.&lt;br /&gt;
&lt;br /&gt;
In general, we only add support for something when we can get it working without affecting PowerUI&amp;#039;s overall speed. It&amp;#039;s working too - PowerUI can handle large volumes of HTML with little to no performance issues, whilst now simultaneously having very broad coverage of web technologies.&lt;br /&gt;
&lt;br /&gt;
However, PowerUI is vulnerable to being exposed to some very performance draining web techniques (and there are many of them!) so this is intended to be a short guide to understanding how web engines work and what you can do to avoid some common pitfalls.&lt;br /&gt;
&lt;br /&gt;
== Avoid searching for constant elements in Update ==&lt;br /&gt;
&lt;br /&gt;
This one is a common mistake but can also make great performance savings if you make some small changes. Here&amp;#039;s an example of what it looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
 &lt;br /&gt;
    // Don&amp;#039;t do this!&lt;br /&gt;
    var element = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PowerUI will try and index your IDs, but in general, this will result in scanning your whole DOM every single frame. You should just cache the element instead:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Element MyNavMenu;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    // Much better!&lt;br /&gt;
    MyNavMenu = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    // Use MyNavMenu in here&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Go event based - avoid spamming your UI in Update ==&lt;br /&gt;
&lt;br /&gt;
Although it&amp;#039;s ok to update your UI in the Update loop, for example for a timer, try being more event based for the greatest performance. For example, let&amp;#039;s say you pop up some info when the user clicks on an NPC. Rather than spamming some &amp;#039;SelectedNpc&amp;#039; field, update the UI when they&amp;#039;re actually clicked on:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;A common Unity anti-pattern - don&amp;#039;t do this!&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update() {&lt;br /&gt;
    // Bad!&lt;br /&gt;
    var headsUp = UI.document.getElementById(&amp;quot;npc-heads-up-info&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    if (SelectedNpc != null) {&lt;br /&gt;
        // Spamspamspamspamspam&lt;br /&gt;
        headsUp.innerHTML = SelectedNpc.HtmlDetails;&lt;br /&gt;
    } else {&lt;br /&gt;
        headsUp.innerHTML = &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead, set that innerHTML when you set SelectedNpc:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void SelectedAnNpc(Npc npc) {&lt;br /&gt;
    // Much better!&lt;br /&gt;
    SelectedNpc = npc;&lt;br /&gt;
&lt;br /&gt;
    // Update the UI:&lt;br /&gt;
    var headsUp = UI.document.getElementById(&amp;quot;npc-heads-up-info&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    if (SelectedNpc != null) {&lt;br /&gt;
        headsUp.innerHTML = SelectedNpc.HtmlDetails;&lt;br /&gt;
    } else {&lt;br /&gt;
        headsUp.innerHTML = &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PowerUI ships with a very powerful and extendible [[Event Flow|standards compliant event system]] - use this to your advantage. Selecting an NPC could fire off an NPC selection event, which some other class controlling your UI responds to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void SelectedAnNpc(Npc npc) {&lt;br /&gt;
    // Much better!&lt;br /&gt;
    SelectedNpc = npc;&lt;br /&gt;
    &lt;br /&gt;
    // Fire off an event which anything can subscribe to with a standard event listener on the document:&lt;br /&gt;
    NpcEvent e = new NpcEvent(&amp;quot;selected&amp;quot;);&lt;br /&gt;
    e.npc = npc;&lt;br /&gt;
    UI.document.dispatchEvent(e);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// .. somewhere else ..&lt;br /&gt;
&lt;br /&gt;
UI.document.addEventListener(&amp;quot;npcselected&amp;quot;, delegate(NpcEvent e){&lt;br /&gt;
    // Update the UI here, using e.npc instead.&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reflow ==&lt;br /&gt;
&lt;br /&gt;
Reflow is the name given when a web engine resolves CSS values and figures out where everything is on the screen. PowerUI also performs reflow, so following standard good practice for reducing reflow in a web browser applies to PowerUI too, so [https://developers.google.com/speed/articles/reflow here&amp;#039;s a guide that will help with just that]. You may have cases where your UI generates lots of reflows very fast - PowerUI internally meters this using UI.SetRate; it won&amp;#039;t reflow any more often than the rate you give.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #1: Use UI.SetRate and get it as low as you reasonably can. The default is 30fps with super smooth at 60fps.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Following similar lines, pulling properties such as contentHeight from an element will force a reflow to happen if the element is known to require one. Accessing the computed style (element.style.Computed.ContentHeight for example) does not force reflows, so if you know e.g. the height didn&amp;#039;t change then using computed styles directly can be a little quicker, but this only really applies if you&amp;#039;re doing a style change and then grabbing the contentHeight rapidly in a loop. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #2: Read from ComputedStyle where possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Skipping Reflow ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s possible to pull off a complex UI which only performs reflow a handful of times by focusing on post-process CSS properties. These are CSS properties which don&amp;#039;t affect the flow or structure of an element - the main examples are color, color-overlay, transform and the special case that is scroll. Generally try to animate these ones when you can!&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #3: Animate transforms (scale, rotate, translate) rather than positions (top, left, right etc) if possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Limiting reflow scope ===&lt;br /&gt;
&lt;br /&gt;
Reflow applies to the nearest &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; element. For example, let&amp;#039;s say you update the innerHTML of a fixed/absolute/sticky &amp;#039;&amp;#039;&amp;#039;positioned element&amp;#039;&amp;#039;&amp;#039; then &amp;#039;&amp;#039;only that element will actually reflow&amp;#039;&amp;#039;. The same applies to any of the nested kids of that positioned element - it&amp;#039;ll bubble up the DOM to the nearest flow root, and request to reflow that element. In short, making an element become a &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; is an easy way to massively limit how many elements reflow actually affects.&lt;br /&gt;
&lt;br /&gt;
== Table Chaos ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;PowerUI doesn&amp;#039;t support tables with no defined widths.&amp;#039;&amp;#039;&amp;#039; Tables cause multiple passes over potentially thousands of elements. The modern reason for using a table today is for vertical alignment - most other layouts can be easily done with other far less intense techniques. If it&amp;#039;s vertical align that you&amp;#039;re really after then use the custom vertical-align values on any element:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Middle vertical alignment without the overhead of table-cell/ tables */&lt;br /&gt;
vertical-align:table-middle;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On a similar line, tables with no defined column widths are outright evil. The number of elements scanned to guess how wide a column probably should be can go exponential very quickly and, after all of that, it often doesn&amp;#039;t look great anyway. As we&amp;#039;re making UIs which reflow very frequently, PowerUI requires you to give all your table columns and the table itself some kind of width value. This way PowerUI has unusually fast tables - making them suitable for heavy reflow - but they&amp;#039;re still slow compared to almost anything else.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #4: Use techniques other than table whenever appropriate, and make use of table-middle.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Memory Usage ==&lt;br /&gt;
&lt;br /&gt;
PowerUI is conservative about its memory usage, but if you&amp;#039;re targeting really low memory devices, turning off [[Image_Atlasing|image atlasing]] may be wise. Turning it off exchanges GPU/rendering time for lower memory and CPU use, which can be vital for pulling off a stunning UI on a device with little memory available.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #5: Turn off image atlasing for very low memory devices. See UI.RenderMode for doing that.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Multithreading ==&lt;br /&gt;
&lt;br /&gt;
Virtually all of PowerUI is multithreading friendly - anything that directly calls a Unity method like the geolocation web API isn&amp;#039;t. Presently the cookie cache (loading or setting cookies) is the only known PowerUI API which avoidably causes threading issues. Use PowerUI API&amp;#039;s directly from network threads, or spin up threads specifically for doing heavier UI work to make significant performance gains on multi-core architectures.&lt;br /&gt;
&lt;br /&gt;
== Canvas ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing to a canvas, there&amp;#039;s some nice savings you can be making. These savings are particularly noticeable if you&amp;#039;re drawing repeatedly, such as in Update.&lt;br /&gt;
&lt;br /&gt;
=== Only redraw your canvas when PowerUI does ===&lt;br /&gt;
PowerUI uploads the canvas image to the GPU no faster than your UI rate. Drawing your canvas any faster than that interval will essentially just waste cycles. We call that upload process a &amp;#039;refresh&amp;#039; - whenever you call stroke() or fill(), a refresh request is made (and then at some point in the near future, a refresh happens).&lt;br /&gt;
&lt;br /&gt;
So, if PowerUI already has an image which is ready but hasn&amp;#039;t been uploaded yet, there will be a pending refresh. Checking for that is like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
private CanvasContext2D Context;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
&lt;br /&gt;
    if(Context.ImageData.RefreshRequired){&lt;br /&gt;
        // This means we&amp;#039;ve already rendered something to the image data&lt;br /&gt;
        // and it&amp;#039;s just waiting to be uploaded. Rendering again would be a waste of time.&lt;br /&gt;
        // So, do nothing!&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Nothing to upload - draw it now!&lt;br /&gt;
    Context.beginPath();&lt;br /&gt;
    Context.moveTo(10,10);&lt;br /&gt;
    // ...&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multithreading canvas ===&lt;br /&gt;
&lt;br /&gt;
Like most PowerUI API&amp;#039;s, canvas is multithreading friendly. You could build those paths on some separate timer thread if you wanted to, for example.&lt;br /&gt;
&lt;br /&gt;
=== Cache your paths ===&lt;br /&gt;
&lt;br /&gt;
Whenever you call context.arcTo, context.lineTo etc, PowerUI internally builds up a representation of your path. When you then next call context.beginPath or context.clear, that representation is destroyed. If you&amp;#039;re drawing the same path over and over, it would be a great idea to save this internal representation rather than constantly rebuilding it to take some pressure off garbage collection.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you do this, it&amp;#039;s up to you to safely bound your points.&amp;#039;&amp;#039;&amp;#039; Normally the canvas API automatically takes care of points that are excessively out of range for you - things like infinity, NaN, or generally huge numbers. If you build a VectorPath and set it to a canvas, it&amp;#039;s important that you also guarantee your path doesn&amp;#039;t have any of those things. Internally, the canvas API runs VectorPath.Clip on all paths constructed via lineTo, arcTo etc. Otherwise, if you have an extremely long path then the canvas API will freeze whilst it outputs billions of pixels.&lt;br /&gt;
&lt;br /&gt;
To cache your paths you could either simply never call context.clear or context.beginPath and access Context.Path to move the nodes around like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI.&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
&lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // To clear the image but not the path, use ImageData:&lt;br /&gt;
    Context.ImageData.Clear();&lt;br /&gt;
&lt;br /&gt;
    // The path is totally empty if there&amp;#039;s no first node:&lt;br /&gt;
    if(Context.Path.FirstPathNode == null){&lt;br /&gt;
        &lt;br /&gt;
        // No path yet! Build it now:&lt;br /&gt;
        Context.moveTo(10,10);&lt;br /&gt;
        Context.lineTo(10,100);&lt;br /&gt;
        Context.lineTo(100,100);&lt;br /&gt;
        Context.lineTo(100,10);&lt;br /&gt;
        Context.closePath();&lt;br /&gt;
        &lt;br /&gt;
        // Note if any of the points in this first time call&lt;br /&gt;
        // go far out of range of the canvas, they may be &lt;br /&gt;
        // sliced for performance purposes.&lt;br /&gt;
        // For example, if your entire path is off canvas,&lt;br /&gt;
        // the whole thing may be dumped when you call stroke().&lt;br /&gt;
        &lt;br /&gt;
        // One way to avoid that uncertainty is to build the VectorPath directly (like below)&lt;br /&gt;
        // and then call VectorPath.Clip when it&amp;#039;s appropriate for your use case.&lt;br /&gt;
        &lt;br /&gt;
    }else{&lt;br /&gt;
        &lt;br /&gt;
        // E.g. update the nodes in the cachedPath:&lt;br /&gt;
        var point = CachedPath.FirstPathNode;&lt;br /&gt;
        &lt;br /&gt;
        // Our path has 5 points (alternatively loop until point is null).&lt;br /&gt;
        for(int i=0;i&amp;lt;5;i++){ // while(point!=null){&lt;br /&gt;
            &lt;br /&gt;
            // Move the point by the frame time:&lt;br /&gt;
            point.X += Time.deltaTime;&lt;br /&gt;
            &lt;br /&gt;
            // Go to the next point:&lt;br /&gt;
            point = point.Next;&lt;br /&gt;
          &lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Stroke or fill etc down here:&lt;br /&gt;
    Context.stroke();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing multiple paths and you want to cache them all, then the simpler route would be to directly build one or more VectorPath instances first:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI&lt;br /&gt;
using Blaze; // For VectorPath&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
/// &amp;lt;summary&amp;gt;A single cached path.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private VectorPath CachedPath;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    &lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // build the vector path(s):&lt;br /&gt;
    CachedPath = new VectorPath();&lt;br /&gt;
&lt;br /&gt;
    // The API is very similar - it&amp;#039;s capitalized as it&amp;#039;s part of the internal public API:&lt;br /&gt;
    CachedPath.MoveTo(10,10);&lt;br /&gt;
    CachedPath.LineTo(10,100);&lt;br /&gt;
    CachedPath.LineTo(100,100);&lt;br /&gt;
    CachedPath.LineTo(100,10);&lt;br /&gt;
    CachedPath.ClosePath();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // Calling normal clear doesn&amp;#039;t matter here (as we&amp;#039;re not using e.g. Context.lineTo)&lt;br /&gt;
    Context.clear();&lt;br /&gt;
    &lt;br /&gt;
    // E.g. update current path here:&lt;br /&gt;
    var point = CachedPath.FirstPathNode;&lt;br /&gt;
    &lt;br /&gt;
    // note that closed paths never make infinite loops here.&lt;br /&gt;
    // A close node simply overlaps the node it closes and has IsClose set to true.&lt;br /&gt;
    while(point!=null){&lt;br /&gt;
        point.X+=Time.deltaTime;&lt;br /&gt;
        point=point.Next;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Temporarily retain the path object in the canvas:&lt;br /&gt;
    VectorPath activePath = Canvas.Path;&lt;br /&gt;
    &lt;br /&gt;
    // Set ours:&lt;br /&gt;
    Canvas.Path = CachedPath;&lt;br /&gt;
    &lt;br /&gt;
    // Stroke it now:&lt;br /&gt;
    Canvas.stroke();&lt;br /&gt;
&lt;br /&gt;
    // Restore the other path:&lt;br /&gt;
    Canvas.Path = activePath;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Precompile PowerUI ==&lt;br /&gt;
&lt;br /&gt;
Performance applies to your development process too. Unless you&amp;#039;ve got a solid state hard drive, PowerUI can take some 15 seconds to compile. Every time you change any of your C# files. [[Precompiler|Precompile PowerUI]] by going to &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Precompile&amp;#039;&amp;#039;&amp;#039; then just tick the box - that will entirely eliminate this delay for you.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you change platform, or update Unity, you must precompile it again!&amp;#039;&amp;#039;&amp;#039; That&amp;#039;s because things like UNITY_ANDROID matter a lot.&lt;br /&gt;
&lt;br /&gt;
Note that precompiling does not affect custom tags etc, but it does affect any &amp;#039;&amp;#039;partial class extensions&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Set textContent rather than innerHTML ==&lt;br /&gt;
&lt;br /&gt;
If you know your text contains no HTML then setting to textContent will cause virtually everything to get recycled. Setting innerHTML is fast anyway but textContent does almost nothing.&lt;br /&gt;
&lt;br /&gt;
You can also get another small boost if the new text you&amp;#039;re setting is the same length as the old text - this takes advantage of a health counter optimisation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
myElement.textContent = &amp;quot;1&amp;quot;;&lt;br /&gt;
myElement.textContent = &amp;quot;14&amp;quot;; // 1 character longer&lt;br /&gt;
&lt;br /&gt;
// Using 01 would make a (tiny) saving:&lt;br /&gt;
myElement.textContent = &amp;quot;01&amp;quot;;&lt;br /&gt;
myElement.textContent = &amp;quot;14&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disabling Unicode Bidirectionality ==&lt;br /&gt;
&lt;br /&gt;
If you have no plans to use right-to-left or bidirectional text (like Arabic mixed with English), disable it by deleting &amp;#039;&amp;#039;&amp;#039;PowerUI/Resources/BidirectionalData.bytes&amp;#039;&amp;#039;&amp;#039;. This will give you a small memory saving (about 10kb) and slightly boost text performance.&lt;br /&gt;
&lt;br /&gt;
You can also go further by specifying &amp;#039;&amp;#039;&amp;#039;NoBIDI&amp;#039;&amp;#039;&amp;#039; as a &amp;quot;scripting define symbols&amp;quot; as that will effectively remove all of the code which does the BIDI testing.&lt;br /&gt;
&lt;br /&gt;
== Avoid late loading CSS ==&lt;br /&gt;
&lt;br /&gt;
This is a massive performance drainer - avoid it! Put style as high up your document as you can (e.g. in head). That&amp;#039;s because a newly loaded CSS selector must &amp;#039;&amp;#039;check your entire DOM&amp;#039;&amp;#039; to see if they match any of the elements already in there. If your DOM is basically empty then this operation is much faster.&lt;br /&gt;
&lt;br /&gt;
Meanwhile, a newly loading element uses a range of indices to very rapidly figure out which selectors actually apply to it.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=804</id>
		<title>Performance</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=804"/>
				<updated>2018-03-21T18:49:56Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI puts performance first. A user interface has very different requirements from a web browser - compare the UI of your favourite games with just how stationary this wiki is, for example. A web browser focuses on making a page show up quickly where as a game will spend time loading to make sure it &amp;#039;&amp;#039;runs&amp;#039;&amp;#039; quickly. PowerUI has been built from scratch to fit the requirements of a high performance UI framework.&lt;br /&gt;
&lt;br /&gt;
In general, we only add support for something when we can get it working without affecting PowerUI&amp;#039;s overall speed. It&amp;#039;s working too - PowerUI can handle large volumes of HTML with little to no performance issues, whilst now simultaneously having very broad coverage of web technologies.&lt;br /&gt;
&lt;br /&gt;
However, PowerUI is vulnerable to being exposed to some very performance draining web techniques (and there are many of them!) so this is intended to be a short guide to understanding how web engines work and what you can do to avoid some common pitfalls.&lt;br /&gt;
&lt;br /&gt;
== Avoid searching for constant elements in Update ==&lt;br /&gt;
&lt;br /&gt;
This one is a common mistake but can also make great performance savings if you make some small changes. Here&amp;#039;s an example of what it looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
 &lt;br /&gt;
    // Don&amp;#039;t do this!&lt;br /&gt;
    var element = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PowerUI will try and index your IDs, but in general, this will result in scanning your whole DOM every single frame. You should just cache the element instead:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Element MyNavMenu;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    // Much better!&lt;br /&gt;
    MyNavMenu = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    // Use MyNavMenu in here&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Go event based - avoid spamming your UI in Update ==&lt;br /&gt;
&lt;br /&gt;
Although it&amp;#039;s ok to update your UI in the Update loop, for example for a timer, try being more event based for the greatest performance. For example, let&amp;#039;s say you pop up some info when the user clicks on an NPC. Rather than spamming some &amp;#039;SelectedNpc&amp;#039; field, update the UI when they&amp;#039;re actually clicked on:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;A common Unity anti-pattern - don&amp;#039;t do this!&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update() {&lt;br /&gt;
    // Bad!&lt;br /&gt;
    var headsUp = UI.document.getElementById(&amp;quot;npc-heads-up-info&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    if (SelectedNpc != null) {&lt;br /&gt;
        // Spamspamspamspamspam&lt;br /&gt;
        headsUp.innerHTML = SelectedNpc.HtmlDetails;&lt;br /&gt;
    } else {&lt;br /&gt;
        headsUp.innerHTML = &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead, set that innerHTML when you set SelectedNpc:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void SelectedAnNpc(Npc npc) {&lt;br /&gt;
    // Much better!&lt;br /&gt;
    SelectedNpc = npc;&lt;br /&gt;
&lt;br /&gt;
    // Update the UI:&lt;br /&gt;
    var headsUp = UI.document.getElementById(&amp;quot;npc-heads-up-info&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    if (SelectedNpc != null) {&lt;br /&gt;
        headsUp.innerHTML = SelectedNpc.HtmlDetails;&lt;br /&gt;
    } else {&lt;br /&gt;
        headsUp.innerHTML = &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PowerUI ships with a very powerful and extendible [Event Flow|standards compliant event system] - use this to your advantage. Selecting an NPC could fire off an NPC selection event, which some other class controlling your UI responds to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void SelectedAnNpc(Npc npc) {&lt;br /&gt;
    // Much better!&lt;br /&gt;
    SelectedNpc = npc;&lt;br /&gt;
    &lt;br /&gt;
    // Fire off an event which anything can subscribe to with a standard event listener on the document:&lt;br /&gt;
    NpcEvent e = new NpcEvent(&amp;quot;selected&amp;quot;);&lt;br /&gt;
    e.npc = npc;&lt;br /&gt;
    UI.document.dispatchEvent(e);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// .. somewhere else ..&lt;br /&gt;
&lt;br /&gt;
UI.document.addEventListener(&amp;quot;npcselected&amp;quot;, delegate(NpcEvent e){&lt;br /&gt;
    // Update the UI here, using e.npc instead.&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reflow ==&lt;br /&gt;
&lt;br /&gt;
Reflow is the name given when a web engine resolves CSS values and figures out where everything is on the screen. PowerUI also performs reflow, so following standard good practice for reducing reflow in a web browser applies to PowerUI too, so [https://developers.google.com/speed/articles/reflow here&amp;#039;s a guide that will help with just that]. You may have cases where your UI generates lots of reflows very fast - PowerUI internally meters this using UI.SetRate; it won&amp;#039;t reflow any more often than the rate you give.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #1: Use UI.SetRate and get it as low as you reasonably can. The default is 30fps with super smooth at 60fps.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Following similar lines, pulling properties such as contentHeight from an element will force a reflow to happen if the element is known to require one. Accessing the computed style (element.style.Computed.ContentHeight for example) does not force reflows, so if you know e.g. the height didn&amp;#039;t change then using computed styles directly can be a little quicker, but this only really applies if you&amp;#039;re doing a style change and then grabbing the contentHeight rapidly in a loop. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #2: Read from ComputedStyle where possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Skipping Reflow ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s possible to pull off a complex UI which only performs reflow a handful of times by focusing on post-process CSS properties. These are CSS properties which don&amp;#039;t affect the flow or structure of an element - the main examples are color, color-overlay, transform and the special case that is scroll. Generally try to animate these ones when you can!&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #3: Animate transforms (scale, rotate, translate) rather than positions (top, left, right etc) if possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Limiting reflow scope ===&lt;br /&gt;
&lt;br /&gt;
Reflow applies to the nearest &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; element. For example, let&amp;#039;s say you update the innerHTML of a fixed/absolute/sticky &amp;#039;&amp;#039;&amp;#039;positioned element&amp;#039;&amp;#039;&amp;#039; then &amp;#039;&amp;#039;only that element will actually reflow&amp;#039;&amp;#039;. The same applies to any of the nested kids of that positioned element - it&amp;#039;ll bubble up the DOM to the nearest flow root, and request to reflow that element. In short, making an element become a &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; is an easy way to massively limit how many elements reflow actually affects.&lt;br /&gt;
&lt;br /&gt;
== Table Chaos ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;PowerUI doesn&amp;#039;t support tables with no defined widths.&amp;#039;&amp;#039;&amp;#039; Tables cause multiple passes over potentially thousands of elements. The modern reason for using a table today is for vertical alignment - most other layouts can be easily done with other far less intense techniques. If it&amp;#039;s vertical align that you&amp;#039;re really after then use the custom vertical-align values on any element:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Middle vertical alignment without the overhead of table-cell/ tables */&lt;br /&gt;
vertical-align:table-middle;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On a similar line, tables with no defined column widths are outright evil. The number of elements scanned to guess how wide a column probably should be can go exponential very quickly and, after all of that, it often doesn&amp;#039;t look great anyway. As we&amp;#039;re making UIs which reflow very frequently, PowerUI requires you to give all your table columns and the table itself some kind of width value. This way PowerUI has unusually fast tables - making them suitable for heavy reflow - but they&amp;#039;re still slow compared to almost anything else.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #4: Use techniques other than table whenever appropriate, and make use of table-middle.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Memory Usage ==&lt;br /&gt;
&lt;br /&gt;
PowerUI is conservative about its memory usage, but if you&amp;#039;re targeting really low memory devices, turning off [[Image_Atlasing|image atlasing]] may be wise. Turning it off exchanges GPU/rendering time for lower memory and CPU use, which can be vital for pulling off a stunning UI on a device with little memory available.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #5: Turn off image atlasing for very low memory devices. See UI.RenderMode for doing that.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Multithreading ==&lt;br /&gt;
&lt;br /&gt;
Virtually all of PowerUI is multithreading friendly - anything that directly calls a Unity method like the geolocation web API isn&amp;#039;t. Presently the cookie cache (loading or setting cookies) is the only known PowerUI API which avoidably causes threading issues. Use PowerUI API&amp;#039;s directly from network threads, or spin up threads specifically for doing heavier UI work to make significant performance gains on multi-core architectures.&lt;br /&gt;
&lt;br /&gt;
== Canvas ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing to a canvas, there&amp;#039;s some nice savings you can be making. These savings are particularly noticeable if you&amp;#039;re drawing repeatedly, such as in Update.&lt;br /&gt;
&lt;br /&gt;
=== Only redraw your canvas when PowerUI does ===&lt;br /&gt;
PowerUI uploads the canvas image to the GPU no faster than your UI rate. Drawing your canvas any faster than that interval will essentially just waste cycles. We call that upload process a &amp;#039;refresh&amp;#039; - whenever you call stroke() or fill(), a refresh request is made (and then at some point in the near future, a refresh happens).&lt;br /&gt;
&lt;br /&gt;
So, if PowerUI already has an image which is ready but hasn&amp;#039;t been uploaded yet, there will be a pending refresh. Checking for that is like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
private CanvasContext2D Context;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
&lt;br /&gt;
    if(Context.ImageData.RefreshRequired){&lt;br /&gt;
        // This means we&amp;#039;ve already rendered something to the image data&lt;br /&gt;
        // and it&amp;#039;s just waiting to be uploaded. Rendering again would be a waste of time.&lt;br /&gt;
        // So, do nothing!&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Nothing to upload - draw it now!&lt;br /&gt;
    Context.beginPath();&lt;br /&gt;
    Context.moveTo(10,10);&lt;br /&gt;
    // ...&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multithreading canvas ===&lt;br /&gt;
&lt;br /&gt;
Like most PowerUI API&amp;#039;s, canvas is multithreading friendly. You could build those paths on some separate timer thread if you wanted to, for example.&lt;br /&gt;
&lt;br /&gt;
=== Cache your paths ===&lt;br /&gt;
&lt;br /&gt;
Whenever you call context.arcTo, context.lineTo etc, PowerUI internally builds up a representation of your path. When you then next call context.beginPath or context.clear, that representation is destroyed. If you&amp;#039;re drawing the same path over and over, it would be a great idea to save this internal representation rather than constantly rebuilding it to take some pressure off garbage collection.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you do this, it&amp;#039;s up to you to safely bound your points.&amp;#039;&amp;#039;&amp;#039; Normally the canvas API automatically takes care of points that are excessively out of range for you - things like infinity, NaN, or generally huge numbers. If you build a VectorPath and set it to a canvas, it&amp;#039;s important that you also guarantee your path doesn&amp;#039;t have any of those things. Internally, the canvas API runs VectorPath.Clip on all paths constructed via lineTo, arcTo etc. Otherwise, if you have an extremely long path then the canvas API will freeze whilst it outputs billions of pixels.&lt;br /&gt;
&lt;br /&gt;
To cache your paths you could either simply never call context.clear or context.beginPath and access Context.Path to move the nodes around like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI.&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
&lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // To clear the image but not the path, use ImageData:&lt;br /&gt;
    Context.ImageData.Clear();&lt;br /&gt;
&lt;br /&gt;
    // The path is totally empty if there&amp;#039;s no first node:&lt;br /&gt;
    if(Context.Path.FirstPathNode == null){&lt;br /&gt;
        &lt;br /&gt;
        // No path yet! Build it now:&lt;br /&gt;
        Context.moveTo(10,10);&lt;br /&gt;
        Context.lineTo(10,100);&lt;br /&gt;
        Context.lineTo(100,100);&lt;br /&gt;
        Context.lineTo(100,10);&lt;br /&gt;
        Context.closePath();&lt;br /&gt;
        &lt;br /&gt;
        // Note if any of the points in this first time call&lt;br /&gt;
        // go far out of range of the canvas, they may be &lt;br /&gt;
        // sliced for performance purposes.&lt;br /&gt;
        // For example, if your entire path is off canvas,&lt;br /&gt;
        // the whole thing may be dumped when you call stroke().&lt;br /&gt;
        &lt;br /&gt;
        // One way to avoid that uncertainty is to build the VectorPath directly (like below)&lt;br /&gt;
        // and then call VectorPath.Clip when it&amp;#039;s appropriate for your use case.&lt;br /&gt;
        &lt;br /&gt;
    }else{&lt;br /&gt;
        &lt;br /&gt;
        // E.g. update the nodes in the cachedPath:&lt;br /&gt;
        var point = CachedPath.FirstPathNode;&lt;br /&gt;
        &lt;br /&gt;
        // Our path has 5 points (alternatively loop until point is null).&lt;br /&gt;
        for(int i=0;i&amp;lt;5;i++){ // while(point!=null){&lt;br /&gt;
            &lt;br /&gt;
            // Move the point by the frame time:&lt;br /&gt;
            point.X += Time.deltaTime;&lt;br /&gt;
            &lt;br /&gt;
            // Go to the next point:&lt;br /&gt;
            point = point.Next;&lt;br /&gt;
          &lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Stroke or fill etc down here:&lt;br /&gt;
    Context.stroke();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing multiple paths and you want to cache them all, then the simpler route would be to directly build one or more VectorPath instances first:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI&lt;br /&gt;
using Blaze; // For VectorPath&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
/// &amp;lt;summary&amp;gt;A single cached path.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private VectorPath CachedPath;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    &lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // build the vector path(s):&lt;br /&gt;
    CachedPath = new VectorPath();&lt;br /&gt;
&lt;br /&gt;
    // The API is very similar - it&amp;#039;s capitalized as it&amp;#039;s part of the internal public API:&lt;br /&gt;
    CachedPath.MoveTo(10,10);&lt;br /&gt;
    CachedPath.LineTo(10,100);&lt;br /&gt;
    CachedPath.LineTo(100,100);&lt;br /&gt;
    CachedPath.LineTo(100,10);&lt;br /&gt;
    CachedPath.ClosePath();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // Calling normal clear doesn&amp;#039;t matter here (as we&amp;#039;re not using e.g. Context.lineTo)&lt;br /&gt;
    Context.clear();&lt;br /&gt;
    &lt;br /&gt;
    // E.g. update current path here:&lt;br /&gt;
    var point = CachedPath.FirstPathNode;&lt;br /&gt;
    &lt;br /&gt;
    // note that closed paths never make infinite loops here.&lt;br /&gt;
    // A close node simply overlaps the node it closes and has IsClose set to true.&lt;br /&gt;
    while(point!=null){&lt;br /&gt;
        point.X+=Time.deltaTime;&lt;br /&gt;
        point=point.Next;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Temporarily retain the path object in the canvas:&lt;br /&gt;
    VectorPath activePath = Canvas.Path;&lt;br /&gt;
    &lt;br /&gt;
    // Set ours:&lt;br /&gt;
    Canvas.Path = CachedPath;&lt;br /&gt;
    &lt;br /&gt;
    // Stroke it now:&lt;br /&gt;
    Canvas.stroke();&lt;br /&gt;
&lt;br /&gt;
    // Restore the other path:&lt;br /&gt;
    Canvas.Path = activePath;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Precompile PowerUI ==&lt;br /&gt;
&lt;br /&gt;
Performance applies to your development process too. Unless you&amp;#039;ve got a solid state hard drive, PowerUI can take some 15 seconds to compile. Every time you change any of your C# files. [[Precompiler|Precompile PowerUI]] by going to &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Precompile&amp;#039;&amp;#039;&amp;#039; then just tick the box - that will entirely eliminate this delay for you.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you change platform, or update Unity, you must precompile it again!&amp;#039;&amp;#039;&amp;#039; That&amp;#039;s because things like UNITY_ANDROID matter a lot.&lt;br /&gt;
&lt;br /&gt;
Note that precompiling does not affect custom tags etc, but it does affect any &amp;#039;&amp;#039;partial class extensions&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Set textContent rather than innerHTML ==&lt;br /&gt;
&lt;br /&gt;
If you know your text contains no HTML then setting to textContent will cause virtually everything to get recycled. Setting innerHTML is fast anyway but textContent does almost nothing.&lt;br /&gt;
&lt;br /&gt;
You can also get another small boost if the new text you&amp;#039;re setting is the same length as the old text - this takes advantage of a health counter optimisation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
myElement.textContent = &amp;quot;1&amp;quot;;&lt;br /&gt;
myElement.textContent = &amp;quot;14&amp;quot;; // 1 character longer&lt;br /&gt;
&lt;br /&gt;
// Using 01 would make a (tiny) saving:&lt;br /&gt;
myElement.textContent = &amp;quot;01&amp;quot;;&lt;br /&gt;
myElement.textContent = &amp;quot;14&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disabling Unicode Bidirectionality ==&lt;br /&gt;
&lt;br /&gt;
If you have no plans to use right-to-left or bidirectional text (like Arabic mixed with English), disable it by deleting &amp;#039;&amp;#039;&amp;#039;PowerUI/Resources/BidirectionalData.bytes&amp;#039;&amp;#039;&amp;#039;. This will give you a small memory saving (about 10kb) and slightly boost text performance.&lt;br /&gt;
&lt;br /&gt;
You can also go further by specifying &amp;#039;&amp;#039;&amp;#039;NoBIDI&amp;#039;&amp;#039;&amp;#039; as a &amp;quot;scripting define symbols&amp;quot; as that will effectively remove all of the code which does the BIDI testing.&lt;br /&gt;
&lt;br /&gt;
== Avoid late loading CSS ==&lt;br /&gt;
&lt;br /&gt;
This is a massive performance drainer - avoid it! Put style as high up your document as you can (e.g. in head). That&amp;#039;s because a newly loaded CSS selector must &amp;#039;&amp;#039;check your entire DOM&amp;#039;&amp;#039; to see if they match any of the elements already in there. If your DOM is basically empty then this operation is much faster.&lt;br /&gt;
&lt;br /&gt;
Meanwhile, a newly loading element uses a range of indices to very rapidly figure out which selectors actually apply to it.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=802</id>
		<title>Performance</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=802"/>
				<updated>2018-03-13T23:34:59Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Table Chaos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI puts performance first. A user interface has very different requirements from a web browser - compare the UI of your favourite games with just how stationary this wiki is, for example. A web browser focuses on making a page show up quickly where as a game will spend time loading to make sure it &amp;#039;&amp;#039;runs&amp;#039;&amp;#039; quickly. PowerUI has been built from scratch to fit the requirements of a high performance UI framework.&lt;br /&gt;
&lt;br /&gt;
In general, we only add support for something when we can get it working without affecting PowerUI&amp;#039;s overall speed. It&amp;#039;s working too - PowerUI can handle large volumes of HTML with little to no performance issues, whilst now simultaneously having very broad coverage of web technologies.&lt;br /&gt;
&lt;br /&gt;
However, PowerUI is vulnerable to being exposed to some very performance draining web techniques (and there are many of them!) so this is intended to be a short guide to understanding how web engines work and what you can do to avoid some common pitfalls.&lt;br /&gt;
&lt;br /&gt;
== Avoid searching for constant elements in Update ==&lt;br /&gt;
&lt;br /&gt;
This one is a common mistake but can also make great performance savings if you make some small changes. Here&amp;#039;s an example of what it looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
 &lt;br /&gt;
    // Don&amp;#039;t do this!&lt;br /&gt;
    var element = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PowerUI will try and index your IDs, but in general, this will result in scanning your whole DOM every single frame. You should just cache the element instead:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Element MyNavMenu;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    // Much better!&lt;br /&gt;
    MyNavMenu = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    // Use MyNavMenu in here&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reflow ==&lt;br /&gt;
&lt;br /&gt;
Reflow is the name given when a web engine resolves CSS values and figures out where everything is on the screen. PowerUI also performs reflow, so following standard good practice for reducing reflow in a web browser applies to PowerUI too, so [https://developers.google.com/speed/articles/reflow here&amp;#039;s a guide that will help with just that]. You may have cases where your UI generates lots of reflows very fast - PowerUI internally meters this using UI.SetRate; it won&amp;#039;t reflow any more often than the rate you give.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #1: Use UI.SetRate and get it as low as you reasonably can. The default is 30fps with super smooth at 60fps.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Following similar lines, pulling properties such as contentHeight from an element will force a reflow to happen if the element is known to require one. Accessing the computed style (element.style.Computed.ContentHeight for example) does not force reflows, so if you know e.g. the height didn&amp;#039;t change then using computed styles directly can be a little quicker, but this only really applies if you&amp;#039;re doing a style change and then grabbing the contentHeight rapidly in a loop. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #2: Read from ComputedStyle where possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Skipping Reflow ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s possible to pull off a complex UI which only performs reflow a handful of times by focusing on post-process CSS properties. These are CSS properties which don&amp;#039;t affect the flow or structure of an element - the main examples are color, color-overlay, transform and the special case that is scroll. Generally try to animate these ones when you can!&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #3: Animate transforms (scale, rotate, translate) rather than positions (top, left, right etc) if possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Limiting reflow scope ===&lt;br /&gt;
&lt;br /&gt;
Reflow applies to the nearest &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; element. For example, let&amp;#039;s say you update the innerHTML of a fixed/absolute/sticky &amp;#039;&amp;#039;&amp;#039;positioned element&amp;#039;&amp;#039;&amp;#039; then &amp;#039;&amp;#039;only that element will actually reflow&amp;#039;&amp;#039;. The same applies to any of the nested kids of that positioned element - it&amp;#039;ll bubble up the DOM to the nearest flow root, and request to reflow that element. In short, making an element become a &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; is an easy way to massively limit how many elements reflow actually affects.&lt;br /&gt;
&lt;br /&gt;
== Table Chaos ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;PowerUI doesn&amp;#039;t support tables with no defined widths.&amp;#039;&amp;#039;&amp;#039; Tables cause multiple passes over potentially thousands of elements. The modern reason for using a table today is for vertical alignment - most other layouts can be easily done with other far less intense techniques. If it&amp;#039;s vertical align that you&amp;#039;re really after then use the custom vertical-align values on any element:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Middle vertical alignment without the overhead of table-cell/ tables */&lt;br /&gt;
vertical-align:table-middle;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On a similar line, tables with no defined column widths are outright evil. The number of elements scanned to guess how wide a column probably should be can go exponential very quickly and, after all of that, it often doesn&amp;#039;t look great anyway. As we&amp;#039;re making UIs which reflow very frequently, PowerUI requires you to give all your table columns and the table itself some kind of width value. This way PowerUI has unusually fast tables - making them suitable for heavy reflow - but they&amp;#039;re still slow compared to almost anything else.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #4: Use techniques other than table whenever appropriate, and make use of table-middle.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Memory Usage ==&lt;br /&gt;
&lt;br /&gt;
PowerUI is conservative about its memory usage, but if you&amp;#039;re targeting really low memory devices, turning off [[Image_Atlasing|image atlasing]] may be wise. Turning it off exchanges GPU/rendering time for lower memory and CPU use, which can be vital for pulling off a stunning UI on a device with little memory available.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #5: Turn off image atlasing for very low memory devices. See UI.RenderMode for doing that.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Multithreading ==&lt;br /&gt;
&lt;br /&gt;
Virtually all of PowerUI is multithreading friendly - anything that directly calls a Unity method like the geolocation web API isn&amp;#039;t. Presently the cookie cache (loading or setting cookies) is the only known PowerUI API which avoidably causes threading issues. Use PowerUI API&amp;#039;s directly from network threads, or spin up threads specifically for doing heavier UI work to make significant performance gains on multi-core architectures.&lt;br /&gt;
&lt;br /&gt;
== Canvas ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing to a canvas, there&amp;#039;s some nice savings you can be making. These savings are particularly noticeable if you&amp;#039;re drawing repeatedly, such as in Update.&lt;br /&gt;
&lt;br /&gt;
=== Only redraw your canvas when PowerUI does ===&lt;br /&gt;
PowerUI uploads the canvas image to the GPU no faster than your UI rate. Drawing your canvas any faster than that interval will essentially just waste cycles. We call that upload process a &amp;#039;refresh&amp;#039; - whenever you call stroke() or fill(), a refresh request is made (and then at some point in the near future, a refresh happens).&lt;br /&gt;
&lt;br /&gt;
So, if PowerUI already has an image which is ready but hasn&amp;#039;t been uploaded yet, there will be a pending refresh. Checking for that is like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
private CanvasContext2D Context;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
&lt;br /&gt;
    if(Context.ImageData.RefreshRequired){&lt;br /&gt;
        // This means we&amp;#039;ve already rendered something to the image data&lt;br /&gt;
        // and it&amp;#039;s just waiting to be uploaded. Rendering again would be a waste of time.&lt;br /&gt;
        // So, do nothing!&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Nothing to upload - draw it now!&lt;br /&gt;
    Context.beginPath();&lt;br /&gt;
    Context.moveTo(10,10);&lt;br /&gt;
    // ...&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multithreading canvas ===&lt;br /&gt;
&lt;br /&gt;
Like most PowerUI API&amp;#039;s, canvas is multithreading friendly. You could build those paths on some separate timer thread if you wanted to, for example.&lt;br /&gt;
&lt;br /&gt;
=== Cache your paths ===&lt;br /&gt;
&lt;br /&gt;
Whenever you call context.arcTo, context.lineTo etc, PowerUI internally builds up a representation of your path. When you then next call context.beginPath or context.clear, that representation is destroyed. If you&amp;#039;re drawing the same path over and over, it would be a great idea to save this internal representation rather than constantly rebuilding it to take some pressure off garbage collection.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you do this, it&amp;#039;s up to you to safely bound your points.&amp;#039;&amp;#039;&amp;#039; Normally the canvas API automatically takes care of points that are excessively out of range for you - things like infinity, NaN, or generally huge numbers. If you build a VectorPath and set it to a canvas, it&amp;#039;s important that you also guarantee your path doesn&amp;#039;t have any of those things. Internally, the canvas API runs VectorPath.Clip on all paths constructed via lineTo, arcTo etc. Otherwise, if you have an extremely long path then the canvas API will freeze whilst it outputs billions of pixels.&lt;br /&gt;
&lt;br /&gt;
To cache your paths you could either simply never call context.clear or context.beginPath and access Context.Path to move the nodes around like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI.&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
&lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // To clear the image but not the path, use ImageData:&lt;br /&gt;
    Context.ImageData.Clear();&lt;br /&gt;
&lt;br /&gt;
    // The path is totally empty if there&amp;#039;s no first node:&lt;br /&gt;
    if(Context.Path.FirstPathNode == null){&lt;br /&gt;
        &lt;br /&gt;
        // No path yet! Build it now:&lt;br /&gt;
        Context.moveTo(10,10);&lt;br /&gt;
        Context.lineTo(10,100);&lt;br /&gt;
        Context.lineTo(100,100);&lt;br /&gt;
        Context.lineTo(100,10);&lt;br /&gt;
        Context.closePath();&lt;br /&gt;
        &lt;br /&gt;
        // Note if any of the points in this first time call&lt;br /&gt;
        // go far out of range of the canvas, they may be &lt;br /&gt;
        // sliced for performance purposes.&lt;br /&gt;
        // For example, if your entire path is off canvas,&lt;br /&gt;
        // the whole thing may be dumped when you call stroke().&lt;br /&gt;
        &lt;br /&gt;
        // One way to avoid that uncertainty is to build the VectorPath directly (like below)&lt;br /&gt;
        // and then call VectorPath.Clip when it&amp;#039;s appropriate for your use case.&lt;br /&gt;
        &lt;br /&gt;
    }else{&lt;br /&gt;
        &lt;br /&gt;
        // E.g. update the nodes in the cachedPath:&lt;br /&gt;
        var point = CachedPath.FirstPathNode;&lt;br /&gt;
        &lt;br /&gt;
        // Our path has 5 points (alternatively loop until point is null).&lt;br /&gt;
        for(int i=0;i&amp;lt;5;i++){ // while(point!=null){&lt;br /&gt;
            &lt;br /&gt;
            // Move the point by the frame time:&lt;br /&gt;
            point.X += Time.deltaTime;&lt;br /&gt;
            &lt;br /&gt;
            // Go to the next point:&lt;br /&gt;
            point = point.Next;&lt;br /&gt;
          &lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Stroke or fill etc down here:&lt;br /&gt;
    Context.stroke();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing multiple paths and you want to cache them all, then the simpler route would be to directly build one or more VectorPath instances first:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI&lt;br /&gt;
using Blaze; // For VectorPath&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
/// &amp;lt;summary&amp;gt;A single cached path.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private VectorPath CachedPath;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    &lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // build the vector path(s):&lt;br /&gt;
    CachedPath = new VectorPath();&lt;br /&gt;
&lt;br /&gt;
    // The API is very similar - it&amp;#039;s capitalized as it&amp;#039;s part of the internal public API:&lt;br /&gt;
    CachedPath.MoveTo(10,10);&lt;br /&gt;
    CachedPath.LineTo(10,100);&lt;br /&gt;
    CachedPath.LineTo(100,100);&lt;br /&gt;
    CachedPath.LineTo(100,10);&lt;br /&gt;
    CachedPath.ClosePath();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // Calling normal clear doesn&amp;#039;t matter here (as we&amp;#039;re not using e.g. Context.lineTo)&lt;br /&gt;
    Context.clear();&lt;br /&gt;
    &lt;br /&gt;
    // E.g. update current path here:&lt;br /&gt;
    var point = CachedPath.FirstPathNode;&lt;br /&gt;
    &lt;br /&gt;
    // note that closed paths never make infinite loops here.&lt;br /&gt;
    // A close node simply overlaps the node it closes and has IsClose set to true.&lt;br /&gt;
    while(point!=null){&lt;br /&gt;
        point.X+=Time.deltaTime;&lt;br /&gt;
        point=point.Next;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Temporarily retain the path object in the canvas:&lt;br /&gt;
    VectorPath activePath = Canvas.Path;&lt;br /&gt;
    &lt;br /&gt;
    // Set ours:&lt;br /&gt;
    Canvas.Path = CachedPath;&lt;br /&gt;
    &lt;br /&gt;
    // Stroke it now:&lt;br /&gt;
    Canvas.stroke();&lt;br /&gt;
&lt;br /&gt;
    // Restore the other path:&lt;br /&gt;
    Canvas.Path = activePath;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Precompile PowerUI ==&lt;br /&gt;
&lt;br /&gt;
Performance applies to your development process too. Unless you&amp;#039;ve got a solid state hard drive, PowerUI can take some 15 seconds to compile. Every time you change any of your C# files. [[Precompiler|Precompile PowerUI]] by going to &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Precompile&amp;#039;&amp;#039;&amp;#039; then just tick the box - that will entirely eliminate this delay for you.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you change platform, or update Unity, you must precompile it again!&amp;#039;&amp;#039;&amp;#039; That&amp;#039;s because things like UNITY_ANDROID matter a lot.&lt;br /&gt;
&lt;br /&gt;
Note that precompiling does not affect custom tags etc, but it does affect any &amp;#039;&amp;#039;partial class extensions&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Set textContent rather than innerHTML ==&lt;br /&gt;
&lt;br /&gt;
If you know your text contains no HTML then setting to textContent will cause virtually everything to get recycled. Setting innerHTML is fast anyway but textContent does almost nothing.&lt;br /&gt;
&lt;br /&gt;
You can also get another small boost if the new text you&amp;#039;re setting is the same length as the old text - this takes advantage of a health counter optimisation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
myElement.textContent = &amp;quot;1&amp;quot;;&lt;br /&gt;
myElement.textContent = &amp;quot;14&amp;quot;; // 1 character longer&lt;br /&gt;
&lt;br /&gt;
// Using 01 would make a (tiny) saving:&lt;br /&gt;
myElement.textContent = &amp;quot;01&amp;quot;;&lt;br /&gt;
myElement.textContent = &amp;quot;14&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disabling Unicode Bidirectionality ==&lt;br /&gt;
&lt;br /&gt;
If you have no plans to use right-to-left or bidirectional text (like Arabic mixed with English), disable it by deleting &amp;#039;&amp;#039;&amp;#039;PowerUI/Resources/BidirectionalData.bytes&amp;#039;&amp;#039;&amp;#039;. This will give you a small memory saving (about 10kb) and slightly boost text performance.&lt;br /&gt;
&lt;br /&gt;
You can also go further by specifying &amp;#039;&amp;#039;&amp;#039;NoBIDI&amp;#039;&amp;#039;&amp;#039; as a &amp;quot;scripting define symbols&amp;quot; as that will effectively remove all of the code which does the BIDI testing.&lt;br /&gt;
&lt;br /&gt;
== Avoid late loading CSS ==&lt;br /&gt;
&lt;br /&gt;
This is a massive performance drainer - avoid it! Put style as high up your document as you can (e.g. in head). That&amp;#039;s because a newly loaded CSS selector must &amp;#039;&amp;#039;check your entire DOM&amp;#039;&amp;#039; to see if they match any of the elements already in there. If your DOM is basically empty then this operation is much faster.&lt;br /&gt;
&lt;br /&gt;
Meanwhile, a newly loading element uses a range of indices to very rapidly figure out which selectors actually apply to it.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=801</id>
		<title>Performance</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=801"/>
				<updated>2018-03-13T23:32:21Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Table Chaos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI puts performance first. A user interface has very different requirements from a web browser - compare the UI of your favourite games with just how stationary this wiki is, for example. A web browser focuses on making a page show up quickly where as a game will spend time loading to make sure it &amp;#039;&amp;#039;runs&amp;#039;&amp;#039; quickly. PowerUI has been built from scratch to fit the requirements of a high performance UI framework.&lt;br /&gt;
&lt;br /&gt;
In general, we only add support for something when we can get it working without affecting PowerUI&amp;#039;s overall speed. It&amp;#039;s working too - PowerUI can handle large volumes of HTML with little to no performance issues, whilst now simultaneously having very broad coverage of web technologies.&lt;br /&gt;
&lt;br /&gt;
However, PowerUI is vulnerable to being exposed to some very performance draining web techniques (and there are many of them!) so this is intended to be a short guide to understanding how web engines work and what you can do to avoid some common pitfalls.&lt;br /&gt;
&lt;br /&gt;
== Avoid searching for constant elements in Update ==&lt;br /&gt;
&lt;br /&gt;
This one is a common mistake but can also make great performance savings if you make some small changes. Here&amp;#039;s an example of what it looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
 &lt;br /&gt;
    // Don&amp;#039;t do this!&lt;br /&gt;
    var element = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PowerUI will try and index your IDs, but in general, this will result in scanning your whole DOM every single frame. You should just cache the element instead:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Element MyNavMenu;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    // Much better!&lt;br /&gt;
    MyNavMenu = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    // Use MyNavMenu in here&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reflow ==&lt;br /&gt;
&lt;br /&gt;
Reflow is the name given when a web engine resolves CSS values and figures out where everything is on the screen. PowerUI also performs reflow, so following standard good practice for reducing reflow in a web browser applies to PowerUI too, so [https://developers.google.com/speed/articles/reflow here&amp;#039;s a guide that will help with just that]. You may have cases where your UI generates lots of reflows very fast - PowerUI internally meters this using UI.SetRate; it won&amp;#039;t reflow any more often than the rate you give.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #1: Use UI.SetRate and get it as low as you reasonably can. The default is 30fps with super smooth at 60fps.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Following similar lines, pulling properties such as contentHeight from an element will force a reflow to happen if the element is known to require one. Accessing the computed style (element.style.Computed.ContentHeight for example) does not force reflows, so if you know e.g. the height didn&amp;#039;t change then using computed styles directly can be a little quicker, but this only really applies if you&amp;#039;re doing a style change and then grabbing the contentHeight rapidly in a loop. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #2: Read from ComputedStyle where possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Skipping Reflow ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s possible to pull off a complex UI which only performs reflow a handful of times by focusing on post-process CSS properties. These are CSS properties which don&amp;#039;t affect the flow or structure of an element - the main examples are color, color-overlay, transform and the special case that is scroll. Generally try to animate these ones when you can!&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #3: Animate transforms (scale, rotate, translate) rather than positions (top, left, right etc) if possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Limiting reflow scope ===&lt;br /&gt;
&lt;br /&gt;
Reflow applies to the nearest &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; element. For example, let&amp;#039;s say you update the innerHTML of a fixed/absolute/sticky &amp;#039;&amp;#039;&amp;#039;positioned element&amp;#039;&amp;#039;&amp;#039; then &amp;#039;&amp;#039;only that element will actually reflow&amp;#039;&amp;#039;. The same applies to any of the nested kids of that positioned element - it&amp;#039;ll bubble up the DOM to the nearest flow root, and request to reflow that element. In short, making an element become a &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; is an easy way to massively limit how many elements reflow actually affects.&lt;br /&gt;
&lt;br /&gt;
== Table Chaos ==&lt;br /&gt;
&lt;br /&gt;
Tables cause multiple passes over potentially thousands of elements. The modern reason for using a table today is for vertical alignment - most other layouts can be easily done with other less intense techniques. If it&amp;#039;s vertical align that you&amp;#039;re really after then use the custom vertical-align values on any element:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Middle vertical alignment without the overhead of table-cell/ tables */&lt;br /&gt;
vertical-align:table-middle;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On a similar line, tables with no defined column widths are outright evil. The number of elements scanned to guess how wide a column probably should be can go exponential very quickly and after all of that, it often doesn&amp;#039;t look great anyway. As a result, &amp;#039;&amp;#039;&amp;#039;PowerUI doesn&amp;#039;t support tables with no defined widths&amp;#039;&amp;#039;&amp;#039; - you must give all your table columns and the table itself some kind of width value.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #4: Use techniques other than table whenever appropriate, and make use of table-middle.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Memory Usage ==&lt;br /&gt;
&lt;br /&gt;
PowerUI is conservative about its memory usage, but if you&amp;#039;re targeting really low memory devices, turning off [[Image_Atlasing|image atlasing]] may be wise. Turning it off exchanges GPU/rendering time for lower memory and CPU use, which can be vital for pulling off a stunning UI on a device with little memory available.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #5: Turn off image atlasing for very low memory devices. See UI.RenderMode for doing that.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Multithreading ==&lt;br /&gt;
&lt;br /&gt;
Virtually all of PowerUI is multithreading friendly - anything that directly calls a Unity method like the geolocation web API isn&amp;#039;t. Presently the cookie cache (loading or setting cookies) is the only known PowerUI API which avoidably causes threading issues. Use PowerUI API&amp;#039;s directly from network threads, or spin up threads specifically for doing heavier UI work to make significant performance gains on multi-core architectures.&lt;br /&gt;
&lt;br /&gt;
== Canvas ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing to a canvas, there&amp;#039;s some nice savings you can be making. These savings are particularly noticeable if you&amp;#039;re drawing repeatedly, such as in Update.&lt;br /&gt;
&lt;br /&gt;
=== Only redraw your canvas when PowerUI does ===&lt;br /&gt;
PowerUI uploads the canvas image to the GPU no faster than your UI rate. Drawing your canvas any faster than that interval will essentially just waste cycles. We call that upload process a &amp;#039;refresh&amp;#039; - whenever you call stroke() or fill(), a refresh request is made (and then at some point in the near future, a refresh happens).&lt;br /&gt;
&lt;br /&gt;
So, if PowerUI already has an image which is ready but hasn&amp;#039;t been uploaded yet, there will be a pending refresh. Checking for that is like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
private CanvasContext2D Context;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
&lt;br /&gt;
    if(Context.ImageData.RefreshRequired){&lt;br /&gt;
        // This means we&amp;#039;ve already rendered something to the image data&lt;br /&gt;
        // and it&amp;#039;s just waiting to be uploaded. Rendering again would be a waste of time.&lt;br /&gt;
        // So, do nothing!&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Nothing to upload - draw it now!&lt;br /&gt;
    Context.beginPath();&lt;br /&gt;
    Context.moveTo(10,10);&lt;br /&gt;
    // ...&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multithreading canvas ===&lt;br /&gt;
&lt;br /&gt;
Like most PowerUI API&amp;#039;s, canvas is multithreading friendly. You could build those paths on some separate timer thread if you wanted to, for example.&lt;br /&gt;
&lt;br /&gt;
=== Cache your paths ===&lt;br /&gt;
&lt;br /&gt;
Whenever you call context.arcTo, context.lineTo etc, PowerUI internally builds up a representation of your path. When you then next call context.beginPath or context.clear, that representation is destroyed. If you&amp;#039;re drawing the same path over and over, it would be a great idea to save this internal representation rather than constantly rebuilding it to take some pressure off garbage collection.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you do this, it&amp;#039;s up to you to safely bound your points.&amp;#039;&amp;#039;&amp;#039; Normally the canvas API automatically takes care of points that are excessively out of range for you - things like infinity, NaN, or generally huge numbers. If you build a VectorPath and set it to a canvas, it&amp;#039;s important that you also guarantee your path doesn&amp;#039;t have any of those things. Internally, the canvas API runs VectorPath.Clip on all paths constructed via lineTo, arcTo etc. Otherwise, if you have an extremely long path then the canvas API will freeze whilst it outputs billions of pixels.&lt;br /&gt;
&lt;br /&gt;
To cache your paths you could either simply never call context.clear or context.beginPath and access Context.Path to move the nodes around like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI.&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
&lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // To clear the image but not the path, use ImageData:&lt;br /&gt;
    Context.ImageData.Clear();&lt;br /&gt;
&lt;br /&gt;
    // The path is totally empty if there&amp;#039;s no first node:&lt;br /&gt;
    if(Context.Path.FirstPathNode == null){&lt;br /&gt;
        &lt;br /&gt;
        // No path yet! Build it now:&lt;br /&gt;
        Context.moveTo(10,10);&lt;br /&gt;
        Context.lineTo(10,100);&lt;br /&gt;
        Context.lineTo(100,100);&lt;br /&gt;
        Context.lineTo(100,10);&lt;br /&gt;
        Context.closePath();&lt;br /&gt;
        &lt;br /&gt;
        // Note if any of the points in this first time call&lt;br /&gt;
        // go far out of range of the canvas, they may be &lt;br /&gt;
        // sliced for performance purposes.&lt;br /&gt;
        // For example, if your entire path is off canvas,&lt;br /&gt;
        // the whole thing may be dumped when you call stroke().&lt;br /&gt;
        &lt;br /&gt;
        // One way to avoid that uncertainty is to build the VectorPath directly (like below)&lt;br /&gt;
        // and then call VectorPath.Clip when it&amp;#039;s appropriate for your use case.&lt;br /&gt;
        &lt;br /&gt;
    }else{&lt;br /&gt;
        &lt;br /&gt;
        // E.g. update the nodes in the cachedPath:&lt;br /&gt;
        var point = CachedPath.FirstPathNode;&lt;br /&gt;
        &lt;br /&gt;
        // Our path has 5 points (alternatively loop until point is null).&lt;br /&gt;
        for(int i=0;i&amp;lt;5;i++){ // while(point!=null){&lt;br /&gt;
            &lt;br /&gt;
            // Move the point by the frame time:&lt;br /&gt;
            point.X += Time.deltaTime;&lt;br /&gt;
            &lt;br /&gt;
            // Go to the next point:&lt;br /&gt;
            point = point.Next;&lt;br /&gt;
          &lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Stroke or fill etc down here:&lt;br /&gt;
    Context.stroke();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing multiple paths and you want to cache them all, then the simpler route would be to directly build one or more VectorPath instances first:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI&lt;br /&gt;
using Blaze; // For VectorPath&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
/// &amp;lt;summary&amp;gt;A single cached path.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private VectorPath CachedPath;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    &lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // build the vector path(s):&lt;br /&gt;
    CachedPath = new VectorPath();&lt;br /&gt;
&lt;br /&gt;
    // The API is very similar - it&amp;#039;s capitalized as it&amp;#039;s part of the internal public API:&lt;br /&gt;
    CachedPath.MoveTo(10,10);&lt;br /&gt;
    CachedPath.LineTo(10,100);&lt;br /&gt;
    CachedPath.LineTo(100,100);&lt;br /&gt;
    CachedPath.LineTo(100,10);&lt;br /&gt;
    CachedPath.ClosePath();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // Calling normal clear doesn&amp;#039;t matter here (as we&amp;#039;re not using e.g. Context.lineTo)&lt;br /&gt;
    Context.clear();&lt;br /&gt;
    &lt;br /&gt;
    // E.g. update current path here:&lt;br /&gt;
    var point = CachedPath.FirstPathNode;&lt;br /&gt;
    &lt;br /&gt;
    // note that closed paths never make infinite loops here.&lt;br /&gt;
    // A close node simply overlaps the node it closes and has IsClose set to true.&lt;br /&gt;
    while(point!=null){&lt;br /&gt;
        point.X+=Time.deltaTime;&lt;br /&gt;
        point=point.Next;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Temporarily retain the path object in the canvas:&lt;br /&gt;
    VectorPath activePath = Canvas.Path;&lt;br /&gt;
    &lt;br /&gt;
    // Set ours:&lt;br /&gt;
    Canvas.Path = CachedPath;&lt;br /&gt;
    &lt;br /&gt;
    // Stroke it now:&lt;br /&gt;
    Canvas.stroke();&lt;br /&gt;
&lt;br /&gt;
    // Restore the other path:&lt;br /&gt;
    Canvas.Path = activePath;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Precompile PowerUI ==&lt;br /&gt;
&lt;br /&gt;
Performance applies to your development process too. Unless you&amp;#039;ve got a solid state hard drive, PowerUI can take some 15 seconds to compile. Every time you change any of your C# files. [[Precompiler|Precompile PowerUI]] by going to &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Precompile&amp;#039;&amp;#039;&amp;#039; then just tick the box - that will entirely eliminate this delay for you.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you change platform, or update Unity, you must precompile it again!&amp;#039;&amp;#039;&amp;#039; That&amp;#039;s because things like UNITY_ANDROID matter a lot.&lt;br /&gt;
&lt;br /&gt;
Note that precompiling does not affect custom tags etc, but it does affect any &amp;#039;&amp;#039;partial class extensions&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Set textContent rather than innerHTML ==&lt;br /&gt;
&lt;br /&gt;
If you know your text contains no HTML then setting to textContent will cause virtually everything to get recycled. Setting innerHTML is fast anyway but textContent does almost nothing.&lt;br /&gt;
&lt;br /&gt;
You can also get another small boost if the new text you&amp;#039;re setting is the same length as the old text - this takes advantage of a health counter optimisation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
myElement.textContent = &amp;quot;1&amp;quot;;&lt;br /&gt;
myElement.textContent = &amp;quot;14&amp;quot;; // 1 character longer&lt;br /&gt;
&lt;br /&gt;
// Using 01 would make a (tiny) saving:&lt;br /&gt;
myElement.textContent = &amp;quot;01&amp;quot;;&lt;br /&gt;
myElement.textContent = &amp;quot;14&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disabling Unicode Bidirectionality ==&lt;br /&gt;
&lt;br /&gt;
If you have no plans to use right-to-left or bidirectional text (like Arabic mixed with English), disable it by deleting &amp;#039;&amp;#039;&amp;#039;PowerUI/Resources/BidirectionalData.bytes&amp;#039;&amp;#039;&amp;#039;. This will give you a small memory saving (about 10kb) and slightly boost text performance.&lt;br /&gt;
&lt;br /&gt;
You can also go further by specifying &amp;#039;&amp;#039;&amp;#039;NoBIDI&amp;#039;&amp;#039;&amp;#039; as a &amp;quot;scripting define symbols&amp;quot; as that will effectively remove all of the code which does the BIDI testing.&lt;br /&gt;
&lt;br /&gt;
== Avoid late loading CSS ==&lt;br /&gt;
&lt;br /&gt;
This is a massive performance drainer - avoid it! Put style as high up your document as you can (e.g. in head). That&amp;#039;s because a newly loaded CSS selector must &amp;#039;&amp;#039;check your entire DOM&amp;#039;&amp;#039; to see if they match any of the elements already in there. If your DOM is basically empty then this operation is much faster.&lt;br /&gt;
&lt;br /&gt;
Meanwhile, a newly loading element uses a range of indices to very rapidly figure out which selectors actually apply to it.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Linear_lighting&amp;diff=800</id>
		<title>Linear lighting</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Linear_lighting&amp;diff=800"/>
				<updated>2018-02-19T01:51:38Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you&amp;#039;d like to use a linear lighting workflow in your project, you&amp;#039;ll need to define a flag which tells PowerUI it should use the linear colour flow. If this flag isn&amp;#039;t set, colours of your UI can appear a little off (either too bright, or too dark, depending on the colour).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;To set the linear flag&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
* Open your current platform build settings&lt;br /&gt;
* Look for the text field called custom defines&lt;br /&gt;
* Add &amp;#039;&amp;#039;&amp;#039;LINEAR&amp;#039;&amp;#039;&amp;#039; in here&lt;br /&gt;
&lt;br /&gt;
When you click out of the field, Unity will recompile your code and PowerUI will then be in linear lighting mode.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Linear_lighting&amp;diff=799</id>
		<title>Linear lighting</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Linear_lighting&amp;diff=799"/>
				<updated>2018-02-19T01:51:08Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you&amp;#039;d like to use a linear lighting workflow in your project, you&amp;#039;ll need to define a flag which tells PowerUI it should use the linear colour flow. If this flag isn&amp;#039;t set, colours of your UI can appear a little off (either too bright, or too dark, depending on the colour).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;To set the linear flag&amp;#039;&amp;#039;&amp;#039;, open your current platform build settings and look for the text field called custom defines. Add &amp;#039;&amp;#039;&amp;#039;LINEAR&amp;#039;&amp;#039;&amp;#039; in here and when you click out of the field, Unity will recompile your code and PowerUI will then be in linear lighting mode.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Linear_lighting&amp;diff=798</id>
		<title>Linear lighting</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Linear_lighting&amp;diff=798"/>
				<updated>2018-02-19T01:50:44Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: Created page with &amp;quot;If you&amp;#039;d like to use a linear lighting workflow in your project, you&amp;#039;ll need to define a flag which tells PowerUI it should use the linear colour flow. If this flag isn&amp;#039;t set,...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you&amp;#039;d like to use a linear lighting workflow in your project, you&amp;#039;ll need to define a flag which tells PowerUI it should use the linear colour flow. If this flag isn&amp;#039;t set, colours of your UI can appear a little off (either too bright, or too dark, depending on the colour).&lt;br /&gt;
&lt;br /&gt;
To set the linear flag, open your current platform build settings and look for the text field called custom defines. Add `LINEAR` in here and when you click out of the field, Unity will recompile your code and PowerUI will then be in linear lighting mode.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=772</id>
		<title>Performance</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=772"/>
				<updated>2017-05-01T18:17:55Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Set textContent rather than innerHTML */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI puts performance first. A user interface has very different requirements from a web browser - compare the UI of your favourite games with just how stationary this wiki is, for example. A web browser focuses on making a page show up quickly where as a game will spend time loading to make sure it &amp;#039;&amp;#039;runs&amp;#039;&amp;#039; quickly. PowerUI has been built from scratch to fit the requirements of a high performance UI framework.&lt;br /&gt;
&lt;br /&gt;
In general, we only add support for something when we can get it working without affecting PowerUI&amp;#039;s overall speed. It&amp;#039;s working too - PowerUI can handle large volumes of HTML with little to no performance issues, whilst now simultaneously having very broad coverage of web technologies.&lt;br /&gt;
&lt;br /&gt;
However, PowerUI is vulnerable to being exposed to some very performance draining web techniques (and there are many of them!) so this is intended to be a short guide to understanding how web engines work and what you can do to avoid some common pitfalls.&lt;br /&gt;
&lt;br /&gt;
== Avoid searching for constant elements in Update ==&lt;br /&gt;
&lt;br /&gt;
This one is a common mistake but can also make great performance savings if you make some small changes. Here&amp;#039;s an example of what it looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
 &lt;br /&gt;
    // Don&amp;#039;t do this!&lt;br /&gt;
    var element = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PowerUI will try and index your IDs, but in general, this will result in scanning your whole DOM every single frame. You should just cache the element instead:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Element MyNavMenu;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    // Much better!&lt;br /&gt;
    MyNavMenu = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    // Use MyNavMenu in here&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reflow ==&lt;br /&gt;
&lt;br /&gt;
Reflow is the name given when a web engine resolves CSS values and figures out where everything is on the screen. PowerUI also performs reflow, so following standard good practice for reducing reflow in a web browser applies to PowerUI too, so [https://developers.google.com/speed/articles/reflow here&amp;#039;s a guide that will help with just that]. You may have cases where your UI generates lots of reflows very fast - PowerUI internally meters this using UI.SetRate; it won&amp;#039;t reflow any more often than the rate you give.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #1: Use UI.SetRate and get it as low as you reasonably can. The default is 30fps with super smooth at 60fps.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Following similar lines, pulling properties such as contentHeight from an element will force a reflow to happen if the element is known to require one. Accessing the computed style (element.style.Computed.ContentHeight for example) does not force reflows, so if you know e.g. the height didn&amp;#039;t change then using computed styles directly can be a little quicker, but this only really applies if you&amp;#039;re doing a style change and then grabbing the contentHeight rapidly in a loop. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #2: Read from ComputedStyle where possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Skipping Reflow ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s possible to pull off a complex UI which only performs reflow a handful of times by focusing on post-process CSS properties. These are CSS properties which don&amp;#039;t affect the flow or structure of an element - the main examples are color, color-overlay, transform and the special case that is scroll. Generally try to animate these ones when you can!&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #3: Animate transforms (scale, rotate, translate) rather than positions (top, left, right etc) if possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Limiting reflow scope ===&lt;br /&gt;
&lt;br /&gt;
Reflow applies to the nearest &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; element. For example, let&amp;#039;s say you update the innerHTML of a fixed/absolute/sticky &amp;#039;&amp;#039;&amp;#039;positioned element&amp;#039;&amp;#039;&amp;#039; then &amp;#039;&amp;#039;only that element will actually reflow&amp;#039;&amp;#039;. The same applies to any of the nested kids of that positioned element - it&amp;#039;ll bubble up the DOM to the nearest flow root, and request to reflow that element. In short, making an element become a &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; is an easy way to massively limit how many elements reflow actually affects.&lt;br /&gt;
&lt;br /&gt;
== Table Chaos ==&lt;br /&gt;
&lt;br /&gt;
Tables cause multiple passes over potentially thousands of elements. The modern reason for using a table today is for vertical alignment - most other layouts can be easily done with other less intense techniques. If it&amp;#039;s vertical align that you&amp;#039;re really after then use the custom vertical-align values on any element:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Middle vertical alignment without the overhead of table-cell/ tables */&lt;br /&gt;
vertical-align:table-middle;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #4: Use techniques other than table whenever appropriate, and make use of table-middle.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Memory Usage ==&lt;br /&gt;
&lt;br /&gt;
PowerUI is conservative about its memory usage, but if you&amp;#039;re targeting really low memory devices, turning off [[Image_Atlasing|image atlasing]] may be wise. Turning it off exchanges GPU/rendering time for lower memory and CPU use, which can be vital for pulling off a stunning UI on a device with little memory available.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #5: Turn off image atlasing for very low memory devices. See UI.RenderMode for doing that.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Multithreading ==&lt;br /&gt;
&lt;br /&gt;
Virtually all of PowerUI is multithreading friendly - anything that directly calls a Unity method like the geolocation web API isn&amp;#039;t. Presently the cookie cache (loading or setting cookies) is the only known PowerUI API which avoidably causes threading issues. Use PowerUI API&amp;#039;s directly from network threads, or spin up threads specifically for doing heavier UI work to make significant performance gains on multi-core architectures.&lt;br /&gt;
&lt;br /&gt;
== Canvas ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing to a canvas, there&amp;#039;s some nice savings you can be making. These savings are particularly noticeable if you&amp;#039;re drawing repeatedly, such as in Update.&lt;br /&gt;
&lt;br /&gt;
=== Only redraw your canvas when PowerUI does ===&lt;br /&gt;
PowerUI uploads the canvas image to the GPU no faster than your UI rate. Drawing your canvas any faster than that interval will essentially just waste cycles. We call that upload process a &amp;#039;refresh&amp;#039; - whenever you call stroke() or fill(), a refresh request is made (and then at some point in the near future, a refresh happens).&lt;br /&gt;
&lt;br /&gt;
So, if PowerUI already has an image which is ready but hasn&amp;#039;t been uploaded yet, there will be a pending refresh. Checking for that is like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
private CanvasContext2D Context;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
&lt;br /&gt;
    if(Context.ImageData.RefreshRequired){&lt;br /&gt;
        // This means we&amp;#039;ve already rendered something to the image data&lt;br /&gt;
        // and it&amp;#039;s just waiting to be uploaded. Rendering again would be a waste of time.&lt;br /&gt;
        // So, do nothing!&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Nothing to upload - draw it now!&lt;br /&gt;
    Context.beginPath();&lt;br /&gt;
    Context.moveTo(10,10);&lt;br /&gt;
    // ...&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multithreading canvas ===&lt;br /&gt;
&lt;br /&gt;
Like most PowerUI API&amp;#039;s, canvas is multithreading friendly. You could build those paths on some separate timer thread if you wanted to, for example.&lt;br /&gt;
&lt;br /&gt;
=== Cache your paths ===&lt;br /&gt;
&lt;br /&gt;
Whenever you call context.arcTo, context.lineTo etc, PowerUI internally builds up a representation of your path. When you then next call context.beginPath or context.clear, that representation is destroyed. If you&amp;#039;re drawing the same path over and over, it would be a great idea to save this internal representation rather than constantly rebuilding it to take some pressure off garbage collection.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you do this, it&amp;#039;s up to you to safely bound your points.&amp;#039;&amp;#039;&amp;#039; Normally the canvas API automatically takes care of points that are excessively out of range for you - things like infinity, NaN, or generally huge numbers. If you build a VectorPath and set it to a canvas, it&amp;#039;s important that you also guarantee your path doesn&amp;#039;t have any of those things. Internally, the canvas API runs VectorPath.Clip on all paths constructed via lineTo, arcTo etc. Otherwise, if you have an extremely long path then the canvas API will freeze whilst it outputs billions of pixels.&lt;br /&gt;
&lt;br /&gt;
To cache your paths you could either simply never call context.clear or context.beginPath and access Context.Path to move the nodes around like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI.&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
&lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // To clear the image but not the path, use ImageData:&lt;br /&gt;
    Context.ImageData.Clear();&lt;br /&gt;
&lt;br /&gt;
    // The path is totally empty if there&amp;#039;s no first node:&lt;br /&gt;
    if(Context.Path.FirstPathNode == null){&lt;br /&gt;
        &lt;br /&gt;
        // No path yet! Build it now:&lt;br /&gt;
        Context.moveTo(10,10);&lt;br /&gt;
        Context.lineTo(10,100);&lt;br /&gt;
        Context.lineTo(100,100);&lt;br /&gt;
        Context.lineTo(100,10);&lt;br /&gt;
        Context.closePath();&lt;br /&gt;
        &lt;br /&gt;
        // Note if any of the points in this first time call&lt;br /&gt;
        // go far out of range of the canvas, they may be &lt;br /&gt;
        // sliced for performance purposes.&lt;br /&gt;
        // For example, if your entire path is off canvas,&lt;br /&gt;
        // the whole thing may be dumped when you call stroke().&lt;br /&gt;
        &lt;br /&gt;
        // One way to avoid that uncertainty is to build the VectorPath directly (like below)&lt;br /&gt;
        // and then call VectorPath.Clip when it&amp;#039;s appropriate for your use case.&lt;br /&gt;
        &lt;br /&gt;
    }else{&lt;br /&gt;
        &lt;br /&gt;
        // E.g. update the nodes in the cachedPath:&lt;br /&gt;
        var point = CachedPath.FirstPathNode;&lt;br /&gt;
        &lt;br /&gt;
        // Our path has 5 points (alternatively loop until point is null).&lt;br /&gt;
        for(int i=0;i&amp;lt;5;i++){ // while(point!=null){&lt;br /&gt;
            &lt;br /&gt;
            // Move the point by the frame time:&lt;br /&gt;
            point.X += Time.deltaTime;&lt;br /&gt;
            &lt;br /&gt;
            // Go to the next point:&lt;br /&gt;
            point = point.Next;&lt;br /&gt;
          &lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Stroke or fill etc down here:&lt;br /&gt;
    Context.stroke();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing multiple paths and you want to cache them all, then the simpler route would be to directly build one or more VectorPath instances first:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI&lt;br /&gt;
using Blaze; // For VectorPath&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
/// &amp;lt;summary&amp;gt;A single cached path.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private VectorPath CachedPath;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    &lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // build the vector path(s):&lt;br /&gt;
    CachedPath = new VectorPath();&lt;br /&gt;
&lt;br /&gt;
    // The API is very similar - it&amp;#039;s capitalized as it&amp;#039;s part of the internal public API:&lt;br /&gt;
    CachedPath.MoveTo(10,10);&lt;br /&gt;
    CachedPath.LineTo(10,100);&lt;br /&gt;
    CachedPath.LineTo(100,100);&lt;br /&gt;
    CachedPath.LineTo(100,10);&lt;br /&gt;
    CachedPath.ClosePath();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // Calling normal clear doesn&amp;#039;t matter here (as we&amp;#039;re not using e.g. Context.lineTo)&lt;br /&gt;
    Context.clear();&lt;br /&gt;
    &lt;br /&gt;
    // E.g. update current path here:&lt;br /&gt;
    var point = CachedPath.FirstPathNode;&lt;br /&gt;
    &lt;br /&gt;
    // note that closed paths never make infinite loops here.&lt;br /&gt;
    // A close node simply overlaps the node it closes and has IsClose set to true.&lt;br /&gt;
    while(point!=null){&lt;br /&gt;
        point.X+=Time.deltaTime;&lt;br /&gt;
        point=point.Next;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Temporarily retain the path object in the canvas:&lt;br /&gt;
    VectorPath activePath = Canvas.Path;&lt;br /&gt;
    &lt;br /&gt;
    // Set ours:&lt;br /&gt;
    Canvas.Path = CachedPath;&lt;br /&gt;
    &lt;br /&gt;
    // Stroke it now:&lt;br /&gt;
    Canvas.stroke();&lt;br /&gt;
&lt;br /&gt;
    // Restore the other path:&lt;br /&gt;
    Canvas.Path = activePath;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Precompile PowerUI ==&lt;br /&gt;
&lt;br /&gt;
Performance applies to your development process too. Unless you&amp;#039;ve got a solid state hard drive, PowerUI can take some 15 seconds to compile. Every time you change any of your C# files. [[Precompiler|Precompile PowerUI]] by going to &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Precompile&amp;#039;&amp;#039;&amp;#039; then just tick the box - that will entirely eliminate this delay for you.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you change platform, or update Unity, you must precompile it again!&amp;#039;&amp;#039;&amp;#039; That&amp;#039;s because things like UNITY_ANDROID matter a lot.&lt;br /&gt;
&lt;br /&gt;
Note that precompiling does not affect custom tags etc, but it does affect any &amp;#039;&amp;#039;partial class extensions&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Set textContent rather than innerHTML ==&lt;br /&gt;
&lt;br /&gt;
If you know your text contains no HTML then setting to textContent will cause virtually everything to get recycled. Setting innerHTML is fast anyway but textContent does almost nothing.&lt;br /&gt;
&lt;br /&gt;
You can also get another small boost if the new text you&amp;#039;re setting is the same length as the old text - this takes advantage of a health counter optimisation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
myElement.textContent = &amp;quot;1&amp;quot;;&lt;br /&gt;
myElement.textContent = &amp;quot;14&amp;quot;; // 1 character longer&lt;br /&gt;
&lt;br /&gt;
// Using 01 would make a (tiny) saving:&lt;br /&gt;
myElement.textContent = &amp;quot;01&amp;quot;;&lt;br /&gt;
myElement.textContent = &amp;quot;14&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disabling Unicode Bidirectionality ==&lt;br /&gt;
&lt;br /&gt;
If you have no plans to use right-to-left or bidirectional text (like Arabic mixed with English), disable it by deleting &amp;#039;&amp;#039;&amp;#039;PowerUI/Resources/BidirectionalData.bytes&amp;#039;&amp;#039;&amp;#039;. This will give you a small memory saving (about 10kb) and slightly boost text performance.&lt;br /&gt;
&lt;br /&gt;
You can also go further by specifying &amp;#039;&amp;#039;&amp;#039;NoBIDI&amp;#039;&amp;#039;&amp;#039; as a &amp;quot;scripting define symbols&amp;quot; as that will effectively remove all of the code which does the BIDI testing.&lt;br /&gt;
&lt;br /&gt;
== Avoid late loading CSS ==&lt;br /&gt;
&lt;br /&gt;
This is a massive performance drainer - avoid it! Put style as high up your document as you can (e.g. in head). That&amp;#039;s because a newly loaded CSS selector must &amp;#039;&amp;#039;check your entire DOM&amp;#039;&amp;#039; to see if they match any of the elements already in there. If your DOM is basically empty then this operation is much faster.&lt;br /&gt;
&lt;br /&gt;
Meanwhile, a newly loading element uses a range of indices to very rapidly figure out which selectors actually apply to it.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Performance_Tips&amp;diff=771</id>
		<title>Performance Tips</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Performance_Tips&amp;diff=771"/>
				<updated>2017-05-01T18:13:34Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: Redirected page to Performance&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Performance]]&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=770</id>
		<title>Performance</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=770"/>
				<updated>2017-05-01T18:11:47Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Memory Usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI puts performance first. A user interface has very different requirements from a web browser - compare the UI of your favourite games with just how stationary this wiki is, for example. A web browser focuses on making a page show up quickly where as a game will spend time loading to make sure it &amp;#039;&amp;#039;runs&amp;#039;&amp;#039; quickly. PowerUI has been built from scratch to fit the requirements of a high performance UI framework.&lt;br /&gt;
&lt;br /&gt;
In general, we only add support for something when we can get it working without affecting PowerUI&amp;#039;s overall speed. It&amp;#039;s working too - PowerUI can handle large volumes of HTML with little to no performance issues, whilst now simultaneously having very broad coverage of web technologies.&lt;br /&gt;
&lt;br /&gt;
However, PowerUI is vulnerable to being exposed to some very performance draining web techniques (and there are many of them!) so this is intended to be a short guide to understanding how web engines work and what you can do to avoid some common pitfalls.&lt;br /&gt;
&lt;br /&gt;
== Avoid searching for constant elements in Update ==&lt;br /&gt;
&lt;br /&gt;
This one is a common mistake but can also make great performance savings if you make some small changes. Here&amp;#039;s an example of what it looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
 &lt;br /&gt;
    // Don&amp;#039;t do this!&lt;br /&gt;
    var element = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PowerUI will try and index your IDs, but in general, this will result in scanning your whole DOM every single frame. You should just cache the element instead:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Element MyNavMenu;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    // Much better!&lt;br /&gt;
    MyNavMenu = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    // Use MyNavMenu in here&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reflow ==&lt;br /&gt;
&lt;br /&gt;
Reflow is the name given when a web engine resolves CSS values and figures out where everything is on the screen. PowerUI also performs reflow, so following standard good practice for reducing reflow in a web browser applies to PowerUI too, so [https://developers.google.com/speed/articles/reflow here&amp;#039;s a guide that will help with just that]. You may have cases where your UI generates lots of reflows very fast - PowerUI internally meters this using UI.SetRate; it won&amp;#039;t reflow any more often than the rate you give.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #1: Use UI.SetRate and get it as low as you reasonably can. The default is 30fps with super smooth at 60fps.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Following similar lines, pulling properties such as contentHeight from an element will force a reflow to happen if the element is known to require one. Accessing the computed style (element.style.Computed.ContentHeight for example) does not force reflows, so if you know e.g. the height didn&amp;#039;t change then using computed styles directly can be a little quicker, but this only really applies if you&amp;#039;re doing a style change and then grabbing the contentHeight rapidly in a loop. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #2: Read from ComputedStyle where possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Skipping Reflow ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s possible to pull off a complex UI which only performs reflow a handful of times by focusing on post-process CSS properties. These are CSS properties which don&amp;#039;t affect the flow or structure of an element - the main examples are color, color-overlay, transform and the special case that is scroll. Generally try to animate these ones when you can!&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #3: Animate transforms (scale, rotate, translate) rather than positions (top, left, right etc) if possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Limiting reflow scope ===&lt;br /&gt;
&lt;br /&gt;
Reflow applies to the nearest &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; element. For example, let&amp;#039;s say you update the innerHTML of a fixed/absolute/sticky &amp;#039;&amp;#039;&amp;#039;positioned element&amp;#039;&amp;#039;&amp;#039; then &amp;#039;&amp;#039;only that element will actually reflow&amp;#039;&amp;#039;. The same applies to any of the nested kids of that positioned element - it&amp;#039;ll bubble up the DOM to the nearest flow root, and request to reflow that element. In short, making an element become a &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; is an easy way to massively limit how many elements reflow actually affects.&lt;br /&gt;
&lt;br /&gt;
== Table Chaos ==&lt;br /&gt;
&lt;br /&gt;
Tables cause multiple passes over potentially thousands of elements. The modern reason for using a table today is for vertical alignment - most other layouts can be easily done with other less intense techniques. If it&amp;#039;s vertical align that you&amp;#039;re really after then use the custom vertical-align values on any element:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Middle vertical alignment without the overhead of table-cell/ tables */&lt;br /&gt;
vertical-align:table-middle;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #4: Use techniques other than table whenever appropriate, and make use of table-middle.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Memory Usage ==&lt;br /&gt;
&lt;br /&gt;
PowerUI is conservative about its memory usage, but if you&amp;#039;re targeting really low memory devices, turning off [[Image_Atlasing|image atlasing]] may be wise. Turning it off exchanges GPU/rendering time for lower memory and CPU use, which can be vital for pulling off a stunning UI on a device with little memory available.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #5: Turn off image atlasing for very low memory devices. See UI.RenderMode for doing that.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Multithreading ==&lt;br /&gt;
&lt;br /&gt;
Virtually all of PowerUI is multithreading friendly - anything that directly calls a Unity method like the geolocation web API isn&amp;#039;t. Presently the cookie cache (loading or setting cookies) is the only known PowerUI API which avoidably causes threading issues. Use PowerUI API&amp;#039;s directly from network threads, or spin up threads specifically for doing heavier UI work to make significant performance gains on multi-core architectures.&lt;br /&gt;
&lt;br /&gt;
== Canvas ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing to a canvas, there&amp;#039;s some nice savings you can be making. These savings are particularly noticeable if you&amp;#039;re drawing repeatedly, such as in Update.&lt;br /&gt;
&lt;br /&gt;
=== Only redraw your canvas when PowerUI does ===&lt;br /&gt;
PowerUI uploads the canvas image to the GPU no faster than your UI rate. Drawing your canvas any faster than that interval will essentially just waste cycles. We call that upload process a &amp;#039;refresh&amp;#039; - whenever you call stroke() or fill(), a refresh request is made (and then at some point in the near future, a refresh happens).&lt;br /&gt;
&lt;br /&gt;
So, if PowerUI already has an image which is ready but hasn&amp;#039;t been uploaded yet, there will be a pending refresh. Checking for that is like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
private CanvasContext2D Context;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
&lt;br /&gt;
    if(Context.ImageData.RefreshRequired){&lt;br /&gt;
        // This means we&amp;#039;ve already rendered something to the image data&lt;br /&gt;
        // and it&amp;#039;s just waiting to be uploaded. Rendering again would be a waste of time.&lt;br /&gt;
        // So, do nothing!&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Nothing to upload - draw it now!&lt;br /&gt;
    Context.beginPath();&lt;br /&gt;
    Context.moveTo(10,10);&lt;br /&gt;
    // ...&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multithreading canvas ===&lt;br /&gt;
&lt;br /&gt;
Like most PowerUI API&amp;#039;s, canvas is multithreading friendly. You could build those paths on some separate timer thread if you wanted to, for example.&lt;br /&gt;
&lt;br /&gt;
=== Cache your paths ===&lt;br /&gt;
&lt;br /&gt;
Whenever you call context.arcTo, context.lineTo etc, PowerUI internally builds up a representation of your path. When you then next call context.beginPath or context.clear, that representation is destroyed. If you&amp;#039;re drawing the same path over and over, it would be a great idea to save this internal representation rather than constantly rebuilding it to take some pressure off garbage collection.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you do this, it&amp;#039;s up to you to safely bound your points.&amp;#039;&amp;#039;&amp;#039; Normally the canvas API automatically takes care of points that are excessively out of range for you - things like infinity, NaN, or generally huge numbers. If you build a VectorPath and set it to a canvas, it&amp;#039;s important that you also guarantee your path doesn&amp;#039;t have any of those things. Internally, the canvas API runs VectorPath.Clip on all paths constructed via lineTo, arcTo etc. Otherwise, if you have an extremely long path then the canvas API will freeze whilst it outputs billions of pixels.&lt;br /&gt;
&lt;br /&gt;
To cache your paths you could either simply never call context.clear or context.beginPath and access Context.Path to move the nodes around like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI.&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
&lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // To clear the image but not the path, use ImageData:&lt;br /&gt;
    Context.ImageData.Clear();&lt;br /&gt;
&lt;br /&gt;
    // The path is totally empty if there&amp;#039;s no first node:&lt;br /&gt;
    if(Context.Path.FirstPathNode == null){&lt;br /&gt;
        &lt;br /&gt;
        // No path yet! Build it now:&lt;br /&gt;
        Context.moveTo(10,10);&lt;br /&gt;
        Context.lineTo(10,100);&lt;br /&gt;
        Context.lineTo(100,100);&lt;br /&gt;
        Context.lineTo(100,10);&lt;br /&gt;
        Context.closePath();&lt;br /&gt;
        &lt;br /&gt;
        // Note if any of the points in this first time call&lt;br /&gt;
        // go far out of range of the canvas, they may be &lt;br /&gt;
        // sliced for performance purposes.&lt;br /&gt;
        // For example, if your entire path is off canvas,&lt;br /&gt;
        // the whole thing may be dumped when you call stroke().&lt;br /&gt;
        &lt;br /&gt;
        // One way to avoid that uncertainty is to build the VectorPath directly (like below)&lt;br /&gt;
        // and then call VectorPath.Clip when it&amp;#039;s appropriate for your use case.&lt;br /&gt;
        &lt;br /&gt;
    }else{&lt;br /&gt;
        &lt;br /&gt;
        // E.g. update the nodes in the cachedPath:&lt;br /&gt;
        var point = CachedPath.FirstPathNode;&lt;br /&gt;
        &lt;br /&gt;
        // Our path has 5 points (alternatively loop until point is null).&lt;br /&gt;
        for(int i=0;i&amp;lt;5;i++){ // while(point!=null){&lt;br /&gt;
            &lt;br /&gt;
            // Move the point by the frame time:&lt;br /&gt;
            point.X += Time.deltaTime;&lt;br /&gt;
            &lt;br /&gt;
            // Go to the next point:&lt;br /&gt;
            point = point.Next;&lt;br /&gt;
          &lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Stroke or fill etc down here:&lt;br /&gt;
    Context.stroke();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing multiple paths and you want to cache them all, then the simpler route would be to directly build one or more VectorPath instances first:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI&lt;br /&gt;
using Blaze; // For VectorPath&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
/// &amp;lt;summary&amp;gt;A single cached path.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private VectorPath CachedPath;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    &lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // build the vector path(s):&lt;br /&gt;
    CachedPath = new VectorPath();&lt;br /&gt;
&lt;br /&gt;
    // The API is very similar - it&amp;#039;s capitalized as it&amp;#039;s part of the internal public API:&lt;br /&gt;
    CachedPath.MoveTo(10,10);&lt;br /&gt;
    CachedPath.LineTo(10,100);&lt;br /&gt;
    CachedPath.LineTo(100,100);&lt;br /&gt;
    CachedPath.LineTo(100,10);&lt;br /&gt;
    CachedPath.ClosePath();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // Calling normal clear doesn&amp;#039;t matter here (as we&amp;#039;re not using e.g. Context.lineTo)&lt;br /&gt;
    Context.clear();&lt;br /&gt;
    &lt;br /&gt;
    // E.g. update current path here:&lt;br /&gt;
    var point = CachedPath.FirstPathNode;&lt;br /&gt;
    &lt;br /&gt;
    // note that closed paths never make infinite loops here.&lt;br /&gt;
    // A close node simply overlaps the node it closes and has IsClose set to true.&lt;br /&gt;
    while(point!=null){&lt;br /&gt;
        point.X+=Time.deltaTime;&lt;br /&gt;
        point=point.Next;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Temporarily retain the path object in the canvas:&lt;br /&gt;
    VectorPath activePath = Canvas.Path;&lt;br /&gt;
    &lt;br /&gt;
    // Set ours:&lt;br /&gt;
    Canvas.Path = CachedPath;&lt;br /&gt;
    &lt;br /&gt;
    // Stroke it now:&lt;br /&gt;
    Canvas.stroke();&lt;br /&gt;
&lt;br /&gt;
    // Restore the other path:&lt;br /&gt;
    Canvas.Path = activePath;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Precompile PowerUI ==&lt;br /&gt;
&lt;br /&gt;
Performance applies to your development process too. Unless you&amp;#039;ve got a solid state hard drive, PowerUI can take some 15 seconds to compile. Every time you change any of your C# files. [[Precompiler|Precompile PowerUI]] by going to &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Precompile&amp;#039;&amp;#039;&amp;#039; then just tick the box - that will entirely eliminate this delay for you.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you change platform, or update Unity, you must precompile it again!&amp;#039;&amp;#039;&amp;#039; That&amp;#039;s because things like UNITY_ANDROID matter a lot.&lt;br /&gt;
&lt;br /&gt;
Note that precompiling does not affect custom tags etc, but it does affect any &amp;#039;&amp;#039;partial class extensions&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Set textContent rather than innerHTML ==&lt;br /&gt;
&lt;br /&gt;
If you know your text contains no HTML then setting to textContent will cause virtually everything to get recycled. Setting innerHTML is fast anyway but textContent does almost nothing.&lt;br /&gt;
&lt;br /&gt;
== Disabling Unicode Bidirectionality ==&lt;br /&gt;
&lt;br /&gt;
If you have no plans to use right-to-left or bidirectional text (like Arabic mixed with English), disable it by deleting &amp;#039;&amp;#039;&amp;#039;PowerUI/Resources/BidirectionalData.bytes&amp;#039;&amp;#039;&amp;#039;. This will give you a small memory saving (about 10kb) and slightly boost text performance.&lt;br /&gt;
&lt;br /&gt;
You can also go further by specifying &amp;#039;&amp;#039;&amp;#039;NoBIDI&amp;#039;&amp;#039;&amp;#039; as a &amp;quot;scripting define symbols&amp;quot; as that will effectively remove all of the code which does the BIDI testing.&lt;br /&gt;
&lt;br /&gt;
== Avoid late loading CSS ==&lt;br /&gt;
&lt;br /&gt;
This is a massive performance drainer - avoid it! Put style as high up your document as you can (e.g. in head). That&amp;#039;s because a newly loaded CSS selector must &amp;#039;&amp;#039;check your entire DOM&amp;#039;&amp;#039; to see if they match any of the elements already in there. If your DOM is basically empty then this operation is much faster.&lt;br /&gt;
&lt;br /&gt;
Meanwhile, a newly loading element uses a range of indices to very rapidly figure out which selectors actually apply to it.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=769</id>
		<title>Performance</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Performance&amp;diff=769"/>
				<updated>2017-05-01T18:08:20Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI puts performance first. A user interface has very different requirements from a web browser - compare the UI of your favourite games with just how stationary this wiki is, for example. A web browser focuses on making a page show up quickly where as a game will spend time loading to make sure it &amp;#039;&amp;#039;runs&amp;#039;&amp;#039; quickly. PowerUI has been built from scratch to fit the requirements of a high performance UI framework.&lt;br /&gt;
&lt;br /&gt;
In general, we only add support for something when we can get it working without affecting PowerUI&amp;#039;s overall speed. It&amp;#039;s working too - PowerUI can handle large volumes of HTML with little to no performance issues, whilst now simultaneously having very broad coverage of web technologies.&lt;br /&gt;
&lt;br /&gt;
However, PowerUI is vulnerable to being exposed to some very performance draining web techniques (and there are many of them!) so this is intended to be a short guide to understanding how web engines work and what you can do to avoid some common pitfalls.&lt;br /&gt;
&lt;br /&gt;
== Avoid searching for constant elements in Update ==&lt;br /&gt;
&lt;br /&gt;
This one is a common mistake but can also make great performance savings if you make some small changes. Here&amp;#039;s an example of what it looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
 &lt;br /&gt;
    // Don&amp;#039;t do this!&lt;br /&gt;
    var element = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PowerUI will try and index your IDs, but in general, this will result in scanning your whole DOM every single frame. You should just cache the element instead:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Element MyNavMenu;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    // Much better!&lt;br /&gt;
    MyNavMenu = UI.document.getElementById(&amp;quot;my-nav-menu&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    // Use MyNavMenu in here&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reflow ==&lt;br /&gt;
&lt;br /&gt;
Reflow is the name given when a web engine resolves CSS values and figures out where everything is on the screen. PowerUI also performs reflow, so following standard good practice for reducing reflow in a web browser applies to PowerUI too, so [https://developers.google.com/speed/articles/reflow here&amp;#039;s a guide that will help with just that]. You may have cases where your UI generates lots of reflows very fast - PowerUI internally meters this using UI.SetRate; it won&amp;#039;t reflow any more often than the rate you give.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #1: Use UI.SetRate and get it as low as you reasonably can. The default is 30fps with super smooth at 60fps.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Following similar lines, pulling properties such as contentHeight from an element will force a reflow to happen if the element is known to require one. Accessing the computed style (element.style.Computed.ContentHeight for example) does not force reflows, so if you know e.g. the height didn&amp;#039;t change then using computed styles directly can be a little quicker, but this only really applies if you&amp;#039;re doing a style change and then grabbing the contentHeight rapidly in a loop. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #2: Read from ComputedStyle where possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Skipping Reflow ==&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s possible to pull off a complex UI which only performs reflow a handful of times by focusing on post-process CSS properties. These are CSS properties which don&amp;#039;t affect the flow or structure of an element - the main examples are color, color-overlay, transform and the special case that is scroll. Generally try to animate these ones when you can!&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #3: Animate transforms (scale, rotate, translate) rather than positions (top, left, right etc) if possible.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Limiting reflow scope ===&lt;br /&gt;
&lt;br /&gt;
Reflow applies to the nearest &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; element. For example, let&amp;#039;s say you update the innerHTML of a fixed/absolute/sticky &amp;#039;&amp;#039;&amp;#039;positioned element&amp;#039;&amp;#039;&amp;#039; then &amp;#039;&amp;#039;only that element will actually reflow&amp;#039;&amp;#039;. The same applies to any of the nested kids of that positioned element - it&amp;#039;ll bubble up the DOM to the nearest flow root, and request to reflow that element. In short, making an element become a &amp;#039;&amp;#039;flow root&amp;#039;&amp;#039; is an easy way to massively limit how many elements reflow actually affects.&lt;br /&gt;
&lt;br /&gt;
== Table Chaos ==&lt;br /&gt;
&lt;br /&gt;
Tables cause multiple passes over potentially thousands of elements. The modern reason for using a table today is for vertical alignment - most other layouts can be easily done with other less intense techniques. If it&amp;#039;s vertical align that you&amp;#039;re really after then use the custom vertical-align values on any element:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Middle vertical alignment without the overhead of table-cell/ tables */&lt;br /&gt;
vertical-align:table-middle;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #4: Use techniques other than table whenever appropriate, and make use of table-middle.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Memory Usage ==&lt;br /&gt;
&lt;br /&gt;
PowerUI is conservative about its memory usage, but if your targeting really low memory devices, turning off [[Image_Atlasing|image atlasing]] may be wise. Turning it off exchanges GPU/rendering time for lower memory and CPU use, which can be vital for pulling off a stunning UI on a device with little memory available.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Power tip #5: Turn off image atlasing for very low memory devices. See UI.RenderMode for doing that.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Multithreading ==&lt;br /&gt;
&lt;br /&gt;
Virtually all of PowerUI is multithreading friendly - anything that directly calls a Unity method like the geolocation web API isn&amp;#039;t. Presently the cookie cache (loading or setting cookies) is the only known PowerUI API which avoidably causes threading issues. Use PowerUI API&amp;#039;s directly from network threads, or spin up threads specifically for doing heavier UI work to make significant performance gains on multi-core architectures.&lt;br /&gt;
&lt;br /&gt;
== Canvas ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing to a canvas, there&amp;#039;s some nice savings you can be making. These savings are particularly noticeable if you&amp;#039;re drawing repeatedly, such as in Update.&lt;br /&gt;
&lt;br /&gt;
=== Only redraw your canvas when PowerUI does ===&lt;br /&gt;
PowerUI uploads the canvas image to the GPU no faster than your UI rate. Drawing your canvas any faster than that interval will essentially just waste cycles. We call that upload process a &amp;#039;refresh&amp;#039; - whenever you call stroke() or fill(), a refresh request is made (and then at some point in the near future, a refresh happens).&lt;br /&gt;
&lt;br /&gt;
So, if PowerUI already has an image which is ready but hasn&amp;#039;t been uploaded yet, there will be a pending refresh. Checking for that is like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
private CanvasContext2D Context;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
&lt;br /&gt;
    if(Context.ImageData.RefreshRequired){&lt;br /&gt;
        // This means we&amp;#039;ve already rendered something to the image data&lt;br /&gt;
        // and it&amp;#039;s just waiting to be uploaded. Rendering again would be a waste of time.&lt;br /&gt;
        // So, do nothing!&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Nothing to upload - draw it now!&lt;br /&gt;
    Context.beginPath();&lt;br /&gt;
    Context.moveTo(10,10);&lt;br /&gt;
    // ...&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multithreading canvas ===&lt;br /&gt;
&lt;br /&gt;
Like most PowerUI API&amp;#039;s, canvas is multithreading friendly. You could build those paths on some separate timer thread if you wanted to, for example.&lt;br /&gt;
&lt;br /&gt;
=== Cache your paths ===&lt;br /&gt;
&lt;br /&gt;
Whenever you call context.arcTo, context.lineTo etc, PowerUI internally builds up a representation of your path. When you then next call context.beginPath or context.clear, that representation is destroyed. If you&amp;#039;re drawing the same path over and over, it would be a great idea to save this internal representation rather than constantly rebuilding it to take some pressure off garbage collection.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you do this, it&amp;#039;s up to you to safely bound your points.&amp;#039;&amp;#039;&amp;#039; Normally the canvas API automatically takes care of points that are excessively out of range for you - things like infinity, NaN, or generally huge numbers. If you build a VectorPath and set it to a canvas, it&amp;#039;s important that you also guarantee your path doesn&amp;#039;t have any of those things. Internally, the canvas API runs VectorPath.Clip on all paths constructed via lineTo, arcTo etc. Otherwise, if you have an extremely long path then the canvas API will freeze whilst it outputs billions of pixels.&lt;br /&gt;
&lt;br /&gt;
To cache your paths you could either simply never call context.clear or context.beginPath and access Context.Path to move the nodes around like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI.&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
&lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // To clear the image but not the path, use ImageData:&lt;br /&gt;
    Context.ImageData.Clear();&lt;br /&gt;
&lt;br /&gt;
    // The path is totally empty if there&amp;#039;s no first node:&lt;br /&gt;
    if(Context.Path.FirstPathNode == null){&lt;br /&gt;
        &lt;br /&gt;
        // No path yet! Build it now:&lt;br /&gt;
        Context.moveTo(10,10);&lt;br /&gt;
        Context.lineTo(10,100);&lt;br /&gt;
        Context.lineTo(100,100);&lt;br /&gt;
        Context.lineTo(100,10);&lt;br /&gt;
        Context.closePath();&lt;br /&gt;
        &lt;br /&gt;
        // Note if any of the points in this first time call&lt;br /&gt;
        // go far out of range of the canvas, they may be &lt;br /&gt;
        // sliced for performance purposes.&lt;br /&gt;
        // For example, if your entire path is off canvas,&lt;br /&gt;
        // the whole thing may be dumped when you call stroke().&lt;br /&gt;
        &lt;br /&gt;
        // One way to avoid that uncertainty is to build the VectorPath directly (like below)&lt;br /&gt;
        // and then call VectorPath.Clip when it&amp;#039;s appropriate for your use case.&lt;br /&gt;
        &lt;br /&gt;
    }else{&lt;br /&gt;
        &lt;br /&gt;
        // E.g. update the nodes in the cachedPath:&lt;br /&gt;
        var point = CachedPath.FirstPathNode;&lt;br /&gt;
        &lt;br /&gt;
        // Our path has 5 points (alternatively loop until point is null).&lt;br /&gt;
        for(int i=0;i&amp;lt;5;i++){ // while(point!=null){&lt;br /&gt;
            &lt;br /&gt;
            // Move the point by the frame time:&lt;br /&gt;
            point.X += Time.deltaTime;&lt;br /&gt;
            &lt;br /&gt;
            // Go to the next point:&lt;br /&gt;
            point = point.Next;&lt;br /&gt;
          &lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Stroke or fill etc down here:&lt;br /&gt;
    Context.stroke();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re drawing multiple paths and you want to cache them all, then the simpler route would be to directly build one or more VectorPath instances first:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using PowerUI; // For CanvasContext and UI&lt;br /&gt;
using Blaze; // For VectorPath&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;The canvas context.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private CanvasContext Context;&lt;br /&gt;
/// &amp;lt;summary&amp;gt;A single cached path.&amp;lt;/summary&amp;gt;&lt;br /&gt;
private VectorPath CachedPath;&lt;br /&gt;
&lt;br /&gt;
void Start(){&lt;br /&gt;
    &lt;br /&gt;
    var document = UI.document;&lt;br /&gt;
    &lt;br /&gt;
    var canvas = document.getElementById(&amp;quot;my-canvas&amp;quot;) as HtmlElement;&lt;br /&gt;
&lt;br /&gt;
    Context = canvas.getContext(&amp;quot;2d&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    // build the vector path(s):&lt;br /&gt;
    CachedPath = new VectorPath();&lt;br /&gt;
&lt;br /&gt;
    // The API is very similar - it&amp;#039;s capitalized as it&amp;#039;s part of the internal public API:&lt;br /&gt;
    CachedPath.MoveTo(10,10);&lt;br /&gt;
    CachedPath.LineTo(10,100);&lt;br /&gt;
    CachedPath.LineTo(100,100);&lt;br /&gt;
    CachedPath.LineTo(100,10);&lt;br /&gt;
    CachedPath.ClosePath();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
    &lt;br /&gt;
    // Calling normal clear doesn&amp;#039;t matter here (as we&amp;#039;re not using e.g. Context.lineTo)&lt;br /&gt;
    Context.clear();&lt;br /&gt;
    &lt;br /&gt;
    // E.g. update current path here:&lt;br /&gt;
    var point = CachedPath.FirstPathNode;&lt;br /&gt;
    &lt;br /&gt;
    // note that closed paths never make infinite loops here.&lt;br /&gt;
    // A close node simply overlaps the node it closes and has IsClose set to true.&lt;br /&gt;
    while(point!=null){&lt;br /&gt;
        point.X+=Time.deltaTime;&lt;br /&gt;
        point=point.Next;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Temporarily retain the path object in the canvas:&lt;br /&gt;
    VectorPath activePath = Canvas.Path;&lt;br /&gt;
    &lt;br /&gt;
    // Set ours:&lt;br /&gt;
    Canvas.Path = CachedPath;&lt;br /&gt;
    &lt;br /&gt;
    // Stroke it now:&lt;br /&gt;
    Canvas.stroke();&lt;br /&gt;
&lt;br /&gt;
    // Restore the other path:&lt;br /&gt;
    Canvas.Path = activePath;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Precompile PowerUI ==&lt;br /&gt;
&lt;br /&gt;
Performance applies to your development process too. Unless you&amp;#039;ve got a solid state hard drive, PowerUI can take some 15 seconds to compile. Every time you change any of your C# files. [[Precompiler|Precompile PowerUI]] by going to &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Precompile&amp;#039;&amp;#039;&amp;#039; then just tick the box - that will entirely eliminate this delay for you.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If you change platform, or update Unity, you must precompile it again!&amp;#039;&amp;#039;&amp;#039; That&amp;#039;s because things like UNITY_ANDROID matter a lot.&lt;br /&gt;
&lt;br /&gt;
Note that precompiling does not affect custom tags etc, but it does affect any &amp;#039;&amp;#039;partial class extensions&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Set textContent rather than innerHTML ==&lt;br /&gt;
&lt;br /&gt;
If you know your text contains no HTML then setting to textContent will cause virtually everything to get recycled. Setting innerHTML is fast anyway but textContent does almost nothing.&lt;br /&gt;
&lt;br /&gt;
== Disabling Unicode Bidirectionality ==&lt;br /&gt;
&lt;br /&gt;
If you have no plans to use right-to-left or bidirectional text (like Arabic mixed with English), disable it by deleting &amp;#039;&amp;#039;&amp;#039;PowerUI/Resources/BidirectionalData.bytes&amp;#039;&amp;#039;&amp;#039;. This will give you a small memory saving (about 10kb) and slightly boost text performance.&lt;br /&gt;
&lt;br /&gt;
You can also go further by specifying &amp;#039;&amp;#039;&amp;#039;NoBIDI&amp;#039;&amp;#039;&amp;#039; as a &amp;quot;scripting define symbols&amp;quot; as that will effectively remove all of the code which does the BIDI testing.&lt;br /&gt;
&lt;br /&gt;
== Avoid late loading CSS ==&lt;br /&gt;
&lt;br /&gt;
This is a massive performance drainer - avoid it! Put style as high up your document as you can (e.g. in head). That&amp;#039;s because a newly loaded CSS selector must &amp;#039;&amp;#039;check your entire DOM&amp;#039;&amp;#039; to see if they match any of the elements already in there. If your DOM is basically empty then this operation is much faster.&lt;br /&gt;
&lt;br /&gt;
Meanwhile, a newly loading element uses a range of indices to very rapidly figure out which selectors actually apply to it.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Input_Pointers&amp;diff=768</id>
		<title>Input Pointers</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Input_Pointers&amp;diff=768"/>
				<updated>2017-05-01T04:10:52Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Virtual Reality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An input pointer is [https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events#term_pointer any kind of pointing device] which presses, hovers, or both. A mouse, a finger and a stylus are the three main ones. They are related to the (draft) [https://w3c.github.io/pointerevents/ W3C Pointer Events specification]. Here&amp;#039;s some specific notes about the input pointers available in PowerUI.&lt;br /&gt;
&lt;br /&gt;
== Mouse Input ==&lt;br /&gt;
&lt;br /&gt;
PowerUI assumes that only a desktop platform will have a mouse. A [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1MousePointer.html MousePointer] is created when it&amp;#039;s running on a desktop and [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a7527e2574ccda7fb7cdd2d8a28fff6db PowerUI.Input.CreateSystemMouse] is true &amp;#039;&amp;#039;(the default)&amp;#039;&amp;#039;. If your project doesn&amp;#039;t use a mouse pointer on a desktop platform (it&amp;#039;s [[Virtual Reality Cameras|virtual reality]] for example), you&amp;#039;d remove it by setting [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a7527e2574ccda7fb7cdd2d8a28fff6db CreateSystemMouse] to false in an Awake method.&lt;br /&gt;
&lt;br /&gt;
== Touch and Stylus Input ==&lt;br /&gt;
&lt;br /&gt;
PowerUI handles multi-touch input by default on any platform which supports it. It will automatically stack with a mouse input on desktops which also have touchscreens. Each time a new touch is detected, a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1FingerPointer.html FingerPointer] or a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1StylusPointer.html StylusPointer] is created. They fire the various [https://developer.mozilla.org/en-US/docs/Web/API/Touch_events touch events] as well as [https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent mouse events].&lt;br /&gt;
&lt;br /&gt;
All pointers are [https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/isPrimary primary] (which means they all fire those mouse events too).&lt;br /&gt;
&lt;br /&gt;
== Virtual Reality ==&lt;br /&gt;
&lt;br /&gt;
PowerUI has a custom input pointer, a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1CameraPointer.html CameraPointer], for virtual reality. See [[Virtual Reality Cameras|the article]] relating to virtual reality camera&amp;#039;s. Alternatively here&amp;#039;s a (rough!) laser pointer input example. Just add it to your project and see the notes below on how to e.g. add it and make it click:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;#039;csharp&amp;#039;&amp;gt;&lt;br /&gt;
using System;&lt;br /&gt;
using UnityEngine;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;A laser pointer which fires an input ray from e.g. a 3D hand.&amp;lt;/summary&amp;gt;&lt;br /&gt;
public class LaserPointer : PowerUI.InputPointer{&lt;br /&gt;
    &lt;br /&gt;
    public Transform Transform;&lt;br /&gt;
    /// &amp;lt;summary&amp;gt;True if UI&amp;#039;s move around.&amp;lt;/summary&amp;gt;&lt;br /&gt;
    public bool MovingUIs; &lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    /// &amp;lt;summary&amp;gt;Setup a laser pointer from the given transform (e.g. a hand object).&amp;lt;/summary&amp;gt;&lt;br /&gt;
    public LaserPointer(Transform transform):this(transform,true){}&lt;br /&gt;
   &lt;br /&gt;
    /// &amp;lt;summary&amp;gt;Setup a laser pointer from the given transform (e.g. a hand object).&amp;lt;/summary&amp;gt;&lt;br /&gt;
    /// &amp;lt;param name=&amp;#039;movingUIs&amp;#039;&amp;gt;Set this to true if your WorldUI&amp;#039;s move around.&lt;br /&gt;
    /// Setting it to false is a small performance saving. If you&amp;#039;re not sure, just use true.&amp;lt;/param&amp;gt;&lt;br /&gt;
    public LaserPointer(Transform transform, bool movingUIs){&lt;br /&gt;
       Transform = transform;&lt;br /&gt;
       MovingUIs = movingUIs;&lt;br /&gt;
       &lt;br /&gt;
       // It won&amp;#039;t interact with the main UI so just put it offscreen to skip checking entirely:&lt;br /&gt;
       ScreenX = ScreenY = -1000f;&lt;br /&gt;
       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public override bool Raycast(out RaycastHit hit, Camera cam, Vector2 screenPoint){&lt;br /&gt;
        &lt;br /&gt;
        // Fire off your ray in whatever your pointers direction is; we&amp;#039;ll use transform.forward here.&lt;br /&gt;
        // (&amp;#039;forward&amp;#039; is +ve z):&lt;br /&gt;
        Ray ray = new Ray(Transform.position, Transform.forward);&lt;br /&gt;
&lt;br /&gt;
        return Physics.Raycast(theRay, out hit);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public override bool Relocate(out Vector2 delta){&lt;br /&gt;
        &lt;br /&gt;
        // We can just ignore delta (it&amp;#039;s for the main UI):&lt;br /&gt;
        delta = Vector2.zero;&lt;br /&gt;
        &lt;br /&gt;
        if(MovingUIs){&lt;br /&gt;
            // Always recompute.&lt;br /&gt;
            return true;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // Transform moved?&lt;br /&gt;
        if(Transform!=null &amp;amp;&amp;amp; Transform.hasChanged){&lt;br /&gt;
            Transform.hasChanged = false;&lt;br /&gt;
            return true;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // Don&amp;#039;t bother recalculating - it&amp;#039;s not moved.&lt;br /&gt;
        // (Always return true if your UI&amp;#039;s are moving instead).&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;#039;csharp&amp;#039;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Fires a ray from the given hand object. If your UI&amp;#039;s don&amp;#039;t move around, use LaserPointer(aHandObject,false) to make a performance gain.&lt;br /&gt;
LaserPointer myPointer = new LaserPointer(aHandObject);&lt;br /&gt;
&lt;br /&gt;
// Add it:&lt;br /&gt;
myPointer.Add();&lt;br /&gt;
&lt;br /&gt;
// myPointer.LeftDown(); etc to click (see more below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Define your own ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re doing something more specialised then you can also define your own input pointer. Multiple Wii controllers, for example. This is very straight forward to do - at a minimum you must inherit from InputPointer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public class MyCustomPointer : InputPointer{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then to use it, all you need to do is create and add it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    MyCustomPointer pointer = new MyCustomPointer();&lt;br /&gt;
    pointer.Add();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be clicked etc or have a pressure value like any other pointer. To move it around, set the Position property (Top left corner is 0,0):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    pointer.Position = new Vector2(100,100);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively you can put your position update logic inside the pointer itself by overriding the Relocate method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public class MyCustomPointer : InputPointer{&lt;br /&gt;
    &lt;br /&gt;
    public override bool Relocate(out Vector2 positionChange){&lt;br /&gt;
    &lt;br /&gt;
        // - Get your latest coordinates here -&lt;br /&gt;
        Vector2 newPosition = Vector2.zero;&lt;br /&gt;
        &lt;br /&gt;
        // Try moving it (just returns false if your position wasn&amp;#039;t different to the current one):&lt;br /&gt;
        return TryChangePosition(newPosition, out positionChange);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Making it click ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve got an input pointer and you&amp;#039;d like to click it (or vary its downward pressure), you can either:&lt;br /&gt;
&lt;br /&gt;
* Use the convenience method for mouse up/down events from OnGUI:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void OnGUI(){&lt;br /&gt;
&lt;br /&gt;
  // Returns true if your pointer actually did something (it went down or up)&lt;br /&gt;
  // You can also directly pass a UnityEngine.Event too.&lt;br /&gt;
  bool didSomething = MyPointer.HandleEvent();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Call the MyPointer.Down and MyPointer.Up methods (Optionally specifying a [https://docs.unity3d.com/ScriptReference/Event-button.html mouse button ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Mousedown event, left button:&lt;br /&gt;
MyPointer.Down(0);&lt;br /&gt;
&lt;br /&gt;
// Which is also the same as:&lt;br /&gt;
MyPointer.LeftDown();&lt;br /&gt;
&lt;br /&gt;
// Mouseup event, left button:&lt;br /&gt;
MyPointer.Up(0);&lt;br /&gt;
&lt;br /&gt;
// Which is the same as:&lt;br /&gt;
MyPointer.LeftUp();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use SetPressure directly - this is useful if you&amp;#039;ve got some kind of stylus &amp;#039;&amp;#039;(every other option is just an abstraction of SetPressure)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
  &lt;br /&gt;
  // Update the pointer pressure:&lt;br /&gt;
  MyPointer.SetPressure(someVaryingField);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessing all pointers ==&lt;br /&gt;
&lt;br /&gt;
PowerUI implements various standard API&amp;#039;s for accessing pointers:&lt;br /&gt;
&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1TouchEvent.html TouchEvent].touches&lt;br /&gt;
* TouchEvent.targetTouches&lt;br /&gt;
* TouchEvent.changedTouches&lt;br /&gt;
* TouchEvent.identifier&lt;br /&gt;
* &amp;#039;&amp;#039;More!&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The non-standard internal ones:&lt;br /&gt;
&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1UIEvent.html#a2daa44fbceddd8510bc2791340a432b4 UIEvent.trigger] - &amp;#039;&amp;#039;MouseEvent, TouchEvent etc; The InputPointer instance this event came from&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#a77189cd51fedf33c73759f641c8380ef InputPointer.All] - &amp;#039;&amp;#039;All active pointers (array created on use; Use AllRaw and PointerCount for better performance)&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#a731d759f87ece43622fb497b5e3d88b3 InputPointer.PointerCount] - &amp;#039;&amp;#039;The number of actual pointers in the AllRaw pointer set&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#aa76092f569304c8fcf6c3bea1f9612e3 InputPointer.AllRaw] - &amp;#039;&amp;#039;The raw set of pointers. Entries beyond PointerCount are random noise/ undefined.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Source locations ==&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll find the implementations of MousePointer, FingerPointer etc here:&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Engine/Input/&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Virtual_Reality_Cameras&amp;diff=767</id>
		<title>Virtual Reality Cameras</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Virtual_Reality_Cameras&amp;diff=767"/>
				<updated>2017-05-01T04:08:39Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In virtual reality, it&amp;#039;s common to see the middle of the screen being used as the [[Input Pointers|input pointer]]. Think Minecraft and similar. Here&amp;#039;s how you set that up in PowerUI using the CameraPointer class.&lt;br /&gt;
&lt;br /&gt;
Note that the UI&amp;#039;s you create would almost always be one or more [[World UI|WorldUI&amp;#039;s]].&lt;br /&gt;
&lt;br /&gt;
== Creating a CameraPointer ==&lt;br /&gt;
&lt;br /&gt;
* You&amp;#039;ll probably want to turn off the mouse pointer (It&amp;#039;s used on desktops only). It&amp;#039;s the input pointer which is controlled by the mouse.&lt;br /&gt;
* In an Awake method, create a CameraPointer for a particular camera.&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CameraPointer MyPointer;&lt;br /&gt;
&lt;br /&gt;
void Awake(){&lt;br /&gt;
&lt;br /&gt;
  // Disable the system mouse:&lt;br /&gt;
  PowerUI.Input.CreateSystemMouse=false;&lt;br /&gt;
  &lt;br /&gt;
  // Create a camera pointer that sits in the middle of the screen (50%,50%):&lt;br /&gt;
  MyPointer = new CameraPointer(Camera.main,0.5f,0.5f);&lt;br /&gt;
  &lt;br /&gt;
  // Add it now:&lt;br /&gt;
  MyPointer.Add();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever the camera you gave is transformed (i.e. rotated or moved around), the pointer automatically updates itself.&lt;br /&gt;
&lt;br /&gt;
== Laser Pointers ==&lt;br /&gt;
&lt;br /&gt;
You can also entirely override the raycast to create a clickable/ hoverable input ray in any direction. Check out the [[Input Pointers#Virtual Reality|input pointers]] page for an example custom laser input pointer. &lt;br /&gt;
&lt;br /&gt;
== Making it click ==&lt;br /&gt;
&lt;br /&gt;
See the section on [[Input Pointers#Making it click|input pointers]] about making them click.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Input_Pointers&amp;diff=766</id>
		<title>Input Pointers</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Input_Pointers&amp;diff=766"/>
				<updated>2017-05-01T04:07:03Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Virtual Reality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An input pointer is [https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events#term_pointer any kind of pointing device] which presses, hovers, or both. A mouse, a finger and a stylus are the three main ones. They are related to the (draft) [https://w3c.github.io/pointerevents/ W3C Pointer Events specification]. Here&amp;#039;s some specific notes about the input pointers available in PowerUI.&lt;br /&gt;
&lt;br /&gt;
== Mouse Input ==&lt;br /&gt;
&lt;br /&gt;
PowerUI assumes that only a desktop platform will have a mouse. A [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1MousePointer.html MousePointer] is created when it&amp;#039;s running on a desktop and [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a7527e2574ccda7fb7cdd2d8a28fff6db PowerUI.Input.CreateSystemMouse] is true &amp;#039;&amp;#039;(the default)&amp;#039;&amp;#039;. If your project doesn&amp;#039;t use a mouse pointer on a desktop platform (it&amp;#039;s [[Virtual Reality Cameras|virtual reality]] for example), you&amp;#039;d remove it by setting [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a7527e2574ccda7fb7cdd2d8a28fff6db CreateSystemMouse] to false in an Awake method.&lt;br /&gt;
&lt;br /&gt;
== Touch and Stylus Input ==&lt;br /&gt;
&lt;br /&gt;
PowerUI handles multi-touch input by default on any platform which supports it. It will automatically stack with a mouse input on desktops which also have touchscreens. Each time a new touch is detected, a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1FingerPointer.html FingerPointer] or a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1StylusPointer.html StylusPointer] is created. They fire the various [https://developer.mozilla.org/en-US/docs/Web/API/Touch_events touch events] as well as [https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent mouse events].&lt;br /&gt;
&lt;br /&gt;
All pointers are [https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/isPrimary primary] (which means they all fire those mouse events too).&lt;br /&gt;
&lt;br /&gt;
== Virtual Reality ==&lt;br /&gt;
&lt;br /&gt;
PowerUI has a custom input pointer, a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1CameraPointer.html CameraPointer], for virtual reality. See [[Virtual Reality Cameras|the article]] relating to virtual reality camera&amp;#039;s. Alternatively here&amp;#039;s a (rough!) laser pointer input example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;#039;csharp&amp;#039;&amp;gt;&lt;br /&gt;
using System;&lt;br /&gt;
using UnityEngine;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&amp;gt;A laser pointer which fires an input ray from e.g. a 3D hand.&amp;lt;/summary&amp;gt;&lt;br /&gt;
public class LaserPointer : PowerUI.InputPointer{&lt;br /&gt;
    &lt;br /&gt;
    public Transform Transform;&lt;br /&gt;
    /// &amp;lt;summary&amp;gt;True if UI&amp;#039;s move around.&amp;lt;/summary&amp;gt;&lt;br /&gt;
    public bool MovingUIs; &lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    /// &amp;lt;summary&amp;gt;Setup a laser pointer from the given transform (e.g. a hand object).&amp;lt;/summary&amp;gt;&lt;br /&gt;
    public LaserPointer(Transform transform):this(transform,true){}&lt;br /&gt;
   &lt;br /&gt;
    /// &amp;lt;summary&amp;gt;Setup a laser pointer from the given transform (e.g. a hand object).&amp;lt;/summary&amp;gt;&lt;br /&gt;
    /// &amp;lt;param name=&amp;#039;movingUIs&amp;#039;&amp;gt;Set this to true if your WorldUI&amp;#039;s move around.&lt;br /&gt;
    /// Setting it to false is a small performance saving. If you&amp;#039;re not sure, just use true.&amp;lt;/param&amp;gt;&lt;br /&gt;
    public LaserPointer(Transform transform, bool movingUIs){&lt;br /&gt;
       Transform = transform;&lt;br /&gt;
       MovingUIs = movingUIs;&lt;br /&gt;
       &lt;br /&gt;
       // It won&amp;#039;t interact with the main UI so just put it offscreen to skip checking entirely:&lt;br /&gt;
       ScreenX = ScreenY = -1000f;&lt;br /&gt;
       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public override bool Raycast(out RaycastHit hit, Camera cam, Vector2 screenPoint){&lt;br /&gt;
        &lt;br /&gt;
        // Fire off your ray in whatever your pointers direction is; we&amp;#039;ll use transform.forward here.&lt;br /&gt;
        // (&amp;#039;forward&amp;#039; is +ve z):&lt;br /&gt;
        Ray ray = new Ray(Transform.position, Transform.forward);&lt;br /&gt;
&lt;br /&gt;
        return Physics.Raycast(theRay, out hit);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public override bool Relocate(out Vector2 delta){&lt;br /&gt;
        &lt;br /&gt;
        // We can just ignore delta (it&amp;#039;s for the main UI):&lt;br /&gt;
        delta = Vector2.zero;&lt;br /&gt;
        &lt;br /&gt;
        if(MovingUIs){&lt;br /&gt;
            // Always recompute.&lt;br /&gt;
            return true;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // Transform moved?&lt;br /&gt;
        if(Transform!=null &amp;amp;&amp;amp; Transform.hasChanged){&lt;br /&gt;
            Transform.hasChanged = false;&lt;br /&gt;
            return true;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // Don&amp;#039;t bother recalculating - it&amp;#039;s not moved.&lt;br /&gt;
        // (Always return true if your UI&amp;#039;s are moving instead).&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Define your own ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re doing something more specialised then you can also define your own input pointer. Multiple Wii controllers, for example. This is very straight forward to do - at a minimum you must inherit from InputPointer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public class MyCustomPointer : InputPointer{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then to use it, all you need to do is create and add it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    MyCustomPointer pointer = new MyCustomPointer();&lt;br /&gt;
    pointer.Add();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be clicked etc or have a pressure value like any other pointer. To move it around, set the Position property (Top left corner is 0,0):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    pointer.Position = new Vector2(100,100);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively you can put your position update logic inside the pointer itself by overriding the Relocate method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public class MyCustomPointer : InputPointer{&lt;br /&gt;
    &lt;br /&gt;
    public override bool Relocate(out Vector2 positionChange){&lt;br /&gt;
    &lt;br /&gt;
        // - Get your latest coordinates here -&lt;br /&gt;
        Vector2 newPosition = Vector2.zero;&lt;br /&gt;
        &lt;br /&gt;
        // Try moving it (just returns false if your position wasn&amp;#039;t different to the current one):&lt;br /&gt;
        return TryChangePosition(newPosition, out positionChange);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Making it click ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve got an input pointer and you&amp;#039;d like to click it (or vary its downward pressure), you can either:&lt;br /&gt;
&lt;br /&gt;
* Use the convenience method for mouse up/down events from OnGUI:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void OnGUI(){&lt;br /&gt;
&lt;br /&gt;
  // Returns true if your pointer actually did something (it went down or up)&lt;br /&gt;
  // You can also directly pass a UnityEngine.Event too.&lt;br /&gt;
  bool didSomething = MyPointer.HandleEvent();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Call the MyPointer.Down and MyPointer.Up methods (Optionally specifying a [https://docs.unity3d.com/ScriptReference/Event-button.html mouse button ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Mousedown event, left button:&lt;br /&gt;
MyPointer.Down(0);&lt;br /&gt;
&lt;br /&gt;
// Which is also the same as:&lt;br /&gt;
MyPointer.LeftDown();&lt;br /&gt;
&lt;br /&gt;
// Mouseup event, left button:&lt;br /&gt;
MyPointer.Up(0);&lt;br /&gt;
&lt;br /&gt;
// Which is the same as:&lt;br /&gt;
MyPointer.LeftUp();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use SetPressure directly - this is useful if you&amp;#039;ve got some kind of stylus &amp;#039;&amp;#039;(every other option is just an abstraction of SetPressure)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
  &lt;br /&gt;
  // Update the pointer pressure:&lt;br /&gt;
  MyPointer.SetPressure(someVaryingField);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessing all pointers ==&lt;br /&gt;
&lt;br /&gt;
PowerUI implements various standard API&amp;#039;s for accessing pointers:&lt;br /&gt;
&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1TouchEvent.html TouchEvent].touches&lt;br /&gt;
* TouchEvent.targetTouches&lt;br /&gt;
* TouchEvent.changedTouches&lt;br /&gt;
* TouchEvent.identifier&lt;br /&gt;
* &amp;#039;&amp;#039;More!&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The non-standard internal ones:&lt;br /&gt;
&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1UIEvent.html#a2daa44fbceddd8510bc2791340a432b4 UIEvent.trigger] - &amp;#039;&amp;#039;MouseEvent, TouchEvent etc; The InputPointer instance this event came from&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#a77189cd51fedf33c73759f641c8380ef InputPointer.All] - &amp;#039;&amp;#039;All active pointers (array created on use; Use AllRaw and PointerCount for better performance)&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#a731d759f87ece43622fb497b5e3d88b3 InputPointer.PointerCount] - &amp;#039;&amp;#039;The number of actual pointers in the AllRaw pointer set&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#aa76092f569304c8fcf6c3bea1f9612e3 InputPointer.AllRaw] - &amp;#039;&amp;#039;The raw set of pointers. Entries beyond PointerCount are random noise/ undefined.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Source locations ==&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll find the implementations of MousePointer, FingerPointer etc here:&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Engine/Input/&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Input_Pointers&amp;diff=764</id>
		<title>Input Pointers</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Input_Pointers&amp;diff=764"/>
				<updated>2017-04-23T17:54:45Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Define your own */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An input pointer is [https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events#term_pointer any kind of pointing device] which presses, hovers, or both. A mouse, a finger and a stylus are the three main ones. They are related to the (draft) [https://w3c.github.io/pointerevents/ W3C Pointer Events specification]. Here&amp;#039;s some specific notes about the input pointers available in PowerUI.&lt;br /&gt;
&lt;br /&gt;
== Mouse Input ==&lt;br /&gt;
&lt;br /&gt;
PowerUI assumes that only a desktop platform will have a mouse. A [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1MousePointer.html MousePointer] is created when it&amp;#039;s running on a desktop and [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a7527e2574ccda7fb7cdd2d8a28fff6db PowerUI.Input.CreateSystemMouse] is true &amp;#039;&amp;#039;(the default)&amp;#039;&amp;#039;. If your project doesn&amp;#039;t use a mouse pointer on a desktop platform (it&amp;#039;s [[Virtual Reality Cameras|virtual reality]] for example), you&amp;#039;d remove it by setting [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a7527e2574ccda7fb7cdd2d8a28fff6db CreateSystemMouse] to false in an Awake method.&lt;br /&gt;
&lt;br /&gt;
== Touch and Stylus Input ==&lt;br /&gt;
&lt;br /&gt;
PowerUI handles multi-touch input by default on any platform which supports it. It will automatically stack with a mouse input on desktops which also have touchscreens. Each time a new touch is detected, a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1FingerPointer.html FingerPointer] or a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1StylusPointer.html StylusPointer] is created. They fire the various [https://developer.mozilla.org/en-US/docs/Web/API/Touch_events touch events] as well as [https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent mouse events].&lt;br /&gt;
&lt;br /&gt;
All pointers are [https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/isPrimary primary] (which means they all fire those mouse events too).&lt;br /&gt;
&lt;br /&gt;
== Virtual Reality ==&lt;br /&gt;
&lt;br /&gt;
PowerUI has a custom input pointer, a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1CameraPointer.html CameraPointer], for virtual reality. See [[Virtual Reality Cameras|the article]] relating to virtual reality camera&amp;#039;s.&lt;br /&gt;
&lt;br /&gt;
== Define your own ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re doing something more specialised then you can also define your own input pointer. Multiple Wii controllers, for example. This is very straight forward to do - at a minimum you must inherit from InputPointer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public class MyCustomPointer : InputPointer{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then to use it, all you need to do is create and add it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    MyCustomPointer pointer = new MyCustomPointer();&lt;br /&gt;
    pointer.Add();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be clicked etc or have a pressure value like any other pointer. To move it around, set the Position property (Top left corner is 0,0):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    pointer.Position = new Vector2(100,100);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively you can put your position update logic inside the pointer itself by overriding the Relocate method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public class MyCustomPointer : InputPointer{&lt;br /&gt;
    &lt;br /&gt;
    public override bool Relocate(out Vector2 positionChange){&lt;br /&gt;
    &lt;br /&gt;
        // - Get your latest coordinates here -&lt;br /&gt;
        Vector2 newPosition = Vector2.zero;&lt;br /&gt;
        &lt;br /&gt;
        // Try moving it (just returns false if your position wasn&amp;#039;t different to the current one):&lt;br /&gt;
        return TryChangePosition(newPosition, out positionChange);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Making it click ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve got an input pointer and you&amp;#039;d like to click it (or vary its downward pressure), you can either:&lt;br /&gt;
&lt;br /&gt;
* Use the convenience method for mouse up/down events from OnGUI:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void OnGUI(){&lt;br /&gt;
&lt;br /&gt;
  // Returns true if your pointer actually did something (it went down or up)&lt;br /&gt;
  // You can also directly pass a UnityEngine.Event too.&lt;br /&gt;
  bool didSomething = MyPointer.HandleEvent();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Call the MyPointer.Down and MyPointer.Up methods (Optionally specifying a [https://docs.unity3d.com/ScriptReference/Event-button.html mouse button ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Mousedown event, left button:&lt;br /&gt;
MyPointer.Down(0);&lt;br /&gt;
&lt;br /&gt;
// Which is also the same as:&lt;br /&gt;
MyPointer.LeftDown();&lt;br /&gt;
&lt;br /&gt;
// Mouseup event, left button:&lt;br /&gt;
MyPointer.Up(0);&lt;br /&gt;
&lt;br /&gt;
// Which is the same as:&lt;br /&gt;
MyPointer.LeftUp();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use SetPressure directly - this is useful if you&amp;#039;ve got some kind of stylus &amp;#039;&amp;#039;(every other option is just an abstraction of SetPressure)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
  &lt;br /&gt;
  // Update the pointer pressure:&lt;br /&gt;
  MyPointer.SetPressure(someVaryingField);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessing all pointers ==&lt;br /&gt;
&lt;br /&gt;
PowerUI implements various standard API&amp;#039;s for accessing pointers:&lt;br /&gt;
&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1TouchEvent.html TouchEvent].touches&lt;br /&gt;
* TouchEvent.targetTouches&lt;br /&gt;
* TouchEvent.changedTouches&lt;br /&gt;
* TouchEvent.identifier&lt;br /&gt;
* &amp;#039;&amp;#039;More!&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The non-standard internal ones:&lt;br /&gt;
&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1UIEvent.html#a2daa44fbceddd8510bc2791340a432b4 UIEvent.trigger] - &amp;#039;&amp;#039;MouseEvent, TouchEvent etc; The InputPointer instance this event came from&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#a77189cd51fedf33c73759f641c8380ef InputPointer.All] - &amp;#039;&amp;#039;All active pointers (array created on use; Use AllRaw and PointerCount for better performance)&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#a731d759f87ece43622fb497b5e3d88b3 InputPointer.PointerCount] - &amp;#039;&amp;#039;The number of actual pointers in the AllRaw pointer set&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#aa76092f569304c8fcf6c3bea1f9612e3 InputPointer.AllRaw] - &amp;#039;&amp;#039;The raw set of pointers. Entries beyond PointerCount are random noise/ undefined.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Source locations ==&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll find the implementations of MousePointer, FingerPointer etc here:&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Engine/Input/&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Input_Pointers&amp;diff=763</id>
		<title>Input Pointers</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Input_Pointers&amp;diff=763"/>
				<updated>2017-04-23T17:43:52Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Define your own */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An input pointer is [https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events#term_pointer any kind of pointing device] which presses, hovers, or both. A mouse, a finger and a stylus are the three main ones. They are related to the (draft) [https://w3c.github.io/pointerevents/ W3C Pointer Events specification]. Here&amp;#039;s some specific notes about the input pointers available in PowerUI.&lt;br /&gt;
&lt;br /&gt;
== Mouse Input ==&lt;br /&gt;
&lt;br /&gt;
PowerUI assumes that only a desktop platform will have a mouse. A [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1MousePointer.html MousePointer] is created when it&amp;#039;s running on a desktop and [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a7527e2574ccda7fb7cdd2d8a28fff6db PowerUI.Input.CreateSystemMouse] is true &amp;#039;&amp;#039;(the default)&amp;#039;&amp;#039;. If your project doesn&amp;#039;t use a mouse pointer on a desktop platform (it&amp;#039;s [[Virtual Reality Cameras|virtual reality]] for example), you&amp;#039;d remove it by setting [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a7527e2574ccda7fb7cdd2d8a28fff6db CreateSystemMouse] to false in an Awake method.&lt;br /&gt;
&lt;br /&gt;
== Touch and Stylus Input ==&lt;br /&gt;
&lt;br /&gt;
PowerUI handles multi-touch input by default on any platform which supports it. It will automatically stack with a mouse input on desktops which also have touchscreens. Each time a new touch is detected, a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1FingerPointer.html FingerPointer] or a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1StylusPointer.html StylusPointer] is created. They fire the various [https://developer.mozilla.org/en-US/docs/Web/API/Touch_events touch events] as well as [https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent mouse events].&lt;br /&gt;
&lt;br /&gt;
All pointers are [https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/isPrimary primary] (which means they all fire those mouse events too).&lt;br /&gt;
&lt;br /&gt;
== Virtual Reality ==&lt;br /&gt;
&lt;br /&gt;
PowerUI has a custom input pointer, a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1CameraPointer.html CameraPointer], for virtual reality. See [[Virtual Reality Cameras|the article]] relating to virtual reality camera&amp;#039;s.&lt;br /&gt;
&lt;br /&gt;
== Define your own ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re doing something more specialised then you can also define your own input pointer. Multiple Wii controllers, for example. This is very straight forward to do - at a minimum you must inherit from InputPointer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public class MyCustomPointer : InputPointer{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then to use it, all you need to do is create and add it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    MyCustomPointer pointer = new MyCustomPointer();&lt;br /&gt;
    pointer.Add();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be clicked etc or have a pressure value like any other pointer. To move it around, set the Position property (Top left corner is 0,0):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    pointer.Position = new Vector2(100,100);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively you can put your position update logic inside the pointer itself by overriding the Relocate method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public class MyCustomPointer : InputPointer{&lt;br /&gt;
    &lt;br /&gt;
    public override bool Relocate(){&lt;br /&gt;
    &lt;br /&gt;
        // - Get your latest coordinates here -&lt;br /&gt;
        Vector2 newPosition = Vector2.zero;&lt;br /&gt;
        &lt;br /&gt;
        // Try moving it (just returns false if your position wasn&amp;#039;t different to the current one):&lt;br /&gt;
        return TryChangePosition(newPosition);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Making it click ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve got an input pointer and you&amp;#039;d like to click it (or vary its downward pressure), you can either:&lt;br /&gt;
&lt;br /&gt;
* Use the convenience method for mouse up/down events from OnGUI:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void OnGUI(){&lt;br /&gt;
&lt;br /&gt;
  // Returns true if your pointer actually did something (it went down or up)&lt;br /&gt;
  // You can also directly pass a UnityEngine.Event too.&lt;br /&gt;
  bool didSomething = MyPointer.HandleEvent();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Call the MyPointer.Down and MyPointer.Up methods (Optionally specifying a [https://docs.unity3d.com/ScriptReference/Event-button.html mouse button ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Mousedown event, left button:&lt;br /&gt;
MyPointer.Down(0);&lt;br /&gt;
&lt;br /&gt;
// Which is also the same as:&lt;br /&gt;
MyPointer.LeftDown();&lt;br /&gt;
&lt;br /&gt;
// Mouseup event, left button:&lt;br /&gt;
MyPointer.Up(0);&lt;br /&gt;
&lt;br /&gt;
// Which is the same as:&lt;br /&gt;
MyPointer.LeftUp();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use SetPressure directly - this is useful if you&amp;#039;ve got some kind of stylus &amp;#039;&amp;#039;(every other option is just an abstraction of SetPressure)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
  &lt;br /&gt;
  // Update the pointer pressure:&lt;br /&gt;
  MyPointer.SetPressure(someVaryingField);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessing all pointers ==&lt;br /&gt;
&lt;br /&gt;
PowerUI implements various standard API&amp;#039;s for accessing pointers:&lt;br /&gt;
&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1TouchEvent.html TouchEvent].touches&lt;br /&gt;
* TouchEvent.targetTouches&lt;br /&gt;
* TouchEvent.changedTouches&lt;br /&gt;
* TouchEvent.identifier&lt;br /&gt;
* &amp;#039;&amp;#039;More!&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The non-standard internal ones:&lt;br /&gt;
&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1UIEvent.html#a2daa44fbceddd8510bc2791340a432b4 UIEvent.trigger] - &amp;#039;&amp;#039;MouseEvent, TouchEvent etc; The InputPointer instance this event came from&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#a77189cd51fedf33c73759f641c8380ef InputPointer.All] - &amp;#039;&amp;#039;All active pointers (array created on use; Use AllRaw and PointerCount for better performance)&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#a731d759f87ece43622fb497b5e3d88b3 InputPointer.PointerCount] - &amp;#039;&amp;#039;The number of actual pointers in the AllRaw pointer set&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#aa76092f569304c8fcf6c3bea1f9612e3 InputPointer.AllRaw] - &amp;#039;&amp;#039;The raw set of pointers. Entries beyond PointerCount are random noise/ undefined.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Source locations ==&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll find the implementations of MousePointer, FingerPointer etc here:&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Engine/Input/&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Input_Pointers&amp;diff=762</id>
		<title>Input Pointers</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Input_Pointers&amp;diff=762"/>
				<updated>2017-04-23T17:29:19Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An input pointer is [https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events#term_pointer any kind of pointing device] which presses, hovers, or both. A mouse, a finger and a stylus are the three main ones. They are related to the (draft) [https://w3c.github.io/pointerevents/ W3C Pointer Events specification]. Here&amp;#039;s some specific notes about the input pointers available in PowerUI.&lt;br /&gt;
&lt;br /&gt;
== Mouse Input ==&lt;br /&gt;
&lt;br /&gt;
PowerUI assumes that only a desktop platform will have a mouse. A [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1MousePointer.html MousePointer] is created when it&amp;#039;s running on a desktop and [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a7527e2574ccda7fb7cdd2d8a28fff6db PowerUI.Input.CreateSystemMouse] is true &amp;#039;&amp;#039;(the default)&amp;#039;&amp;#039;. If your project doesn&amp;#039;t use a mouse pointer on a desktop platform (it&amp;#039;s [[Virtual Reality Cameras|virtual reality]] for example), you&amp;#039;d remove it by setting [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1Input.html#a7527e2574ccda7fb7cdd2d8a28fff6db CreateSystemMouse] to false in an Awake method.&lt;br /&gt;
&lt;br /&gt;
== Touch and Stylus Input ==&lt;br /&gt;
&lt;br /&gt;
PowerUI handles multi-touch input by default on any platform which supports it. It will automatically stack with a mouse input on desktops which also have touchscreens. Each time a new touch is detected, a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1FingerPointer.html FingerPointer] or a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1StylusPointer.html StylusPointer] is created. They fire the various [https://developer.mozilla.org/en-US/docs/Web/API/Touch_events touch events] as well as [https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent mouse events].&lt;br /&gt;
&lt;br /&gt;
All pointers are [https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/isPrimary primary] (which means they all fire those mouse events too).&lt;br /&gt;
&lt;br /&gt;
== Virtual Reality ==&lt;br /&gt;
&lt;br /&gt;
PowerUI has a custom input pointer, a [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1CameraPointer.html CameraPointer], for virtual reality. See [[Virtual Reality Cameras|the article]] relating to virtual reality camera&amp;#039;s.&lt;br /&gt;
&lt;br /&gt;
== Define your own ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re doing something more specialised then you can also define your own input pointer. Multiple Wii controllers, for example. This is very straight forward to do - at a minimum you must inherit from InputPointer and override Relocate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public class MyCustomPointer : InputPointer{&lt;br /&gt;
    &lt;br /&gt;
    public override bool Relocate(){&lt;br /&gt;
    &lt;br /&gt;
        // - Get your latest coordinates here -&lt;br /&gt;
        Vector2 newPosition = Vector2.zero;&lt;br /&gt;
        &lt;br /&gt;
        if(newPosition.x == ScreenX &amp;amp;&amp;amp; newPosition.y == ScreenY){&lt;br /&gt;
            // It&amp;#039;s not moved anywhere - quit:&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // It&amp;#039;s moved! Update the x/y coords:&lt;br /&gt;
        ScreenX = newPositionX;&lt;br /&gt;
        ScreenY = newPositionY;&lt;br /&gt;
        &lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then to use it, all you need to do is create and add it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
    MyCustomPointer pointer = new MyCustomPointer();&lt;br /&gt;
    pointer.Add();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can be clicked etc or have a pressure value like any other pointer.&lt;br /&gt;
&lt;br /&gt;
== Making it click ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve got an input pointer and you&amp;#039;d like to click it (or vary its downward pressure), you can either:&lt;br /&gt;
&lt;br /&gt;
* Use the convenience method for mouse up/down events from OnGUI:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void OnGUI(){&lt;br /&gt;
&lt;br /&gt;
  // Returns true if your pointer actually did something (it went down or up)&lt;br /&gt;
  // You can also directly pass a UnityEngine.Event too.&lt;br /&gt;
  bool didSomething = MyPointer.HandleEvent();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Call the MyPointer.Down and MyPointer.Up methods (Optionally specifying a [https://docs.unity3d.com/ScriptReference/Event-button.html mouse button ID]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Mousedown event, left button:&lt;br /&gt;
MyPointer.Down(0);&lt;br /&gt;
&lt;br /&gt;
// Which is also the same as:&lt;br /&gt;
MyPointer.LeftDown();&lt;br /&gt;
&lt;br /&gt;
// Mouseup event, left button:&lt;br /&gt;
MyPointer.Up(0);&lt;br /&gt;
&lt;br /&gt;
// Which is the same as:&lt;br /&gt;
MyPointer.LeftUp();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use SetPressure directly - this is useful if you&amp;#039;ve got some kind of stylus &amp;#039;&amp;#039;(every other option is just an abstraction of SetPressure)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void Update(){&lt;br /&gt;
  &lt;br /&gt;
  // Update the pointer pressure:&lt;br /&gt;
  MyPointer.SetPressure(someVaryingField);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessing all pointers ==&lt;br /&gt;
&lt;br /&gt;
PowerUI implements various standard API&amp;#039;s for accessing pointers:&lt;br /&gt;
&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1TouchEvent.html TouchEvent].touches&lt;br /&gt;
* TouchEvent.targetTouches&lt;br /&gt;
* TouchEvent.changedTouches&lt;br /&gt;
* TouchEvent.identifier&lt;br /&gt;
* &amp;#039;&amp;#039;More!&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The non-standard internal ones:&lt;br /&gt;
&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1UIEvent.html#a2daa44fbceddd8510bc2791340a432b4 UIEvent.trigger] - &amp;#039;&amp;#039;MouseEvent, TouchEvent etc; The InputPointer instance this event came from&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#a77189cd51fedf33c73759f641c8380ef InputPointer.All] - &amp;#039;&amp;#039;All active pointers (array created on use; Use AllRaw and PointerCount for better performance)&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#a731d759f87ece43622fb497b5e3d88b3 InputPointer.PointerCount] - &amp;#039;&amp;#039;The number of actual pointers in the AllRaw pointer set&amp;#039;&amp;#039;&lt;br /&gt;
* [http://powerui.kulestar.com/powerdocs-2_0/classPowerUI_1_1InputPointer.html#aa76092f569304c8fcf6c3bea1f9612e3 InputPointer.AllRaw] - &amp;#039;&amp;#039;The raw set of pointers. Entries beyond PointerCount are random noise/ undefined.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Source locations ==&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll find the implementations of MousePointer, FingerPointer etc here:&lt;br /&gt;
&lt;br /&gt;
* PowerUI/Source/Engine/Input/&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Named_Characters&amp;diff=761</id>
		<title>Named Characters</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Named_Characters&amp;diff=761"/>
				<updated>2017-04-22T01:40:11Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: Created page with &amp;quot;Named characters are things like &amp;amp;amp;bull; or &amp;amp;amp;eacute;. Since roughly 2009 the web has been transitioning from ASCII to UTF8 so they&amp;#039;re generally legacy now. That usually...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Named characters are things like &amp;amp;amp;bull; or &amp;amp;amp;eacute;. Since roughly 2009 the web has been transitioning from ASCII to UTF8 so they&amp;#039;re generally legacy now. That usually means just set your editor to UTF8 and type/ paste the actual character instead as that&amp;#039;s often more convenient than finding out what the name actually is.&lt;br /&gt;
&lt;br /&gt;
PowerUI also uses the named character format for its [[Localization|localization system]].&lt;br /&gt;
&lt;br /&gt;
== Enabling HTML5 Named Characters ==&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re trying to use one and it doesn&amp;#039;t seem to be working, it&amp;#039;ll be because PowerUI defaults to using the HTML4 set of named characters to avoid bloat (because they&amp;#039;re not really used much anymore anyway and the HTML5 set is much bigger). Fortunately there&amp;#039;s just a tick box for it - go here:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Named Characters&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Then tick the box to enable the HTML5 set.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=759</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=759"/>
				<updated>2017-04-21T07:42:28Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Passing Ambiguous Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has three engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;), Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;) and WebAssembly. Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro.&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If you &amp;#039;collapse&amp;#039; a variable - this happens when you set it to things of more than one type and the type tracker is forced to stop tracking it. Not all dynamic resolve paths are complete so your success here will vary. In general though collapsed variables are an indication of incorrect code so the engine will at least tell you about them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var a=14;&lt;br /&gt;
&lt;br /&gt;
function Hello(){&lt;br /&gt;
    a=&amp;quot;My String&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A is both a string and a number. It &amp;#039;collapses&amp;#039; to Object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that collapsing function arguments is perfectly fine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Adder(a,b){&lt;br /&gt;
    return a+b;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Adder(1,2);&lt;br /&gt;
Adder(&amp;quot;hello &amp;quot;,&amp;quot;world!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway (jQuery fails because of the below point).&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;br /&gt;
&lt;br /&gt;
== Interaction with the rest of your code ==&lt;br /&gt;
&lt;br /&gt;
Nitrassic&amp;#039;s JavaScript is a .NET language like C# - that means they can call each other with no overhead when crossing the boundary. In short, you get the best of all worlds because it acts like JavaScript with all of the types available to C# being also available to the JavaScript engine.&lt;br /&gt;
&lt;br /&gt;
=== Calling C#/Unity methods from JS ===&lt;br /&gt;
&lt;br /&gt;
Nitrassic has no particular issues calling C# methods from your project - it &amp;quot;just works&amp;quot; unless you explicitly block it from doing so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// You can use the Unity API too:&lt;br /&gt;
var go = new GameObject();&lt;br /&gt;
&lt;br /&gt;
go.name = &amp;quot;MadeWithLoveByRealJavaScript&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Or if you have some static C# class just call it like you would from C#:&lt;br /&gt;
MyCSharpClass.HelloFromJavaScript();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Passing Functions ====&lt;br /&gt;
&lt;br /&gt;
This is an awesome aspect of Nitrassic and it&amp;#039;s highly recommended you make use of it! If you pass a JavaScript function in the place of a delegate (or relatives, like Action) then it will automagically adopt that delegates type. Like this - here&amp;#039;s the C#:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public static class MyCallbacks{&lt;br /&gt;
&lt;br /&gt;
    public static void RunLater(Action&amp;lt;string&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(&amp;quot;Hello from C#!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And here&amp;#039;s the JavaScript:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Usually you&amp;#039;d use this for event based stuff.&lt;br /&gt;
MyCallbacks.RunLater(function(a){&lt;br /&gt;
   // The type tracker knows &amp;#039;a&amp;#039; is a string:&lt;br /&gt;
   console.log(a);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Passing Ambiguous Functions ====&lt;br /&gt;
&lt;br /&gt;
If your C# function is overloaded (there&amp;#039;s multiple versions of it) then it might be ambiguous. addEventListener is a perfect example of when this happens:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Add a mousedown event listener:&lt;br /&gt;
myElement.addEventListener(&amp;quot;mousedown&amp;quot;,function(e){&lt;br /&gt;
   // The type tracker is magic enough to figure out that &lt;br /&gt;
   // &amp;#039;e&amp;#039; is a MouseEvent - the following has no runtime overhead:&lt;br /&gt;
   console.log(e.clientX);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Add a keydown event listener:&lt;br /&gt;
myElement.addEventListener(&amp;quot;keydown&amp;quot;,function(e){&lt;br /&gt;
   // The type tracker is magic enough to figure out that &lt;br /&gt;
   // &amp;#039;e&amp;#039; is a *KeyboardEvent*.&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever one of your functions is ambiguous, it should define a special disambiguation method. The one for addEventListener uses that first argument to figure out the most appropriate one (e.g. when it spots &amp;#039;mousedown&amp;#039; it knows it&amp;#039;s a MouseEvent). Here&amp;#039;s how to define a disambiguation method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public static class MyCallbacks{&lt;br /&gt;
    &lt;br /&gt;
    // These two methods are ambiguous so we&amp;#039;ll define a disambiguation method:&lt;br /&gt;
    [JSProperties(Disambiguation=&amp;quot;RunLaterDisambig&amp;quot;)]&lt;br /&gt;
    public static void RunLater(string type, Action&amp;lt;string&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(&amp;quot;Hello from C#!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void RunLater(string type, Action&amp;lt;int&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(140);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public MethodInfo RunLaterDisambig(MethodGroup group,FunctionCallExpression fce){&lt;br /&gt;
        &lt;br /&gt;
        // This runs when compiling each call like MyCallbacks.RunLater(&amp;quot;something&amp;quot;,function(x){ });&lt;br /&gt;
        // &amp;#039;group&amp;#039; is the set of 2 methods we need to select from.&lt;br /&gt;
        // &amp;#039;fce&amp;#039; is the function call expression in the source which requires disambiguation.&lt;br /&gt;
        &lt;br /&gt;
        // Assuming that we can identify which one to use based on that textual first arg, we can do this:&lt;br /&gt;
        string typeValue = fce.Arg(0) as string;&lt;br /&gt;
        &lt;br /&gt;
        if(typeValue == null || typeValue == &amp;quot;string&amp;quot;){&lt;br /&gt;
            // It&amp;#039;s not a constant string - Can&amp;#039;t disambiguate (fallback on a default)&lt;br /&gt;
            // or it&amp;#039;s the word &amp;#039;string&amp;#039; which we&amp;#039;ll handle with the string version:&lt;br /&gt;
            return group.Match(new Type[]{typeof(string), typeof(Action&amp;lt;string&amp;gt;)});&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // Otherwise use the int version:&lt;br /&gt;
        return group.Match(new Type[]{typeof(string), typeof(Action&amp;lt;int&amp;gt;)});&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And how the above affects the JavaScript is like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MyCallbacks.RunLater(aRuntimeOnlyVar,function(e){&lt;br /&gt;
 // This is mapped to Action&amp;lt;string&amp;gt; because the first arg is not constant&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
MyCallbacks.RunLater(&amp;quot;string&amp;quot;,function(e){&lt;br /&gt;
 // This is mapped to Action&amp;lt;string&amp;gt;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
MyCallbacks.RunLater(&amp;quot;somethingElse&amp;quot;,function(e){&lt;br /&gt;
 // This is mapped to Action&amp;lt;int&amp;gt;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calling JS from C# ===&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll want to get the ScriptEngine and use the CallGlobalFunction method. Work in progress!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=758</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=758"/>
				<updated>2017-04-21T07:42:09Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Passing Ambiguous Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has three engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;), Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;) and WebAssembly. Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro.&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If you &amp;#039;collapse&amp;#039; a variable - this happens when you set it to things of more than one type and the type tracker is forced to stop tracking it. Not all dynamic resolve paths are complete so your success here will vary. In general though collapsed variables are an indication of incorrect code so the engine will at least tell you about them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var a=14;&lt;br /&gt;
&lt;br /&gt;
function Hello(){&lt;br /&gt;
    a=&amp;quot;My String&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A is both a string and a number. It &amp;#039;collapses&amp;#039; to Object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that collapsing function arguments is perfectly fine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Adder(a,b){&lt;br /&gt;
    return a+b;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Adder(1,2);&lt;br /&gt;
Adder(&amp;quot;hello &amp;quot;,&amp;quot;world!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway (jQuery fails because of the below point).&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;br /&gt;
&lt;br /&gt;
== Interaction with the rest of your code ==&lt;br /&gt;
&lt;br /&gt;
Nitrassic&amp;#039;s JavaScript is a .NET language like C# - that means they can call each other with no overhead when crossing the boundary. In short, you get the best of all worlds because it acts like JavaScript with all of the types available to C# being also available to the JavaScript engine.&lt;br /&gt;
&lt;br /&gt;
=== Calling C#/Unity methods from JS ===&lt;br /&gt;
&lt;br /&gt;
Nitrassic has no particular issues calling C# methods from your project - it &amp;quot;just works&amp;quot; unless you explicitly block it from doing so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// You can use the Unity API too:&lt;br /&gt;
var go = new GameObject();&lt;br /&gt;
&lt;br /&gt;
go.name = &amp;quot;MadeWithLoveByRealJavaScript&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Or if you have some static C# class just call it like you would from C#:&lt;br /&gt;
MyCSharpClass.HelloFromJavaScript();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Passing Functions ====&lt;br /&gt;
&lt;br /&gt;
This is an awesome aspect of Nitrassic and it&amp;#039;s highly recommended you make use of it! If you pass a JavaScript function in the place of a delegate (or relatives, like Action) then it will automagically adopt that delegates type. Like this - here&amp;#039;s the C#:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public static class MyCallbacks{&lt;br /&gt;
&lt;br /&gt;
    public static void RunLater(Action&amp;lt;string&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(&amp;quot;Hello from C#!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And here&amp;#039;s the JavaScript:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Usually you&amp;#039;d use this for event based stuff.&lt;br /&gt;
MyCallbacks.RunLater(function(a){&lt;br /&gt;
   // The type tracker knows &amp;#039;a&amp;#039; is a string:&lt;br /&gt;
   console.log(a);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Passing Ambiguous Functions ====&lt;br /&gt;
&lt;br /&gt;
If your C# function is overloaded (there&amp;#039;s multiple versions of it) then it might be ambiguous. addEventListener is a perfect example of when this happens:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Add a mousedown event listener:&lt;br /&gt;
myElement.addEventListener(&amp;quot;mousedown&amp;quot;,function(e){&lt;br /&gt;
   // The type tracker is magic enough to figure out that &lt;br /&gt;
   // &amp;#039;e&amp;#039; is a MouseEvent - the following has no runtime overhead:&lt;br /&gt;
   console.log(e.clientX);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Add a keydown event listener:&lt;br /&gt;
myElement.addEventListener(&amp;quot;keydown&amp;quot;,function(e){&lt;br /&gt;
   // The type tracker is magic enough to figure out that &lt;br /&gt;
   // &amp;#039;e&amp;#039; is a *KeyboardEvent*.&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever one of your functions is ambiguous, it should define a special disambiguation method. The one for addEventListener uses that first argument to figure out the most appropriate one (e.g. when it spots &amp;#039;mousedown&amp;#039; it knows it&amp;#039;s a MouseEvent). Here&amp;#039;s how to define a disambiguation method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public static class MyCallbacks{&lt;br /&gt;
    &lt;br /&gt;
    // These two methods are ambiguous so we&amp;#039;ll define a disambiguation method:&lt;br /&gt;
    [JSProperties(Disambiguation=&amp;quot;RunLaterDisambig&amp;quot;)]&lt;br /&gt;
    public static void RunLater(string type, Action&amp;lt;string&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(&amp;quot;Hello from C#!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void RunLater(string type, Action&amp;lt;int&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(140);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public MethodInfo RunLaterDisambig(MethodGroup group,FunctionCallExpression fce){&lt;br /&gt;
        &lt;br /&gt;
        // This runs when compiling each call like MyCallbacks.RunLater(&amp;quot;something&amp;quot;,function(x){ });&lt;br /&gt;
        // &amp;#039;group&amp;#039; is the set of 2 methods we need to select from.&lt;br /&gt;
        // &amp;#039;fce&amp;#039; is the function call expression in the source which requires disambiguation.&lt;br /&gt;
        &lt;br /&gt;
        // Assuming that we can identify which one to use based on that textual first arg, we can do this:&lt;br /&gt;
        string typeValue = fce.Arg(0) as string;&lt;br /&gt;
        &lt;br /&gt;
        if(typeValue == null || typeValue == &amp;quot;string&amp;quot;){&lt;br /&gt;
            // It&amp;#039;s not a constant string - Can&amp;#039;t disambiguate (fallback on a default)&lt;br /&gt;
            // or it&amp;#039;s the word &amp;#039;string&amp;#039; which we&amp;#039;ll handle with the string version:&lt;br /&gt;
            return group.Match(new Type[]{typeof(string), typeof(Action&amp;lt;string&amp;gt;)});&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // Otherwise use the int version:&lt;br /&gt;
        return group.Match(new Type[]{typeof(string), typeof(Action&amp;lt;int&amp;gt;)});&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
And how the above affects the JavaScript is like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MyCallbacks.RunLater(aRuntimeOnlyVar,function(e){&lt;br /&gt;
 // This is mapped to Action&amp;lt;string&amp;gt; because the first arg is not constant&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
MyCallbacks.RunLater(&amp;quot;string&amp;quot;,function(e){&lt;br /&gt;
 // This is mapped to Action&amp;lt;string&amp;gt;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
MyCallbacks.RunLater(&amp;quot;somethingElse&amp;quot;,function(e){&lt;br /&gt;
 // This is mapped to Action&amp;lt;int&amp;gt;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calling JS from C# ===&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll want to get the ScriptEngine and use the CallGlobalFunction method. Work in progress!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=757</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=757"/>
				<updated>2017-04-21T07:40:11Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Passing Ambiguous Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has three engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;), Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;) and WebAssembly. Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro.&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If you &amp;#039;collapse&amp;#039; a variable - this happens when you set it to things of more than one type and the type tracker is forced to stop tracking it. Not all dynamic resolve paths are complete so your success here will vary. In general though collapsed variables are an indication of incorrect code so the engine will at least tell you about them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var a=14;&lt;br /&gt;
&lt;br /&gt;
function Hello(){&lt;br /&gt;
    a=&amp;quot;My String&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A is both a string and a number. It &amp;#039;collapses&amp;#039; to Object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that collapsing function arguments is perfectly fine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Adder(a,b){&lt;br /&gt;
    return a+b;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Adder(1,2);&lt;br /&gt;
Adder(&amp;quot;hello &amp;quot;,&amp;quot;world!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway (jQuery fails because of the below point).&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;br /&gt;
&lt;br /&gt;
== Interaction with the rest of your code ==&lt;br /&gt;
&lt;br /&gt;
Nitrassic&amp;#039;s JavaScript is a .NET language like C# - that means they can call each other with no overhead when crossing the boundary. In short, you get the best of all worlds because it acts like JavaScript with all of the types available to C# being also available to the JavaScript engine.&lt;br /&gt;
&lt;br /&gt;
=== Calling C#/Unity methods from JS ===&lt;br /&gt;
&lt;br /&gt;
Nitrassic has no particular issues calling C# methods from your project - it &amp;quot;just works&amp;quot; unless you explicitly block it from doing so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// You can use the Unity API too:&lt;br /&gt;
var go = new GameObject();&lt;br /&gt;
&lt;br /&gt;
go.name = &amp;quot;MadeWithLoveByRealJavaScript&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Or if you have some static C# class just call it like you would from C#:&lt;br /&gt;
MyCSharpClass.HelloFromJavaScript();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Passing Functions ====&lt;br /&gt;
&lt;br /&gt;
This is an awesome aspect of Nitrassic and it&amp;#039;s highly recommended you make use of it! If you pass a JavaScript function in the place of a delegate (or relatives, like Action) then it will automagically adopt that delegates type. Like this - here&amp;#039;s the C#:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public static class MyCallbacks{&lt;br /&gt;
&lt;br /&gt;
    public static void RunLater(Action&amp;lt;string&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(&amp;quot;Hello from C#!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And here&amp;#039;s the JavaScript:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Usually you&amp;#039;d use this for event based stuff.&lt;br /&gt;
MyCallbacks.RunLater(function(a){&lt;br /&gt;
   // The type tracker knows &amp;#039;a&amp;#039; is a string:&lt;br /&gt;
   console.log(a);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Passing Ambiguous Functions ====&lt;br /&gt;
&lt;br /&gt;
If your C# function is overloaded (there&amp;#039;s multiple versions of it) then it might be ambiguous. addEventListener is a perfect example of when this happens:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Add a mousedown event listener:&lt;br /&gt;
myElement.addEventListener(&amp;quot;mousedown&amp;quot;,function(e){&lt;br /&gt;
   // The type tracker is magic enough to figure out that &lt;br /&gt;
   // &amp;#039;e&amp;#039; is a MouseEvent - the following has no runtime overhead:&lt;br /&gt;
   console.log(e.clientX);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Add a keydown event listener:&lt;br /&gt;
myElement.addEventListener(&amp;quot;keydown&amp;quot;,function(e){&lt;br /&gt;
   // The type tracker is magic enough to figure out that &lt;br /&gt;
   // &amp;#039;e&amp;#039; is a *KeyboardEvent*.&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever one of your functions is ambiguous, it should define a special disambiguation method. The one for addEventListener uses that first argument to figure out the most appropriate one (e.g. when it spots &amp;#039;mousedown&amp;#039; it knows it&amp;#039;s a MouseEvent). Here&amp;#039;s how to define a disambiguation method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public static class MyCallbacks{&lt;br /&gt;
    &lt;br /&gt;
    // These two methods are ambiguous so we&amp;#039;ll define a disambiguation method:&lt;br /&gt;
    [JSProperties(Disambiguation=&amp;quot;RunLaterDisambig&amp;quot;)]&lt;br /&gt;
    public static void RunLater(string type, Action&amp;lt;string&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(&amp;quot;Hello from C#!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void RunLater(string type, Action&amp;lt;int&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(140);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public MethodInfo RunLaterDisambig(MethodGroup group,FunctionCallExpression fce){&lt;br /&gt;
        &lt;br /&gt;
        // This runs when compiling each call like MyCallbacks.RunLater(&amp;quot;something&amp;quot;,function(x){ });&lt;br /&gt;
        // &amp;#039;group&amp;#039; is the set of 2 methods we need to select from.&lt;br /&gt;
        // &amp;#039;fce&amp;#039; is the function call expression in the source which requires disambiguation.&lt;br /&gt;
        &lt;br /&gt;
        // Assuming that we can identify which one to use based on that textual first arg, we can do this:&lt;br /&gt;
        string typeValue = fce.Arg(0) as string;&lt;br /&gt;
        &lt;br /&gt;
        if(typeValue == null || typeValue == &amp;quot;string&amp;quot;){&lt;br /&gt;
            // It&amp;#039;s not a constant string - Can&amp;#039;t disambiguate (fallback on a default)&lt;br /&gt;
            // or it&amp;#039;s the word &amp;#039;string&amp;#039; which we&amp;#039;ll handle with the string version:&lt;br /&gt;
            return group.Match(new Type[]{typeof(string), typeof(Action&amp;lt;string&amp;gt;)});&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // Otherwise use the int version:&lt;br /&gt;
        return group.Match(new Type[]{typeof(string), typeof(Action&amp;lt;int&amp;gt;)});&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calling JS from C# ===&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll want to get the ScriptEngine and use the CallGlobalFunction method. Work in progress!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=756</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=756"/>
				<updated>2017-04-21T07:38:55Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Passing Ambiguous Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has three engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;), Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;) and WebAssembly. Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro.&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If you &amp;#039;collapse&amp;#039; a variable - this happens when you set it to things of more than one type and the type tracker is forced to stop tracking it. Not all dynamic resolve paths are complete so your success here will vary. In general though collapsed variables are an indication of incorrect code so the engine will at least tell you about them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var a=14;&lt;br /&gt;
&lt;br /&gt;
function Hello(){&lt;br /&gt;
    a=&amp;quot;My String&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A is both a string and a number. It &amp;#039;collapses&amp;#039; to Object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that collapsing function arguments is perfectly fine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Adder(a,b){&lt;br /&gt;
    return a+b;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Adder(1,2);&lt;br /&gt;
Adder(&amp;quot;hello &amp;quot;,&amp;quot;world!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway (jQuery fails because of the below point).&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;br /&gt;
&lt;br /&gt;
== Interaction with the rest of your code ==&lt;br /&gt;
&lt;br /&gt;
Nitrassic&amp;#039;s JavaScript is a .NET language like C# - that means they can call each other with no overhead when crossing the boundary. In short, you get the best of all worlds because it acts like JavaScript with all of the types available to C# being also available to the JavaScript engine.&lt;br /&gt;
&lt;br /&gt;
=== Calling C#/Unity methods from JS ===&lt;br /&gt;
&lt;br /&gt;
Nitrassic has no particular issues calling C# methods from your project - it &amp;quot;just works&amp;quot; unless you explicitly block it from doing so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// You can use the Unity API too:&lt;br /&gt;
var go = new GameObject();&lt;br /&gt;
&lt;br /&gt;
go.name = &amp;quot;MadeWithLoveByRealJavaScript&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Or if you have some static C# class just call it like you would from C#:&lt;br /&gt;
MyCSharpClass.HelloFromJavaScript();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Passing Functions ====&lt;br /&gt;
&lt;br /&gt;
This is an awesome aspect of Nitrassic and it&amp;#039;s highly recommended you make use of it! If you pass a JavaScript function in the place of a delegate (or relatives, like Action) then it will automagically adopt that delegates type. Like this - here&amp;#039;s the C#:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public static class MyCallbacks{&lt;br /&gt;
&lt;br /&gt;
    public static void RunLater(Action&amp;lt;string&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(&amp;quot;Hello from C#!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And here&amp;#039;s the JavaScript:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Usually you&amp;#039;d use this for event based stuff.&lt;br /&gt;
MyCallbacks.RunLater(function(a){&lt;br /&gt;
   // The type tracker knows &amp;#039;a&amp;#039; is a string:&lt;br /&gt;
   console.log(a);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Passing Ambiguous Functions ====&lt;br /&gt;
&lt;br /&gt;
If your C# function is overloaded (there&amp;#039;s multiple versions of it) then it might be ambiguous. addEventListener is a perfect example of when this happens:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Add a mousedown event listener:&lt;br /&gt;
myElement.addEventListener(&amp;quot;mousedown&amp;quot;,function(e){&lt;br /&gt;
   // The type tracker is magic enough to figure out that &lt;br /&gt;
   // &amp;#039;e&amp;#039; is a MouseEvent - the following has no runtime overhead:&lt;br /&gt;
   console.log(e.clientX);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Add a keydown event listener:&lt;br /&gt;
myElement.addEventListener(&amp;quot;keydown&amp;quot;,function(e){&lt;br /&gt;
   // The type tracker is magic enough to figure out that &lt;br /&gt;
   // &amp;#039;e&amp;#039; is a *KeyboardEvent*.&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever one of your functions is ambiguous, it should define a special disambiguation method. The one for addEventListener uses that first argument to figure out the most appropriate one (e.g. when it spots &amp;#039;mousedown&amp;#039; it knows it&amp;#039;s a MouseEvent). Here&amp;#039;s how to define a disambiguation method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public static class MyCallbacks{&lt;br /&gt;
    &lt;br /&gt;
    // These two methods are ambiguous so we&amp;#039;ll define a disambiguation method:&lt;br /&gt;
    [JSProperties(Disambiguation=&amp;quot;RunLaterDisambig&amp;quot;)]&lt;br /&gt;
    public static void RunLater(string type, Action&amp;lt;string&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(&amp;quot;Hello from C#!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void RunLater(string type, Action&amp;lt;int&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(140);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public MethodInfo RunLaterDisambig(MethodGroup group,FunctionCallExpression fce){&lt;br /&gt;
        &lt;br /&gt;
        // This runs when compiling each call like MyCallbacks.RunLater(&amp;quot;something&amp;quot;,function(x){ });&lt;br /&gt;
        // &amp;#039;group&amp;#039; is the set of 2 methods we need to select from.&lt;br /&gt;
        // &amp;#039;fce&amp;#039; is the function call expression in the source which requires disambiguation.&lt;br /&gt;
        &lt;br /&gt;
        // Assuming that we can identify which one to use based on that textual first arg, we can do this:&lt;br /&gt;
        string typeValue = fce.Arg(0) as string;&lt;br /&gt;
        &lt;br /&gt;
        if(typeValue == null || typeValue == &amp;quot;string&amp;quot;){&lt;br /&gt;
            // It&amp;#039;s not a constant string. Can&amp;#039;t disambiguate (fallback on a default):&lt;br /&gt;
            return group.Match(new Type[]{typeof(string), typeof(Action&amp;lt;string&amp;gt;)});&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // Otherwise use the int version:&lt;br /&gt;
        return group.Match(new Type[]{typeof(string), typeof(Action&amp;lt;int&amp;gt;)});&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calling JS from C# ===&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll want to get the ScriptEngine and use the CallGlobalFunction method. Work in progress!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=755</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=755"/>
				<updated>2017-04-21T07:36:34Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Interaction with the rest of your code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has three engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;), Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;) and WebAssembly. Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro.&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If you &amp;#039;collapse&amp;#039; a variable - this happens when you set it to things of more than one type and the type tracker is forced to stop tracking it. Not all dynamic resolve paths are complete so your success here will vary. In general though collapsed variables are an indication of incorrect code so the engine will at least tell you about them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var a=14;&lt;br /&gt;
&lt;br /&gt;
function Hello(){&lt;br /&gt;
    a=&amp;quot;My String&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A is both a string and a number. It &amp;#039;collapses&amp;#039; to Object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that collapsing function arguments is perfectly fine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Adder(a,b){&lt;br /&gt;
    return a+b;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Adder(1,2);&lt;br /&gt;
Adder(&amp;quot;hello &amp;quot;,&amp;quot;world!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway (jQuery fails because of the below point).&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;br /&gt;
&lt;br /&gt;
== Interaction with the rest of your code ==&lt;br /&gt;
&lt;br /&gt;
Nitrassic&amp;#039;s JavaScript is a .NET language like C# - that means they can call each other with no overhead when crossing the boundary. In short, you get the best of all worlds because it acts like JavaScript with all of the types available to C# being also available to the JavaScript engine.&lt;br /&gt;
&lt;br /&gt;
=== Calling C#/Unity methods from JS ===&lt;br /&gt;
&lt;br /&gt;
Nitrassic has no particular issues calling C# methods from your project - it &amp;quot;just works&amp;quot; unless you explicitly block it from doing so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// You can use the Unity API too:&lt;br /&gt;
var go = new GameObject();&lt;br /&gt;
&lt;br /&gt;
go.name = &amp;quot;MadeWithLoveByRealJavaScript&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Or if you have some static C# class just call it like you would from C#:&lt;br /&gt;
MyCSharpClass.HelloFromJavaScript();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Passing Functions ====&lt;br /&gt;
&lt;br /&gt;
This is an awesome aspect of Nitrassic and it&amp;#039;s highly recommended you make use of it! If you pass a JavaScript function in the place of a delegate (or relatives, like Action) then it will automagically adopt that delegates type. Like this - here&amp;#039;s the C#:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public static class MyCallbacks{&lt;br /&gt;
&lt;br /&gt;
    public static void RunLater(Action&amp;lt;string&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(&amp;quot;Hello from C#!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And here&amp;#039;s the JavaScript:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Usually you&amp;#039;d use this for event based stuff.&lt;br /&gt;
MyCallbacks.RunLater(function(a){&lt;br /&gt;
   // The type tracker knows &amp;#039;a&amp;#039; is a string:&lt;br /&gt;
   console.log(a);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Passing Ambiguous Functions ====&lt;br /&gt;
&lt;br /&gt;
If your C# function is overloaded (there&amp;#039;s multiple versions of it) then it might be ambiguous. addEventListener is a perfect example of when this happens:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Add a mousedown event listener:&lt;br /&gt;
myElement.addEventListener(&amp;quot;mousedown&amp;quot;,function(e){&lt;br /&gt;
   // The type tracker is magic enough to figure out that &lt;br /&gt;
   // &amp;#039;e&amp;#039; is a MouseEvent - the following has no runtime overhead:&lt;br /&gt;
   console.log(e.clientX);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Add a keydown event listener:&lt;br /&gt;
myElement.addEventListener(&amp;quot;keydown&amp;quot;,function(e){&lt;br /&gt;
   // The type tracker is magic enough to figure out that &lt;br /&gt;
   // &amp;#039;e&amp;#039; is a *KeyboardEvent*.&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever one of your functions is ambiguous, it should define a special disambiguation method. The one for addEventListener uses that first argument to figure out the most appropriate one is (e.g. when it spots &amp;#039;mousedown&amp;#039; it knows it&amp;#039;s a MouseEvent). Here&amp;#039;s how to define a disambiguation method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public static class MyCallbacks{&lt;br /&gt;
    &lt;br /&gt;
    // These two methods are ambiguous so we&amp;#039;ll define a disambiguation method:&lt;br /&gt;
    [JSProperties(Disambiguation=&amp;quot;RunLaterDisambig&amp;quot;)]&lt;br /&gt;
    public static void RunLater(string type, Action&amp;lt;string&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(&amp;quot;Hello from C#!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void RunLater(string type, Action&amp;lt;int&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(140);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public MethodInfo RunLaterDisambig(MethodGroup group,FunctionCallExpression fce){&lt;br /&gt;
        &lt;br /&gt;
        // This runs when compiling each call like MyCallbacks.RunLater(&amp;quot;something&amp;quot;,function(x){ });&lt;br /&gt;
        // &amp;#039;group&amp;#039; is the set of 2 methods we need to select from.&lt;br /&gt;
        // &amp;#039;fce&amp;#039; is the function call expression in the source which requires disambiguation.&lt;br /&gt;
        &lt;br /&gt;
        // Assuming that we can identify which one to use based on that textual first arg, we can do this:&lt;br /&gt;
        string typeValue = fce.Arg(0) as string;&lt;br /&gt;
        &lt;br /&gt;
        if(typeValue == null || typeValue == &amp;quot;string&amp;quot;){&lt;br /&gt;
            // It&amp;#039;s not a constant string. Can&amp;#039;t disambiguate (fallback on a default):&lt;br /&gt;
            return group.Match(new Type[]{typeof(string), typeof(Action&amp;lt;string&amp;gt;)});&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // Otherwise use the int version:&lt;br /&gt;
        return group.Match(new Type[]{typeof(string), typeof(Action&amp;lt;int&amp;gt;)});&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calling JS from C# ===&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll want to get the ScriptEngine and use the CallGlobalFunction method. Work in progress!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=754</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=754"/>
				<updated>2017-04-21T03:40:03Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has three engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;), Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;) and WebAssembly. Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro.&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If you &amp;#039;collapse&amp;#039; a variable - this happens when you set it to things of more than one type and the type tracker is forced to stop tracking it. Not all dynamic resolve paths are complete so your success here will vary. In general though collapsed variables are an indication of incorrect code so the engine will at least tell you about them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var a=14;&lt;br /&gt;
&lt;br /&gt;
function Hello(){&lt;br /&gt;
    a=&amp;quot;My String&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A is both a string and a number. It &amp;#039;collapses&amp;#039; to Object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that collapsing function arguments is perfectly fine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Adder(a,b){&lt;br /&gt;
    return a+b;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Adder(1,2);&lt;br /&gt;
Adder(&amp;quot;hello &amp;quot;,&amp;quot;world!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway (jQuery fails because of the below point).&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;br /&gt;
&lt;br /&gt;
== Interaction with the rest of your code ==&lt;br /&gt;
&lt;br /&gt;
Nitrassic like C# is a .NET language - that means they can call each other with no overhead when crossing the boundary. In short, you get the best of all worlds because it acts like JavaScript with all of the types available to C# being also available to the JavaScript engine.&lt;br /&gt;
&lt;br /&gt;
=== Calling C#/Unity methods from JS ===&lt;br /&gt;
&lt;br /&gt;
Nitrassic has no particular issues calling C# methods from your project - it &amp;quot;just works&amp;quot; unless you explicitly block it from doing so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// You can use the Unity API too:&lt;br /&gt;
var go = new GameObject();&lt;br /&gt;
&lt;br /&gt;
go.name = &amp;quot;MadeWithLoveByRealJavaScript&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Or if you have some static C# class just call it like you would from C#:&lt;br /&gt;
MyCSharpClass.HelloFromJavaScript();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Passing Functions ====&lt;br /&gt;
&lt;br /&gt;
This is an awesome aspect of Nitrassic and it&amp;#039;s highly recommended you make use of it! If you pass a JavaScript function in the place of a delegate (or relatives, like Action) then it will automagically adopt that delegates type. Like this - here&amp;#039;s the C#:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public static class MyCallbacks{&lt;br /&gt;
&lt;br /&gt;
    public static void RunLater(Action&amp;lt;string&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(&amp;quot;Hello from C#!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And here&amp;#039;s the JavaScript:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Usually you&amp;#039;d use this for event based stuff.&lt;br /&gt;
MyCallbacks.RunLater(function(a){&lt;br /&gt;
   // The type tracker knows &amp;#039;a&amp;#039; is a string:&lt;br /&gt;
   console.log(a);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Passing Ambiguous Functions ====&lt;br /&gt;
&lt;br /&gt;
If your C# function is overloaded (there&amp;#039;s multiple versions of it) then it might be ambiguous. addEventListener is a perfect example of when this happens:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Add a mousedown event listener:&lt;br /&gt;
myElement.addEventListener(&amp;quot;mousedown&amp;quot;,function(e){&lt;br /&gt;
   // The type tracker is magic enough to figure out that &lt;br /&gt;
   // &amp;#039;e&amp;#039; is a MouseEvent - the following has no runtime overhead:&lt;br /&gt;
   console.log(e.clientX);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Add a keydown event listener:&lt;br /&gt;
myElement.addEventListener(&amp;quot;keydown&amp;quot;,function(e){&lt;br /&gt;
   // The type tracker is magic enough to figure out that &lt;br /&gt;
   // &amp;#039;e&amp;#039; is a *KeyboardEvent*.&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever one of your functions is ambiguous, it should define a special disambiguation method. The one for addEventListener uses that first argument to figure out the most appropriate one is (e.g. when it spots &amp;#039;mousedown&amp;#039; it knows it&amp;#039;s a MouseEvent). Here&amp;#039;s how to define a disambiguation method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public static class MyCallbacks{&lt;br /&gt;
    &lt;br /&gt;
    // These two methods are ambiguous so we&amp;#039;ll define a disambiguation method:&lt;br /&gt;
    [JSProperties(Disambiguation=&amp;quot;RunLaterDisambig&amp;quot;)]&lt;br /&gt;
    public static void RunLater(string type, Action&amp;lt;string&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(&amp;quot;Hello from C#!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void RunLater(string type, Action&amp;lt;int&amp;gt; onDone){&lt;br /&gt;
        // ..Do something..&lt;br /&gt;
        onDone(140);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public MethodInfo RunLaterDisambig(MethodGroup group,FunctionCallExpression fce){&lt;br /&gt;
        &lt;br /&gt;
        // This runs when compiling each call like MyCallbacks.RunLater(&amp;quot;something&amp;quot;,function(x){ });&lt;br /&gt;
        // &amp;#039;group&amp;#039; is the set of 2 methods we need to select from.&lt;br /&gt;
        // &amp;#039;fce&amp;#039; is the function call expression in the source which requires disambiguation.&lt;br /&gt;
        &lt;br /&gt;
        // Assuming that we can identify which one to use based on that textual first arg, we can do this:&lt;br /&gt;
        string typeValue = fce.Arg(0) as string;&lt;br /&gt;
        &lt;br /&gt;
        if(typeValue == null || typeValue == &amp;quot;string&amp;quot;){&lt;br /&gt;
            // It&amp;#039;s not a constant string. Can&amp;#039;t disambiguate (fallback on a default):&lt;br /&gt;
            return group.Match(new Type[]{typeof(string), typeof(Action&amp;lt;string&amp;gt;)});&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // Otherwise use the int version:&lt;br /&gt;
        return group.Match(new Type[]{typeof(string), typeof(Action&amp;lt;int&amp;gt;)});&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Calling JS from C# ===&lt;br /&gt;
&lt;br /&gt;
You&amp;#039;ll want to get the ScriptEngine and use the CallGlobalFunction method. Work in progress!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=753</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=753"/>
				<updated>2017-04-21T02:47:49Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Can I run x - How compliant is the JavaScript in PowerUI? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has three engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;), Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;) and WebAssembly. Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro.&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If you &amp;#039;collapse&amp;#039; a variable - this happens when you set it to things of more than one type and the type tracker is forced to stop tracking it. Not all dynamic resolve paths are complete so your success here will vary. In general though collapsed variables are an indication of incorrect code so the engine will at least tell you about them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var a=14;&lt;br /&gt;
&lt;br /&gt;
function Hello(){&lt;br /&gt;
    a=&amp;quot;My String&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A is both a string and a number. It &amp;#039;collapses&amp;#039; to Object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that collapsing function arguments is perfectly fine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Adder(a,b){&lt;br /&gt;
    return a+b;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Adder(1,2);&lt;br /&gt;
Adder(&amp;quot;hello &amp;quot;,&amp;quot;world!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway (jQuery fails because of the below point).&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=752</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=752"/>
				<updated>2017-04-21T02:46:34Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Can I run x - How compliant is the JavaScript in PowerUI? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has three engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;), Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;) and WebAssembly. Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro.&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If you &amp;#039;collapse&amp;#039; a variable - this happens when you set it to things of more than one type and the type tracker is forced to stop tracking it. Not all dynamic resolve paths are complete so your success here will vary. In general though collapsed variables are an indication of incorrect code so the engine will at least tell you about them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var a=14;&lt;br /&gt;
&lt;br /&gt;
function Hello(){&lt;br /&gt;
    a=&amp;quot;My String&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A is both a string and a number. It &amp;#039;collapses&amp;#039; to Object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway (jQuery fails because of the below point).&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=751</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=751"/>
				<updated>2017-04-21T02:41:45Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has three engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;), Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;) and WebAssembly. Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro.&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If you &amp;#039;collapse&amp;#039; a variable - this happens when you set it to things of more than one type and the type tracker is forced to stop tracking it. Not all dynamic resolve paths are complete so your success here will vary. In general though collapsed variables are an indication of incorrect code so the engine will at least tell you about them.&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway (jQuery fails).&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=750</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=750"/>
				<updated>2017-04-21T02:41:12Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* The JavaScript challenge - A short history */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has two engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;) and Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;). Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro.&lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If you &amp;#039;collapse&amp;#039; a variable - this happens when you set it to things of more than one type and the type tracker is forced to stop tracking it. Not all dynamic resolve paths are complete so your success here will vary. In general though collapsed variables are an indication of incorrect code so the engine will at least tell you about them.&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway (jQuery fails).&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=749</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=749"/>
				<updated>2017-04-21T02:41:00Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Can I run x - How compliant is the JavaScript in PowerUI? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has two engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;) and Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;). Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro. If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If you &amp;#039;collapse&amp;#039; a variable - this happens when you set it to things of more than one type and the type tracker is forced to stop tracking it. Not all dynamic resolve paths are complete so your success here will vary. In general though collapsed variables are an indication of incorrect code so the engine will at least tell you about them.&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway (jQuery fails).&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=748</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=748"/>
				<updated>2017-04-21T02:37:57Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Can I run x - How compliant is the JavaScript in PowerUI? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has two engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;) and Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;). Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro. If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway (jQuery fails).&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=747</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=JavaScript&amp;diff=747"/>
				<updated>2017-04-21T02:37:27Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: Created page with &amp;quot;PowerUI currently has two engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;) and Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;). Nitro is a custom language which more re...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PowerUI currently has two engines for runtime code - Nitro (script type=&amp;#039;text/nitro&amp;#039;) and Nitrassic (script type=&amp;#039;text/javascript-x&amp;#039;). Nitro is a custom language which more resembles UnityScript and the current version of Nitrassic is mostly compliant with ECMAScript 5. Nitro, the older engine, is now defunct and will be removed in the near future so you should either code using C# or use type=&amp;#039;text/javascript-x&amp;#039; in your script tags.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript challenge - A short history ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Most gaming platforms, including iOS, explicitly don&amp;#039;t allow runtime compliation.&amp;#039;&amp;#039;&amp;#039; JavaScript was designed to be runtime compiled so these restrictions cause an instant major problem. It&amp;#039;s not like it&amp;#039;s a particularly small issue either - all but two of the Unity platforms (Standalone and Android) don&amp;#039;t allow runtime compilation. The only route to get JavaScript working on those platforms is to compile the JavaScript &amp;#039;ahead of time&amp;#039; in the editor. However, that is &amp;#039;&amp;#039;extremely&amp;#039;&amp;#039; difficult for a language as dynamic as JavaScript is. We initially went the same route as Unity - create a JavaScript-like language which can be easily compiled in the editor. That&amp;#039;s Nitro. If you&amp;#039;ve ever used UnityScript (or Nitro itself) you will notice very quickly that you can&amp;#039;t simply run a library like jQuery, or indeed virtually any actual JavaScript from the web &amp;#039;&amp;#039;(it&amp;#039;s still very unfortunate that Unity still calls UnityScript &amp;#039;JavaScript&amp;#039; and uses the .js extension)&amp;#039;&amp;#039;. So over the years as PowerUI&amp;#039;s support for the web in general has increased, we naturally needed to make a new JavaScript engine - one which supported ahead of time compilation and as much of the JavaScript specification as possible. That&amp;#039;s Nitrassic.&lt;br /&gt;
&lt;br /&gt;
Nitrassic was built by taking the [https://github.com/paulbartrum/jurassic Jurassic engine] and merging it with Nitro (thus the name) - adding a type tracking system to make it suitable for editor compilation. This ultimately had the effect of making Jurassic massively faster, but at the expense of months of high complexity compiler work. We&amp;#039;re in new territory here - Nitrassic is the first ahead-of-time JavaScript compiler which could have big implications for things like Node.js in the wider web world; particularly as, when combined with IL2CPP, the result is JavaScript running at near native speeds.&lt;br /&gt;
&lt;br /&gt;
== Can I run x - How compliant is the JavaScript in PowerUI? ==&lt;br /&gt;
&lt;br /&gt;
The best option? Just try it and see what happens! At the moment, this depends on:&lt;br /&gt;
* Further testing is required.&lt;br /&gt;
* If your JavaScript uses the &amp;#039;delete&amp;#039; keyword (jQuery does) then tracking the types becomes undefined, but it will still try anyway.&lt;br /&gt;
* How much of the core Object interface &amp;#039;x&amp;#039; uses. Primarily that&amp;#039;s prototype. Whilst prototypes are supported, anObject.prototype (which is part of that interface) currently isn&amp;#039;t. You can access these instance prototypes via a constructor function instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function Point(x,y){&lt;br /&gt;
    // &amp;#039;this&amp;#039; is equivalent of Point.prototype&lt;br /&gt;
    this.x=x;&lt;br /&gt;
    this.y=y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var p = new Point(114,20);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;re working on the above points and any help with that would be greatly appreciated!&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Context_Menu&amp;diff=746</id>
		<title>Context Menu</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Context_Menu&amp;diff=746"/>
				<updated>2017-04-19T05:11:07Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Context menus pop up to display one or more options to the user, depending on what it was that they interacted with. They come in a huge variety of shapes and sizes - from radial &amp;quot;Sims style&amp;quot; to ordinary lists that show up when you right click. PowerUI has a built in context menu system which sits on top of the [[Widget Manager|widget system]] enabling [[Widget Templates|templates of context menu&amp;#039;s]] to be easily created and shared.&lt;br /&gt;
&lt;br /&gt;
== 2D and 3D context menu&amp;#039;s ==&lt;br /&gt;
&lt;br /&gt;
Context menu&amp;#039;s can be created for either 2D or 3D objects. The flow of both has been made as consistent as possible - essentially, you need to &amp;#039;&amp;#039;&amp;#039;respond to the contextmenu event&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&lt;br /&gt;
=== 2D ===&lt;br /&gt;
&lt;br /&gt;
HTML elements receive a contextmenu event, which you can connect to however you like (usually with addEventListener(&amp;quot;contextmenu&amp;quot;,..)). Use ContextEvent.add in there too in order to build up the options. For example, you might have an inventory. Each item, when clicked on, generates a context menu with options like &amp;quot;use&amp;quot; or &amp;quot;drop&amp;quot;. You&amp;#039;d add each of those via ContextEvent.add.&lt;br /&gt;
&lt;br /&gt;
=== 3D ===&lt;br /&gt;
&lt;br /&gt;
Tick &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Handle 3D Input&amp;#039;&amp;#039;&amp;#039; and attach something like this to your GameObjects:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using UnityEngine;&lt;br /&gt;
using System.Collections;&lt;br /&gt;
using Dom;&lt;br /&gt;
using ContextMenus;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class My3DContextMenu : MonoBehaviour {&lt;br /&gt;
	&lt;br /&gt;
	public void OnContextMenu(ContextEvent e){&lt;br /&gt;
	&lt;br /&gt;
		// *this* GameObject has been asked for a context menu.&lt;br /&gt;
		&lt;br /&gt;
		// E.g. if this gameObject is some kind of door, then:&lt;br /&gt;
		context.add(&amp;quot;&amp;amp;Open;&amp;quot;,delegate(Option o){&lt;br /&gt;
			&lt;br /&gt;
			// &amp;#039;open&amp;#039; the door!&lt;br /&gt;
		&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you use this approach, note that &amp;#039;&amp;#039;&amp;#039;the event will bubble up the scene hierarchy&amp;#039;&amp;#039;&amp;#039;, in a similar way to it bubbling through the DOM. This way, if PowerUI&amp;#039;s input ray hits a collider which is a child of an NPC or a door etc, then it will reach the root NPC object and you&amp;#039;ll get a successful handle.&lt;br /&gt;
&lt;br /&gt;
=== Advanced 3D ===&lt;br /&gt;
&lt;br /&gt;
Advanced: If you don&amp;#039;t want to add a script to every gameObject, then instead you can use the GameObject to EventTarget mapper and handle obtaining the event target in a custom way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Hook up our mapper:&lt;br /&gt;
PowerUI.Input.TargetResolver=delegate(GameObject go,out bool cancelEvent){&lt;br /&gt;
	&lt;br /&gt;
	// Don&amp;#039;t cancel the event:&lt;br /&gt;
	cancelEvent=false;&lt;br /&gt;
	&lt;br /&gt;
	// ..Do whatever you&amp;#039;d like to get hold of some object which implements IEventTarget..&lt;br /&gt;
	// (If you don&amp;#039;t get a match, that&amp;#039;s fine - return null)&lt;br /&gt;
	IEventTarget myTarget=null;&lt;br /&gt;
	&lt;br /&gt;
	return myTarget;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, you might have an NPC class (and that NPC class is an IEventTarget). You&amp;#039;d map the given gameObject through to an NPC instance.&lt;br /&gt;
&lt;br /&gt;
The dispatch method is, however, the same as the MonoBehaviour approach (only it would return e.g. context options specific to an NPC).&lt;br /&gt;
&lt;br /&gt;
== Setting up the appearance of context menu&amp;#039;s ==&lt;br /&gt;
&lt;br /&gt;
ContextEvent has a field called &amp;#039;&amp;#039;&amp;#039;template&amp;#039;&amp;#039;&amp;#039; - it&amp;#039;s the name of one of your [[Widget Templates|widget templates]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Get it as a context event:&lt;br /&gt;
ContextEvent context=e as ContextEvent;&lt;br /&gt;
&lt;br /&gt;
// Set the template to use:&lt;br /&gt;
context.template=&amp;quot;widgetTemplateName&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, it&amp;#039;s &amp;quot;menulist&amp;quot; - the name of a built in context menu. Conveniently, this approach means different objects can respond with completely different context menu styles too; for example, a 3D NPC might display a radial context menu (like in the Sims) and a 2D item in an inventory displays the default menulist.&lt;br /&gt;
&lt;br /&gt;
== Menulist - the built in default ==&lt;br /&gt;
&lt;br /&gt;
You can find the source for menulist here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
PowerUI\Source\Extras\Context Menus\Built in\Menulist&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Context_Menu&amp;diff=745</id>
		<title>Context Menu</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Context_Menu&amp;diff=745"/>
				<updated>2017-04-19T05:10:50Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Context menus pop up to display one or more options to the user, depending on what it was that they interacted with. They come in a huge variety of shapes and sizes - from radial &amp;quot;Sims style&amp;quot; to ordinary lists that show up when you right click. PowerUI has a built in context menu system which sits on top of the [[Widget Manager|widget system]] enabling [[Widget Templates|templates of context menu&amp;#039;s]] to be easily created and shared.&lt;br /&gt;
&lt;br /&gt;
== 2D and 3D context menu&amp;#039;s ==&lt;br /&gt;
&lt;br /&gt;
Context menu&amp;#039;s can be created for either 2D or 3D objects. The flow of both has been made as consistent as possible - essentially, you need to &amp;#039;&amp;#039;&amp;#039;respond to the contextmenu event&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&lt;br /&gt;
== 2D ==&lt;br /&gt;
&lt;br /&gt;
HTML elements receive a contextmenu event, which you can connect to however you like (usually with addEventListener(&amp;quot;contextmenu&amp;quot;,..)). Use ContextEvent.add in there too in order to build up the options. For example, you might have an inventory. Each item, when clicked on, generates a context menu with options like &amp;quot;use&amp;quot; or &amp;quot;drop&amp;quot;. You&amp;#039;d add each of those via ContextEvent.add.&lt;br /&gt;
&lt;br /&gt;
== 3D ==&lt;br /&gt;
&lt;br /&gt;
Tick &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Handle 3D Input&amp;#039;&amp;#039;&amp;#039; and attach something like this to your GameObjects:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using UnityEngine;&lt;br /&gt;
using System.Collections;&lt;br /&gt;
using Dom;&lt;br /&gt;
using ContextMenus;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class My3DContextMenu : MonoBehaviour {&lt;br /&gt;
	&lt;br /&gt;
	public void OnContextMenu(ContextEvent e){&lt;br /&gt;
	&lt;br /&gt;
		// *this* GameObject has been asked for a context menu.&lt;br /&gt;
		&lt;br /&gt;
		// E.g. if this gameObject is some kind of door, then:&lt;br /&gt;
		context.add(&amp;quot;&amp;amp;Open;&amp;quot;,delegate(Option o){&lt;br /&gt;
			&lt;br /&gt;
			// &amp;#039;open&amp;#039; the door!&lt;br /&gt;
		&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you use this approach, note that &amp;#039;&amp;#039;&amp;#039;the event will bubble up the scene hierarchy&amp;#039;&amp;#039;&amp;#039;, in a similar way to it bubbling through the DOM. This way, if PowerUI&amp;#039;s input ray hits a collider which is a child of an NPC or a door etc, then it will reach the root NPC object and you&amp;#039;ll get a successful handle.&lt;br /&gt;
&lt;br /&gt;
== Advanced 3D ==&lt;br /&gt;
&lt;br /&gt;
Advanced: If you don&amp;#039;t want to add a script to every gameObject, then instead you can use the GameObject to EventTarget mapper and handle obtaining the event target in a custom way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Hook up our mapper:&lt;br /&gt;
PowerUI.Input.TargetResolver=delegate(GameObject go,out bool cancelEvent){&lt;br /&gt;
	&lt;br /&gt;
	// Don&amp;#039;t cancel the event:&lt;br /&gt;
	cancelEvent=false;&lt;br /&gt;
	&lt;br /&gt;
	// ..Do whatever you&amp;#039;d like to get hold of some object which implements IEventTarget..&lt;br /&gt;
	// (If you don&amp;#039;t get a match, that&amp;#039;s fine - return null)&lt;br /&gt;
	IEventTarget myTarget=null;&lt;br /&gt;
	&lt;br /&gt;
	return myTarget;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, you might have an NPC class (and that NPC class is an IEventTarget). You&amp;#039;d map the given gameObject through to an NPC instance.&lt;br /&gt;
&lt;br /&gt;
The dispatch method is, however, the same as the MonoBehaviour approach (only it would return e.g. context options specific to an NPC).&lt;br /&gt;
&lt;br /&gt;
== Setting up the appearance of context menu&amp;#039;s ==&lt;br /&gt;
&lt;br /&gt;
ContextEvent has a field called &amp;#039;&amp;#039;&amp;#039;template&amp;#039;&amp;#039;&amp;#039; - it&amp;#039;s the name of one of your [[Widget Templates|widget templates]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Get it as a context event:&lt;br /&gt;
ContextEvent context=e as ContextEvent;&lt;br /&gt;
&lt;br /&gt;
// Set the template to use:&lt;br /&gt;
context.template=&amp;quot;widgetTemplateName&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, it&amp;#039;s &amp;quot;menulist&amp;quot; - the name of a built in context menu. Conveniently, this approach means different objects can respond with completely different context menu styles too; for example, a 3D NPC might display a radial context menu (like in the Sims) and a 2D item in an inventory displays the default menulist.&lt;br /&gt;
&lt;br /&gt;
== Menulist - the built in default ==&lt;br /&gt;
&lt;br /&gt;
You can find the source for menulist here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
PowerUI\Source\Extras\Context Menus\Built in\Menulist&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Context_Menu&amp;diff=744</id>
		<title>Context Menu</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Context_Menu&amp;diff=744"/>
				<updated>2017-04-19T05:10:29Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Context menus pop up to display one or more options to the user, depending on what it was that they interacted with. They come in a huge variety of shapes and sizes - from radial &amp;quot;Sims style&amp;quot; to ordinary lists that show up when you right click. PowerUI has a built in context menu system which sits on top of the [[Widget Manager|widget system]] enabling [[Widget Templates|templates of context menu&amp;#039;s]] to be easily created and shared.&lt;br /&gt;
&lt;br /&gt;
== 2D and 3D context menu&amp;#039;s ==&lt;br /&gt;
&lt;br /&gt;
Context menu&amp;#039;s can be created for either 2D or 3D objects. The flow of both has been made as consistent as possible - essentially, you need to &amp;#039;&amp;#039;&amp;#039;respond to the contextmenu event&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&lt;br /&gt;
== 2D ==&lt;br /&gt;
&lt;br /&gt;
HTML elements receive a contextmenu event, which you can connect to however you like (usually with addEventListener(&amp;quot;contextmenu&amp;quot;,..)). Use ContextEvent.add in there too in order to build up the options. For example, you might have an inventory. Each item, when clicked on, generates a context menu with options like &amp;quot;use&amp;quot; or &amp;quot;drop&amp;quot;. You&amp;#039;d add each of those via ContextEvent.add.&lt;br /&gt;
&lt;br /&gt;
== Setting up the appearance of context menu&amp;#039;s ==&lt;br /&gt;
&lt;br /&gt;
ContextEvent has a field called &amp;#039;&amp;#039;&amp;#039;template&amp;#039;&amp;#039;&amp;#039; - it&amp;#039;s the name of one of your [[Widget Templates|widget templates]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Get it as a context event:&lt;br /&gt;
ContextEvent context=e as ContextEvent;&lt;br /&gt;
&lt;br /&gt;
// Set the template to use:&lt;br /&gt;
context.template=&amp;quot;widgetTemplateName&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, it&amp;#039;s &amp;quot;menulist&amp;quot; - the name of a built in context menu. Conveniently, this approach means different objects can respond with completely different context menu styles too; for example, a 3D NPC might display a radial context menu (like in the Sims) and a 2D item in an inventory displays the default menulist.&lt;br /&gt;
&lt;br /&gt;
== 3D ==&lt;br /&gt;
&lt;br /&gt;
Tick &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Handle 3D Input&amp;#039;&amp;#039;&amp;#039; and attach something like this to your GameObjects:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using UnityEngine;&lt;br /&gt;
using System.Collections;&lt;br /&gt;
using Dom;&lt;br /&gt;
using ContextMenus;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class My3DContextMenu : MonoBehaviour {&lt;br /&gt;
	&lt;br /&gt;
	public void OnContextMenu(ContextEvent e){&lt;br /&gt;
	&lt;br /&gt;
		// *this* GameObject has been asked for a context menu.&lt;br /&gt;
		&lt;br /&gt;
		// E.g. if this gameObject is some kind of door, then:&lt;br /&gt;
		context.add(&amp;quot;&amp;amp;Open;&amp;quot;,delegate(Option o){&lt;br /&gt;
			&lt;br /&gt;
			// &amp;#039;open&amp;#039; the door!&lt;br /&gt;
		&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you use this approach, note that &amp;#039;&amp;#039;&amp;#039;the event will bubble up the scene hierarchy&amp;#039;&amp;#039;&amp;#039;, in a similar way to it bubbling through the DOM. This way, if PowerUI&amp;#039;s input ray hits a collider which is a child of an NPC or a door etc, then it will reach the root NPC object and you&amp;#039;ll get a successful handle.&lt;br /&gt;
&lt;br /&gt;
== Advanced 3D ==&lt;br /&gt;
&lt;br /&gt;
Advanced: If you don&amp;#039;t want to add a script to every gameObject, then instead you can use the GameObject to EventTarget mapper and handle obtaining the event target in a custom way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Hook up our mapper:&lt;br /&gt;
PowerUI.Input.TargetResolver=delegate(GameObject go,out bool cancelEvent){&lt;br /&gt;
	&lt;br /&gt;
	// Don&amp;#039;t cancel the event:&lt;br /&gt;
	cancelEvent=false;&lt;br /&gt;
	&lt;br /&gt;
	// ..Do whatever you&amp;#039;d like to get hold of some object which implements IEventTarget..&lt;br /&gt;
	// (If you don&amp;#039;t get a match, that&amp;#039;s fine - return null)&lt;br /&gt;
	IEventTarget myTarget=null;&lt;br /&gt;
	&lt;br /&gt;
	return myTarget;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, you might have an NPC class (and that NPC class is an IEventTarget). You&amp;#039;d map the given gameObject through to an NPC instance.&lt;br /&gt;
&lt;br /&gt;
The dispatch method is, however, the same as the MonoBehaviour approach (only it would return e.g. context options specific to an NPC).&lt;br /&gt;
&lt;br /&gt;
== Menulist - the built in default ==&lt;br /&gt;
&lt;br /&gt;
You can find the source for menulist here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
PowerUI\Source\Extras\Context Menus\Built in\Menulist&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Context_Menu&amp;diff=743</id>
		<title>Context Menu</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Context_Menu&amp;diff=743"/>
				<updated>2017-04-19T05:10:04Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* 3D */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Context menus pop up to display one or more options to the user, depending on what it was that they interacted with. They come in a huge variety of shapes and sizes - from radial &amp;quot;Sims style&amp;quot; to ordinary lists that show up when you right click. PowerUI has a built in context menu system which sits on top of the [[Widget Manager|widget system]] enabling [[Widget Templates|templates of context menu&amp;#039;s]] to be easily created and shared.&lt;br /&gt;
&lt;br /&gt;
== 2D and 3D context menu&amp;#039;s ==&lt;br /&gt;
&lt;br /&gt;
Context menu&amp;#039;s can be created for either 2D or 3D objects. The flow of both has been made as consistent as possible - essentially, you need to &amp;#039;&amp;#039;&amp;#039;respond to the contextmenu event&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 3D ==&lt;br /&gt;
&lt;br /&gt;
Tick &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Handle 3D Input&amp;#039;&amp;#039;&amp;#039; and attach something like this to your GameObjects:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using UnityEngine;&lt;br /&gt;
using System.Collections;&lt;br /&gt;
using Dom;&lt;br /&gt;
using ContextMenus;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class My3DContextMenu : MonoBehaviour {&lt;br /&gt;
	&lt;br /&gt;
	public void OnContextMenu(ContextEvent e){&lt;br /&gt;
	&lt;br /&gt;
		// *this* GameObject has been asked for a context menu.&lt;br /&gt;
		&lt;br /&gt;
		// E.g. if this gameObject is some kind of door, then:&lt;br /&gt;
		context.add(&amp;quot;&amp;amp;Open;&amp;quot;,delegate(Option o){&lt;br /&gt;
			&lt;br /&gt;
			// &amp;#039;open&amp;#039; the door!&lt;br /&gt;
		&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you use this approach, note that &amp;#039;&amp;#039;&amp;#039;the event will bubble up the scene hierarchy&amp;#039;&amp;#039;&amp;#039;, in a similar way to it bubbling through the DOM. This way, if PowerUI&amp;#039;s input ray hits a collider which is a child of an NPC or a door etc, then it will reach the root NPC object and you&amp;#039;ll get a successful handle.&lt;br /&gt;
&lt;br /&gt;
== 2D ==&lt;br /&gt;
&lt;br /&gt;
HTML elements receive a contextmenu event, which you can connect to however you like (usually with addEventListener(&amp;quot;contextmenu&amp;quot;,..)). Use ContextEvent.add in there too in order to build up the options. For example, you might have an inventory. Each item, when clicked on, generates a context menu with options like &amp;quot;use&amp;quot; or &amp;quot;drop&amp;quot;. You&amp;#039;d add each of those via ContextEvent.add.&lt;br /&gt;
&lt;br /&gt;
== Setting up the appearance of context menu&amp;#039;s ==&lt;br /&gt;
&lt;br /&gt;
ContextEvent has a field called &amp;#039;&amp;#039;&amp;#039;template&amp;#039;&amp;#039;&amp;#039; - it&amp;#039;s the name of one of your [[Widget Templates|widget templates]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Get it as a context event:&lt;br /&gt;
ContextEvent context=e as ContextEvent;&lt;br /&gt;
&lt;br /&gt;
// Set the template to use:&lt;br /&gt;
context.template=&amp;quot;widgetTemplateName&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, it&amp;#039;s &amp;quot;menulist&amp;quot; - the name of a built in context menu. Conveniently, this approach means different objects can respond with completely different context menu styles too; for example, a 3D NPC might display a radial context menu (like in the Sims) and a 2D item in an inventory displays the default menulist.&lt;br /&gt;
&lt;br /&gt;
== Menulist - the built in default ==&lt;br /&gt;
&lt;br /&gt;
You can find the source for menulist here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
PowerUI\Source\Extras\Context Menus\Built in\Menulist&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Context_Menu&amp;diff=742</id>
		<title>Context Menu</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Context_Menu&amp;diff=742"/>
				<updated>2017-04-19T05:08:41Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* 3D */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Context menus pop up to display one or more options to the user, depending on what it was that they interacted with. They come in a huge variety of shapes and sizes - from radial &amp;quot;Sims style&amp;quot; to ordinary lists that show up when you right click. PowerUI has a built in context menu system which sits on top of the [[Widget Manager|widget system]] enabling [[Widget Templates|templates of context menu&amp;#039;s]] to be easily created and shared.&lt;br /&gt;
&lt;br /&gt;
== 2D and 3D context menu&amp;#039;s ==&lt;br /&gt;
&lt;br /&gt;
Context menu&amp;#039;s can be created for either 2D or 3D objects. The flow of both has been made as consistent as possible - essentially, you need to &amp;#039;&amp;#039;&amp;#039;respond to the contextmenu event&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 3D ==&lt;br /&gt;
&lt;br /&gt;
Attach something like this to your GameObject:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using UnityEngine;&lt;br /&gt;
using System.Collections;&lt;br /&gt;
using Dom;&lt;br /&gt;
using ContextMenus;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class My3DContextMenu : MonoBehaviour {&lt;br /&gt;
	&lt;br /&gt;
	public void OnContextMenu(ContextEvent e){&lt;br /&gt;
	&lt;br /&gt;
		// *this* GameObject has been asked for a context menu.&lt;br /&gt;
		&lt;br /&gt;
		// E.g. if this gameObject is some kind of door, then:&lt;br /&gt;
		context.add(&amp;quot;&amp;amp;Open;&amp;quot;,delegate(Option o){&lt;br /&gt;
			&lt;br /&gt;
			// &amp;#039;open&amp;#039; gameObject&lt;br /&gt;
		&lt;br /&gt;
		});&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you use this approach, note that &amp;#039;&amp;#039;&amp;#039;the event will bubble up the scene hierarchy&amp;#039;&amp;#039;&amp;#039;, in a similar way to it bubbling through the DOM. This way, if PowerUI&amp;#039;s input ray hits a collider which is a child of an NPC or a door etc, then it will reach the root NPC object and you&amp;#039;ll get a successful handle.&lt;br /&gt;
&lt;br /&gt;
Advanced: If you don&amp;#039;t want to add a script to every gameObject, then instead you can use the GameObject to EventTarget mapper and handle obtaining the event target in a custom way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Hook up our mapper:&lt;br /&gt;
PowerUI.Input.TargetResolver=delegate(GameObject go,out bool cancelEvent){&lt;br /&gt;
	&lt;br /&gt;
	// Don&amp;#039;t cancel the event:&lt;br /&gt;
	cancelEvent=false;&lt;br /&gt;
	&lt;br /&gt;
	// ..Do whatever you&amp;#039;d like to get hold of some object which implements IEventTarget..&lt;br /&gt;
	// (If you don&amp;#039;t get a match, that&amp;#039;s fine - return null)&lt;br /&gt;
	IEventTarget myTarget=null;&lt;br /&gt;
	&lt;br /&gt;
	return myTarget;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, you might have an NPC class (and that NPC class is an IEventTarget). You&amp;#039;d map the given gameObject through to an NPC instance.&lt;br /&gt;
&lt;br /&gt;
The dispatch method is, however, the same as the MonoBehaviour approach (only it would return e.g. context options specific to an NPC).&lt;br /&gt;
&lt;br /&gt;
== 2D ==&lt;br /&gt;
&lt;br /&gt;
HTML elements receive a contextmenu event, which you can connect to however you like (usually with addEventListener(&amp;quot;contextmenu&amp;quot;,..)). Use ContextEvent.add in there too in order to build up the options. For example, you might have an inventory. Each item, when clicked on, generates a context menu with options like &amp;quot;use&amp;quot; or &amp;quot;drop&amp;quot;. You&amp;#039;d add each of those via ContextEvent.add.&lt;br /&gt;
&lt;br /&gt;
== Setting up the appearance of context menu&amp;#039;s ==&lt;br /&gt;
&lt;br /&gt;
ContextEvent has a field called &amp;#039;&amp;#039;&amp;#039;template&amp;#039;&amp;#039;&amp;#039; - it&amp;#039;s the name of one of your [[Widget Templates|widget templates]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Get it as a context event:&lt;br /&gt;
ContextEvent context=e as ContextEvent;&lt;br /&gt;
&lt;br /&gt;
// Set the template to use:&lt;br /&gt;
context.template=&amp;quot;widgetTemplateName&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, it&amp;#039;s &amp;quot;menulist&amp;quot; - the name of a built in context menu. Conveniently, this approach means different objects can respond with completely different context menu styles too; for example, a 3D NPC might display a radial context menu (like in the Sims) and a 2D item in an inventory displays the default menulist.&lt;br /&gt;
&lt;br /&gt;
== Menulist - the built in default ==&lt;br /&gt;
&lt;br /&gt;
You can find the source for menulist here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
PowerUI\Source\Extras\Context Menus\Built in\Menulist&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Click_through&amp;diff=741</id>
		<title>Click through</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Click_through&amp;diff=741"/>
				<updated>2017-04-19T05:06:14Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It&amp;#039;s very common to have game world objects which can be clicked/ tapped on. However, if your UI is over one of those objects, you might get something called &amp;#039;click through&amp;#039; - where both the UI and your game world object handle the click.&lt;br /&gt;
&lt;br /&gt;
== Why click through happens ==&lt;br /&gt;
&lt;br /&gt;
Unity doesn&amp;#039;t provide a way to block the built in raycast which occurs when the screen is pressed or the mouse is clicked. Click through happens for Unity&amp;#039;s built in GUI too. So, because PowerUI can&amp;#039;t block it from happening, both Unity&amp;#039;s raycast and PowerUI&amp;#039;s element resolve occur at the same time - when both happen to get handled, then the click through scenario arises.&lt;br /&gt;
&lt;br /&gt;
== Avoiding it ==&lt;br /&gt;
&lt;br /&gt;
Unity GUI and older versions of PowerUI have a flag which you check from your MonoBehaviour click methods (like OnMouseDown). Due to a wider variety of events (e.g. the touch events) and as PowerUI fully supports multi-touch (which the flag route fails for), there&amp;#039;s now two potential routes - both involve catching the event after they&amp;#039;ve passed through the UI:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Use Input.Unhandled ===&lt;br /&gt;
&lt;br /&gt;
See also the [[Event Flow|event flow]]. This special EventTarget receives all events which were not handled by your UI. If you click &amp;#039;through&amp;#039; your UI, the mouse/touch events are sent here. Grab them using addEventListener:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
PowerUI.Input.Unhandled.addEventListener(&amp;quot;mousedown&amp;quot;,delegate(MouseEvent e){&lt;br /&gt;
    &lt;br /&gt;
    // They clicked on *nothing!* (straight &amp;#039;through&amp;#039; the UI).&lt;br /&gt;
    // Send this event wherever you&amp;#039;d like.&lt;br /&gt;
    // Note that the original raycast (and any GameObject it hit) are available:&lt;br /&gt;
    if(e.raySuccess){&lt;br /&gt;
        // It hit something! Use rayHit next.&lt;br /&gt;
&lt;br /&gt;
        // Get the clicked gameObject:&lt;br /&gt;
        GameObject go = e.rayHit.gameObject;&lt;br /&gt;
        &lt;br /&gt;
        // Try getting a MonoBehaviour called &amp;#039;MyInputScript&amp;#039;:&lt;br /&gt;
        MyInputScript myInput = go.GetComponent&amp;lt;MyInputScript&amp;gt;();&lt;br /&gt;
        &lt;br /&gt;
        if(myInput != null){&lt;br /&gt;
            // Great - forward the event to it:&lt;br /&gt;
            myInput.MouseDown(e);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PowerUI tries to give your input system as much flexibility as possible, so the above route is considered relatively low level and which allows you to pipe those events wherever you need them, but requires a little more scripting to hook it up.&lt;br /&gt;
&lt;br /&gt;
=== Setup an EventTarget MonoBehaviour ===&lt;br /&gt;
&lt;br /&gt;
This is the easier route, but involves PowerUI defining more of your input system. This also has the advantage of being able to correctly handle 3D [[Context Menu|context menu&amp;#039;s]] too. Firstly, tick the &amp;quot;Handle 3D Input&amp;quot; box in &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Input Settings&amp;#039;&amp;#039;&amp;#039;, then typically all you&amp;#039;ll need to do is just add &amp;quot;MouseEvent&amp;quot; to e.g. OnMouseDown. Here&amp;#039;s an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// A MonoBehaviour attached to a GameObject with a collider.&lt;br /&gt;
public class MyGameworldEvents : MonoBehaviour{&lt;br /&gt;
    &lt;br /&gt;
    public void OnMouseDown(MouseEvent e){&lt;br /&gt;
        // To &amp;#039;convert&amp;#039; a method, all we&amp;#039;ve really done is add the MouseEvent parameter.&lt;br /&gt;
        // That makes it much better at dealing with multitouch too.&lt;br /&gt;
        &lt;br /&gt;
        // This runs when this gameobject got clicked on&lt;br /&gt;
        // and the UI was not.&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way you can dispatch any event to any gameObject too:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Create whatever event type you&amp;#039;d like:&lt;br /&gt;
MissionEvent e= new MissionEvent(&amp;quot;missioncomplete&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Dispatch it to a gameobject:&lt;br /&gt;
aGameObject.dispatchEvent(e);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// A MonoBehaviour attached to a GameObject with a collider.&lt;br /&gt;
public class MyGameworldEvents : MonoBehaviour{&lt;br /&gt;
    &lt;br /&gt;
    public void OnMissionComplete(MissionEvent e){&lt;br /&gt;
        // Your method must simply start with &amp;#039;On&amp;#039; and accept exactly 1 event argument.&lt;br /&gt;
        &lt;br /&gt;
        // This will receive the above missioncomplete event.&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Click_through&amp;diff=740</id>
		<title>Click through</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Click_through&amp;diff=740"/>
				<updated>2017-04-19T05:05:48Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: /* Setup an EventTarget MonoBehaviour */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It&amp;#039;s very common to have game world objects which can be clicked/ tapped on. However, if your UI is over one of those objects, you might get something called &amp;#039;click through&amp;#039; - where both the UI and your game world object handle the click.&lt;br /&gt;
&lt;br /&gt;
== Why click through happens ==&lt;br /&gt;
&lt;br /&gt;
Unity doesn&amp;#039;t provide a way to block the built in raycast which occurs when the screen is pressed or the mouse is clicked. Click through happens for Unity&amp;#039;s built in GUI too. So, because PowerUI can&amp;#039;t block it from happening, both Unity&amp;#039;s raycast and PowerUI&amp;#039;s element resolve occur at the same time - when both happen to get handled, then the click through scenario arises.&lt;br /&gt;
&lt;br /&gt;
== Avoiding it ==&lt;br /&gt;
&lt;br /&gt;
Unity GUI and older versions of PowerUI have a flag which you check from your MonoBehaviour click methods (like OnMouseDown). Due to a wider variety of events (e.g. the touch events) and as PowerUI fully supports multi-touch (which the flag route fails for), there&amp;#039;s now two potential routes - both involve catching the event after they&amp;#039;ve passed through the UI:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Use Input.Unhandled ===&lt;br /&gt;
&lt;br /&gt;
See also the [[Event Flow|event flow]]. This special EventTarget receives all events which were not handled by your UI. If you click &amp;#039;through&amp;#039; your UI, the mouse/touch events are sent here. Grab them using addEventListener:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
PowerUI.Input.Unhandled.addEventListener(&amp;quot;mousedown&amp;quot;,delegate(MouseEvent e){&lt;br /&gt;
    &lt;br /&gt;
    // They clicked on *nothing!* (straight &amp;#039;through&amp;#039; the UI).&lt;br /&gt;
    // Send this event wherever you&amp;#039;d like.&lt;br /&gt;
    // Note that the original raycast (and any GameObject it hit) are available:&lt;br /&gt;
    if(e.raySuccess){&lt;br /&gt;
        // It hit something! Use rayHit next.&lt;br /&gt;
&lt;br /&gt;
        // Get the clicked gameObject:&lt;br /&gt;
        GameObject go = e.rayHit.gameObject;&lt;br /&gt;
        &lt;br /&gt;
        // Try getting a MonoBehaviour called &amp;#039;MyInputScript&amp;#039;:&lt;br /&gt;
        MyInputScript myInput = go.GetComponent&amp;lt;MyInputScript&amp;gt;();&lt;br /&gt;
        &lt;br /&gt;
        if(myInput != null){&lt;br /&gt;
            // Great - forward the event to it:&lt;br /&gt;
            myInput.MouseDown(e);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PowerUI tries to give your input system as much flexibility as possible, so the above route is considered relatively low level and which allows you to pipe those events wherever you need them, but requires a little more scripting to hook it up.&lt;br /&gt;
&lt;br /&gt;
=== Setup an EventTarget MonoBehaviour ===&lt;br /&gt;
&lt;br /&gt;
This is the easier route, but involves PowerUI defining more of your input system. This also has the advantage of being able to correctly handle 3D [[Context Menu|context menu&amp;#039;s]] too. Firstly, tick the &amp;quot;Handle 3D Input&amp;quot; box in &amp;#039;&amp;#039;&amp;#039;Window &amp;gt; PowerUI &amp;gt; Input Settings&amp;#039;&amp;#039;&amp;#039;, then typically all you&amp;#039;ll need to do is just add &amp;quot;MouseEvent&amp;quot; to e.g. OnMouseDown. Here&amp;#039;s an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// A MonoBehaviour attached to a GameObject with a collider.&lt;br /&gt;
public class MyGameworldEvents : MonoBehaviour{&lt;br /&gt;
    &lt;br /&gt;
    public void OnMouseDown(MouseEvent e){&lt;br /&gt;
        // To &amp;#039;convert&amp;#039; a method, all we&amp;#039;ve really done is add the MouseEvent parameter.&lt;br /&gt;
        // That makes it much better at dealing with multitouch too.&lt;br /&gt;
        &lt;br /&gt;
        // This runs when this gameobject got clicked on&lt;br /&gt;
        // and the UI was not.&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way you can dispatch any event to any gameObject too:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Create whatever event type you&amp;#039;d like:&lt;br /&gt;
MissionEvent e= new MissionEvent(&amp;quot;missioncomplete&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Dispatch it to a gameobject:&lt;br /&gt;
aGameObject.dispatchEvent(e);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// A MonoBehaviour attached to a GameObject with a collider.&lt;br /&gt;
public class MyGameworldEvents : MonoBehaviour{&lt;br /&gt;
    &lt;br /&gt;
    public void OnMissionComplete(MissionEvent e){&lt;br /&gt;
        // Your method must simply start with &amp;#039;On&amp;#039; and accept exactly 1 event argument.&lt;br /&gt;
        &lt;br /&gt;
        // This will receive the above missioncomplete event.&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternative design ==&lt;br /&gt;
&lt;br /&gt;
PowerUI could use reflection like Unity does to look for OnMouseDown(MouseEvent e) and similar methods so your scripts could be like this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class MyGameworldEvents : MonoBehaviour{&lt;br /&gt;
    &lt;br /&gt;
    public void OnMouseDown(MouseEvent e){&lt;br /&gt;
    &lt;br /&gt;
        // This runs when this gameobject got clicked on&lt;br /&gt;
        // and the UI was not.&lt;br /&gt;
        // Importantly, you have extra information about this particular click&lt;br /&gt;
        // such as the finger that caused it.&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The bonus being it would easily work with all of your custom events too:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class MyGameworldEvents : MonoBehaviour{&lt;br /&gt;
    &lt;br /&gt;
    public void OnMissionComplete(MissionEvent e){&lt;br /&gt;
        // A mission was completed&lt;br /&gt;
        // and the event was dispatched to this gameObject.&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever an event is first dispatched to a gameObject, it would collect the handlers by looking for methods which accept 1 event object and start with &amp;#039;On&amp;#039;, then pass them to addEventListener. That should ultimately be only a small amount of extra overhead for lots more convenience - Any opinions?&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	<entry>
		<id>https://powerui.kulestar.com/wiki/index.php?title=Caret&amp;diff=738</id>
		<title>Caret</title>
		<link rel="alternate" type="text/html" href="https://powerui.kulestar.com/wiki/index.php?title=Caret&amp;diff=738"/>
				<updated>2017-04-17T19:52:37Z</updated>
		
		<summary type="html">&lt;p&gt;Bablakeluke: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In PowerUI, the caret seen in both textarea&amp;#039;s and input elements is a [[Virtual Elements|virtual &amp;lt;caret&amp;gt; element]]. Its appearance comes from the caret selector in the [[User agent stylesheet|user agent stylesheet]] and it&amp;#039;s declared like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
caret{&lt;br /&gt;
    /* Other position properties removed from here */&lt;br /&gt;
    /* This is the most important one: */&lt;br /&gt;
    border-left:1px solid black;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Its appearance is defined as a &amp;#039;&amp;#039;&amp;#039;black left border&amp;#039;&amp;#039;&amp;#039;. We may remove the word &amp;#039;black&amp;#039; in order to make it always default to the font colour in the future. Black is currently present as the default font colour for the PowerUI main UI is &amp;#039;&amp;#039;white&amp;#039;&amp;#039; and a white caret is often unwanted.&lt;br /&gt;
&lt;br /&gt;
== Styling the caret ==&lt;br /&gt;
&lt;br /&gt;
Often a UI will want to style a caret differently from the text. As it&amp;#039;s a caret element, you can simply declare a caret style in your HTML like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
caret{&lt;br /&gt;
    /* All of my carets will be blue */&lt;br /&gt;
    border-color:blue;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The caret acts as a direct child of your textarea or input field, so you can target specific ones using any ordinary selector too:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
textarea caret{&lt;br /&gt;
    /* Carets in textareas will be red */&lt;br /&gt;
    border-color:red;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
input caret{&lt;br /&gt;
    /* Carets in input fields will be white */&lt;br /&gt;
    border-color:white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#nameField caret{&lt;br /&gt;
    /* The caret in an input field with the id &amp;#039;nameField&amp;#039; will be blue */&lt;br /&gt;
    border-color:blue;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You could also use border-width to control the thickness of your caret too.&lt;/div&gt;</summary>
		<author><name>Bablakeluke</name></author>	</entry>

	</feed>