Начало работы с поддержкой экранного чтения
Поддержка экранных читателей APIs не зависит от системы UI, поэтому они работают с UI Toolkit, uGUI, пользовательскими UI фреймворками и не-UI контентом, таким как 2D или 3D объекты в игровом мире. Для простоты, в этом руководстве используется UI Toolkit, но вы можете адаптировать код к вашему UI фреймворку по выбору.
Примерный обзор
В этом примере показано, как создать узел доступности, подключить его к кнопке UI Toolkit и протестировать его с помощью экранных читателей платформы. В конце у вас будет кнопка, которую могут читать и активировать собственные экранные читатели платформы.
Предварительные условия
Это руководство предназначено для разработчиков, знакомых со скриптами Unity Editor, UI Toolkit и C#. Перед началом работы ознакомьтесь со следующим:
Включить модуль доступности
Модуль специальных возможностей включён по умолчанию. Если по какой-либо причине он не включён в проекте, выполните следующие действия:
- Выберите Окно > Управление пакетами > Package Manager, чтобы открыть Package Manager.
- Выберите раздел Встроенный.
- Выберите модуль Доступность.
- Выберите Включить.
Создание кнопки
Используйте UI Toolkit для создания кнопки Start Game в сцене.
Создайте проект с любым шаблоном.
-
Создайте файл UXML с именем
AccessibleStartMenu.uxmlсо следующим содержимым:<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False"> <ui:Button text="Start Game" name="startButton"/> </ui:UXML> Создайте скрипт C# с именем
AccessibleStartMenu.csсо следующим содержанием:
using UnityEngine;
using UnityEngine.UIElements;
public class AccessibleStartMenu : MonoBehaviour
{
Button m_Button;
void OnEnable()
{
VisualElement root = GetComponent<UIDocument>().rootVisualElement;
m_Button = root.Q<Button>("startButton");
m_Button.clicked += OnButtonClicked;
}
void OnDisable()
{
m_Button.clicked -= OnButtonClicked;
}
void OnButtonClicked()
{
Debug.Log("Start Game button clicked");
}
}
Создание иерархии доступности
Иерархия доступности представляет собой семантическое представление вашего UI, которое экранные редакторы используют для обнаружения и взаимодействия с вашим контентом. Экранные редакторы не могут непосредственно обнаружить компоненты GameObject или элементы UI. Они полагаются на эту иерархию для навигации по вашему приложению. Вы создаете AccessibilityHierarchy, а затем добавляете AccessibilityNode, который представляет кнопку Start Game.
Чтобы создать иерархию доступности:
- Добавить пространство имен
UnityEngine.Accessibility. - Создание экземпляра
AccessibilityHierarchy. - Создайте и добавьте
AccessibilityNodeв иерархию доступности. - Установите свойства
label,roleиstateузла в соответствии с текстом кнопки и состоянием интерактивности.
// ...
using UnityEngine.Accessibility;
public class AccessibleStartMenu : MonoBehaviour
{
// ...
AccessibilityHierarchy m_AccessibilityHierarchy;
AccessibilityNode m_AccessibilityNode;
void OnEnable()
{
// ...
CreateAccessibilityHierarchy();
}
// ...
void CreateAccessibilityHierarchy()
{
// Create a new accessibility hierarchy.
m_AccessibilityHierarchy = new AccessibilityHierarchy();
// Create a new accessibility node with the button's text as the label
// (what the screen readers announces).
m_AccessibilityNode = m_AccessibilityHierarchy.AddNode(m_Button.text);
// Set a semantic role (tells the screen reader this is a button).
m_AccessibilityNode.role = AccessibilityRole.Button;
// Set the state (is it currently interactable?).
m_AccessibilityNode.state = m_Button.enabledSelf ?
AccessibilityState.None : AccessibilityState.Disabled;
}
}
Установите координаты экрана узла в соответствии с размером и положением кнопки
Чтобы установить координаты экрана узла:
- Отслеживайте изменения размера и положения кнопки.
- Рассчитать его экранные координаты из его мировых координат и масштаба UI.
- Установите свойство узла
frameна вычисленный прямоугольник экрана.
Обновите скрипт AccessibleStartMenu.cs следующим образом:
public class AccessibleStartMenu : MonoBehaviour
{
// ...
void OnEnable()
{
// ...
m_Button.RegisterCallback<GeometryChangedEvent>(OnGeometryChanged);
}
void OnDisable()
{
// ...
m_Button.UnregisterCallback<GeometryChangedEvent>(OnGeometryChanged);
}
// ...
void OnGeometryChanged(GeometryChangedEvent evt)
{
Rect worldRect = m_Button.worldBound;
float scale = m_Button.panel.scaledPixelsPerPoint;
// Update the screen coordinates of the node.
m_AccessibilityNode.frame =
new Rect(worldRect.position * scale, worldRect.size * scale);
}
}
Подключите событие активации узла к кнопке
Подписаться на событие узла invoked, которое запускается, когда пользователь активирует узел с помощью экранного читателя, а затем вызвать событие кнопки NavigationSubmitEvent в обработчике событий.
Обновите метод CreateAccessibilityHierarchy в скрипте AccessibleStartMenu.cs следующим образом:
public class AccessibleStartMenu : MonoBehaviour
{
// ...
void CreateAccessibilityHierarchy()
{
// ...
// Handle when the user activates this node (e.g., double-tap).
// Called `selected` in versions before Unity 6.3.
m_AccessibilityNode.invoked += () =>
{
using var evt = NavigationSubmitEvent.GetPooled();
evt.target = m_Button;
m_Button.SendEvent(evt);
return true;
};
}
}
Активация иерархии доступности при включении программы чтения экрана
- Когда появится меню, активируйте иерархию доступности, назначив ее
AssistiveSupport.activeHierarchy.- Когда пользователь выключает экранный проигрыватель,
AssistiveSupport.activeHierarchyавтоматически настраивается наnullдля высвобождения ресурсов.
- Когда пользователь выключает экранный проигрыватель,
- Переназначение иерархии каждый раз, когда пользователь включает экранный читатель.
- Когда меню исчезнет, удалите иерархию, установив
AssistiveSupport.activeHierarchyнаnull.
public class AccessibleStartMenu : MonoBehaviour
{
// ...
void OnEnable()
{
// ...
AssistiveSupport.activeHierarchy = m_AccessibilityHierarchy;
AssistiveSupport.screenReaderStatusChanged += OnScreenReaderStatusChanged;
}
void OnDisable()
{
// ...
AssistiveSupport.activeHierarchy = null;
AssistiveSupport.screenReaderStatusChanged -= OnScreenReaderStatusChanged;
}
// ...
void OnScreenReaderStatusChanged(bool enabled)
{
if (enabled)
{
AssistiveSupport.activeHierarchy = m_AccessibilityHierarchy;
}
// else
// {
// // This is automatically done when the user turns the screen
// // reader off.
// AssistiveSupport.activeHierarchy = null;
// }
}
}
Вы создали семантическое представление (AccessibilityNode) визуальной кнопки, которую могут обнаружить и с которой могут взаимодействовать программы для чтения экрана.
Полный скрипт AccessibleStartMenu.cs выглядит следующим образом:
using UnityEngine;
using UnityEngine.Accessibility;
using UnityEngine.UIElements;
public class AccessibleStartMenu : MonoBehaviour
{
Button m_Button;
AccessibilityHierarchy m_AccessibilityHierarchy;
AccessibilityNode m_AccessibilityNode;
void OnEnable()
{
VisualElement root = GetComponent<UIDocument>().rootVisualElement;
m_Button = root.Q<Button>("startButton");
m_Button.clicked += OnButtonClicked;
m_Button.RegisterCallback<GeometryChangedEvent>(OnGeometryChanged);
CreateAccessibilityHierarchy();
AssistiveSupport.activeHierarchy = m_AccessibilityHierarchy;
AssistiveSupport.screenReaderStatusChanged += OnScreenReaderStatusChanged;
}
void OnDisable()
{
m_Button.clicked -= OnButtonClicked;
m_Button.UnregisterCallback<GeometryChangedEvent>(OnGeometryChanged);
AssistiveSupport.activeHierarchy = null;
AssistiveSupport.screenReaderStatusChanged -= OnScreenReaderStatusChanged;
}
void CreateAccessibilityHierarchy()
{
// Create a new accessibility hierarchy.
m_AccessibilityHierarchy = new AccessibilityHierarchy();
// Create a new accessibility node with the button's text as the label
// (what the screen readers announces).
m_AccessibilityNode = m_AccessibilityHierarchy.AddNode(m_Button.text);
// Set a semantic role (tells the screen reader this is a button).
m_AccessibilityNode.role = AccessibilityRole.Button;
// Set the state (is it currently interactable?).
m_AccessibilityNode.state = m_Button.enabledSelf ?
AccessibilityState.None : AccessibilityState.Disabled;
// Handle when the user activates this node (e.g., double-tap).
// Called `selected` in versions before Unity 6.3.
m_AccessibilityNode.invoked += () =>
{
using var evt = NavigationSubmitEvent.GetPooled();
evt.target = m_Button;
m_Button.SendEvent(evt);
return true;
};
}
void OnGeometryChanged(GeometryChangedEvent evt)
{
Rect worldRect = m_Button.worldBound;
float scale = m_Button.panel.scaledPixelsPerPoint;
// Update the screen coordinates of the node.
m_AccessibilityNode.frame =
new Rect(worldRect.position * scale, worldRect.size * scale);
}
void OnButtonClicked()
{
Debug.Log("Start Game button clicked");
}
void OnScreenReaderStatusChanged(bool isEnabled)
{
if (isEnabled)
{
AssistiveSupport.activeHierarchy = m_AccessibilityHierarchy;
}
// else
// {
// // This is automatically done when the user turns the screen
// // reader off.
// AssistiveSupport.activeHierarchy = null;
// }
}
}
Приложить скрипт
Чтобы прикрепить скрипт к вашей сцене:
- Создайте пустой
GameObjectв вашей сцене и дайте ему имяAccessibleStartMenu. - Добавить компонент
UI DocumentвGameObject. - Создайте ассет Настройки панели и назначьте его в поле
Panel Settingsв окне Inspector компонентаUI Document. - Назначьте файл
AccessibleStartMenu.uxmlв полеSource Asset. - Добавить скрипт
AccessibleStartMenu.csкGameObject.
Проверка свойств иерархии и узла в режиме воспроизведения
Для проверки свойств иерархии и узлов в Unity Editor:
- Введите режим воспроизведения.
- Выберите Окно > Доступность > Hierarchy Просмотр.
- Убедитесь, что в иерархии доступности отображается узел доступности с правильными свойствами.
Проверка взаимодействия экранного чтения на вашей целевой платформе
Чтобы проверить взаимодействие экранного чтения на целевой платформе:
- Создайте и запустите приложение на целевой платформе (Android, iOS, Windows или macOS).
- Ознакомьтесь с жестами или командами встроенного в платформу экранного чтителя:
- Android: TalkBack жесты на Android
- iOS: VoiceOver жесты на iPhone
- Windows: Команды Диктора на Windows
- macOS: VoiceOver команды на Mac
- Включите экранный читатель.
- Перейдите к кнопке с помощью жестов или команд экранного считывателя. Считывающее устройство должно фокусироваться на кнопке и объявлять «Пуск Game, кнопка».
- Активируйте кнопку с помощью жеста или команды активации средства чтения с экрана. Кнопка должна сработать, а текст “Start Game button clicked” — появиться в журнале проигрывателя.
Дополнительные ресурсы
- 📚 Документация: Модуль доступности API ссылка
- 📺 Видео: Охват новых аудиторий с помощью доступности и локализации в Unity 6 (Unite 2025)
- ⚙️ Образец проекта: LetterSpell: пример доступного Unity применение
- Сообщество: Unity Дискуссии: Доступность