Better Navigation
The Better Navigation component is crucial for the whole navigation system to work.
It must be added to the same game object that also holds the Event System and Input Module.
You can easily add a Better Navigation component, by right-clicking on the Event System and selecting "Add Better Navigation".
Inspector Properties
Omit Selection State For Pointer Input
The Problem it solves:
In UGUI 2019+ there are five transition states: Normal, Highlight, Pressed, Selected and Disabled.
Highlight is the state when the mouse is hovering over the selectable element, but it can only transition from the Normal state to highlight.
Selected is the state used for gamepad and keyboard input to display which element is currently focused. If the Navigation property of the selectable is not "None", it will also transition to the selected state after clicking or tapping on it. From the Selected state, the selectable cannot transition to hover, so that the last clicked element will not ever show a hover effect until another element becomes selected.
If the property is checked, Better Navigation will automatically deselect the element as soon as mouse or touch input is detected. This allows the element to transition to the highlighted state when the mouse hovers over it.
However, Better UI remembers the last selected element, so that it will select that element (with a transition to the selected state) as soon as gamepad or keyboard input is detected. This also works when you deselect a selectable by clicking somewhere on the screen.
Handle Navigation Input
If checked Better Navigation handles all the navigation logic. This disables "Send Navigation Events" in the Event System.
This is required if you want to use more Better UI navigation features than just "Omit Selection State For Pointer Input".
The logic applied by Better Navigation to handle input should behave the same as UGUI. However, it cannot be guaranteed that it is exactly the same.
Dirty State Detection
Defines the logic how to detect if Navigation Groups or the "Root Selectables" should update their collection of selectables.
- None
The collections are never set dirty. Use this, if you are sure that there are no dynamic elements in the UI. Meaning your UI is defined in prefabs or the scene, but nothing is instantiated or destroyed via code. - Check Count Change
The number of currently active selectables are compared to the number of selectables from the previous frame. This is correctly detecting changes for the very most cases and is pretty fast. - Check Each Selectable
This will keep track of all selectables and compares each of them to the selectables of the previous frame. This detects if a selectable was removed and another one was added in the same frame, resulting in the same count of selectables.
While the implementation is well optimized, it is still a lot slower than Check Count Change.
Root Selectables
An Selectable Collection which do not belong to any Navigation Group.
Code Access
Static
Current
Returns the Better Navigation instance that is on the same Game Object as EventSystem.current (can return null).
InputDetectorsForInputModulesFactories
This is a dictionary to instantiate the correct Input Detector for the given input system. Better UI supports out of the box Unity's legacy input system, Unity's "new" input system as well as Rewired (if enabled with the wizard).
If you use a different input system, you can support this by adding a new entry to that dictionary:
Key: The type of the Input Module (derived from Unity's "BaseInputModule") for the input system you are using
Value: A Func<BaseInputModule, IInputDetector>. You can assume that the BaseInputModule parameter has the same type as you defined as key. The Func should return your own implementation of a class that implements IInputDetector.
Make sure you add your custom entry before BetterNavigation Awake is called (you may need to set the script execution order of your class to a negative value).
LastSelection
Gets the Selectable that was selected last. It may not have a selected state currently.
SelectableChanged
A Callback that is called whenever the current selectable has changed.
void CurrentSelectableChanged(Selectable previousSelectable, Selectable currentSelectable)
Note that both parameters may be null in certain cases (on deselect / re-select).
SetDirty()
Invalidates the state of all Selectable Collections and recollects all selectables of the current Navigation Group.
Non-Static
EventSystem
The EventSystem component on the same game object.
ElementCollection
Gets the Root Selectables.
HandleNavigationInput
See Inspector Properties
OmitSelectionStateForPointerInput
See Inspector Properties
InputDetector
Gets the Input Detector for the used Input System.
HasCancelAction
Returns true if a cancel action has been triggered at the last update - or if the currently active Navigation Group has a cancel action assigned.
As the cancel action may have destroyed the previously active Navigation Group, it might be interesting to know, if the action was handled this frame, so your game's input logic does not trigger some non-UI logic.
CurrentSelectables
The Selectables which are managed by the current Navigation Group. If there is no Navigation Group active, it returns the Root Selectables (see Inspector Properties).
Notes
Better Navigation derives from Selectable, although it actually is no selectable and cannot be selected (unless you find a way). This is to be able to access static members which are marked protected. They are needed for an efficient dirty-state-detection.