UGTK / Toolkit / Ui Module / Screen Chooser System Completed
Screen Chooser System
Summary
ScreenChooser watches the screen orientation and fires UnityEvents when it changes, so a layout can
rearrange itself without a single line of code. It reports two different things, and knowing the
difference is the whole point of the module:
- logical orientation — what the device says (
Portrait,PortraitUpsideDown,LandscapeLeft,LandscapeRight); - visual orientation — what the window actually looks like (
widthvsheight), which is the one that matters on desktop, in the editor and in a resizable WebGL canvas, where the device orientation isUnknownor never changes.
Content
Modules Dependencies
None. Only UnityEngine (Screen.orientation, Screen.width/height) and UnityEvents.
Setup
Drop the ScreenChooser prefab into the scene — a GameObject carrying the component with all six
events ready to be wired. Or add the component to any GameObject that lives as long as the layout it
drives.
There is no GIF for this module: the effect is a device rotation, which is neither visible nor reproducible inside the editor window.
How To Use
Wire the events in the inspector:
Logical Orientation Events — On Portrait, On Portrait Upside Down, On Landscape Left,
On Landscape Right. These follow Screen.orientation, so they are meaningful on phones and
tablets.
Visual Orientation Events — On Visual Portrait, On Visual Landscape. These follow
Screen.height > Screen.width. This is the pair you want on desktop, WebGL and in the editor,
where the logical orientation never changes.
Settings — Continuous Update (off by default): when on, the events fire at every poll tick
(five times a second) instead of only when the orientation changes. Turn it on only for something
that must be driven continuously; leave it off for normal layout switching, or your listeners run 5×
per second forever.
Good to know:
- It fires once on
Startwith the current orientation, so a listener that arranges the layout is called at least once without any rotation. - Polling is every 0.2 s in a coroutine — a rotation can take up to 200 ms to be picked up. That is imperceptible for a layout switch, but do not use it to drive an animation.
- The two families are independent:
LandscapeLeftandLandscapeRightboth raiseOnVisualLandscape. If you only care about "is it wide or tall", use the visual pair and ignore the logical one. - The class is called
ScreenChooser, without theMn_prefix, even though the file isMn_ScreenChooser.cs: useGetComponent<ScreenChooser>().
Testing Scene
Open Debug/ScreenChooserScene.unity. It holds a Canvas, an EventSystem and the
ScreenChooser prefab. A desktop editor cannot be physically rotated, so the component's
inspector carries an Editor Test Tools block that stands in for a device.
The block has two halves:
- What Unity reports —
Screen.orientationand the shape derived from width versus height. These are the values the component itself watches, and they update as you change the Game view's aspect ratio. It is worth checking them before blaming the component: on a desktop editorScreen.orientationoften reports something a phone never would. - Visual events and Precise events — six buttons that raise the events by hand, so a layout can be finished and tested without a device in your hand.
Wire your layout to the visual pair, OnVisualPortrait and OnVisualLandscape. They are
derived from width versus height, which is the question a layout actually asks. The precise four —
OnPortrait, OnPortraitUpsideDown, OnLandscapeLeft, OnLandscapeRight — matter only when the
exact rotation does, a compass or a camera overlay for instance. Driving a layout from them means
handling upside-down portrait separately for no reason, and forgetting it is a bug that only shows
up on a device someone happens to hold the wrong way round.
Technical Info
| Path | Content |
|---|---|
Scripts/Runtime/Mn_ScreenChooser.cs |
The whole system: the ScreenChooser component, the 0.2 s polling coroutine, the logical and visual event dispatch |
Prefabs/ScreenChooser.prefab |
GameObject with the component ready to wire |
Public members: OnPortrait, OnPortraitUpsideDown, OnLandscapeLeft, OnLandscapeRight,
OnVisualPortrait, OnVisualLandscape, continuousUpdate.
© 2026 Marcello De Bonis. All rights reserved
UGTKengine within an engine


