UnityRef is currently in early development. Some features may be incomplete and/or not functioning.

UNITYREF

Your Pit Stop For Solving ANYTHING in Unity

ui

[AccessibilityNode] Optimize Screen Reader Interactions

Solution

accessibilityuser experience

Unity 2021.x - Unity 6.3.x

Published Thu, Mar 12

Issue

UI elements obscured by Mask or Canvas overlays remain detectable by screen readers because the AccessibilityNode hierarchy operates independently of the standard GameObject hierarchy. This results in unintended focus and confusing audio feedback for non-visible elements.

Explanation

The accessibility hierarchy in Unity is not automatically synchronized with visual visibility or the Canvas sorting order. Consequently, a GameObject that is visually hidden may still be reachable by assistive technologies. To resolve this, the AccessibilityNode.isActive property must be manually toggled to reflect the current UI state.

  1. Instantiate an AccessibilityNode for your script and register it via Accessibility.AddNode within the OnEnable lifecycle.
  2. Set AccessibilityNode.isActive to false whenever the element is visually obscured by your Mask, a popup, or is otherwise non-interactable.
  3. Define the AccessibilityNode.role using the AccessibilityRole enum to provide the screen reader with the correct semantic context.
  4. Update the AccessibilityNode.label and AccessibilityNode.hint properties to convey the purpose and interaction method of the element.
  5. Call Accessibility.UpdateNode to push property changes from the AccessibilityNode to the active screen reader.

Additional Tips

  • Screen reader announcement sequences, such as state-first or label-first, are dictated by the native OS (TalkBack/VoiceOver) and are not configurable via the Unity API.
  • For dynamic lists, use the AccessibilityNode.value property to store positional information like “Item 5 of 20”.
  • When a child element gains focus, prepending the parent context to your AccessibilityNode.label ensures the user maintains spatial awareness.
  • Ensure Accessibility.RemoveNode is called when the AccessibilityNode is no longer needed to maintain hierarchy integrity.

TL;DR

Use the AccessibilityNode.isActive property to manage visibility and the Accessibility.UpdateNode method to synchronize changes between AccessibilityNode objects and the native screen reader.


Related Posts Haven't quite found a solution to your problem? We think these posts might help you.

Content inspired by a Unity discussion post.