为 Unity 游戏添加无障碍功能
Add accessibility to your Unity games
2022年6月6日
一句话判断
Apple 发布了 Unity 无障碍插件,让你的游戏可以通过 Accessibility Node 组件支持 VoiceOver、Switch Control 和 Dynamic Type——这是移动游戏无障碍化的一个重要里程碑。
这场 Session 讲了什么
Eric 介绍了 Apple 为 Unity 开发者推出的 Accessibility Plugin,覆盖三个核心无障碍技术的接入方式。
Accessibility Elements(无障碍元素):通过 Accessibility Node 组件让 VoiceOver 和 Switch Control 能够”看到”游戏界面上的元素。每个元素需要设置 Label(描述文字)、Traits(类型标记如 Button/Static Text)、Value(动态值如卡牌面值)。
Dynamic Type:读取用户的文字大小偏好设置,动态调整游戏中的文本尺寸。通过 PreferredContentSizeMultiplier 计算缩放比例。
UI Accommodations:读取用户的其他偏好设置,如是否开启减少动态效果、是否开启高对比度等。
值得深挖的点
游戏无障碍的核心挑战。 不同于原生 UI,游戏界面是像素渲染的——VoiceOver 看不到 Canvas 上的文字,Switch Control 点不到像素按钮。Accessibility Node 组件的作用就是在游戏对象和系统无障碍服务之间建立一座桥梁。
动态 Value 的设置方式。 卡牌游戏中卡牌的面值会随游戏进程变化,不能写死。插件通过 delegate 模式解决:设置 accessibilityValue 的 delegate 为一个函数,每次 VoiceOver 读取时动态返回当前面值。
Dynamic Type 的快速测试技巧。 在设置 > 控制中心中添加”文字大小”快捷控件,然后在游戏中随时通过控制中心调整文字大小,观察游戏 UI 是否正确响应。
代码片段
// Accessibility Node 的基本配置
// 1. 给游戏对象添加 Accessibility Node 组件
// 2. 设置 Label(VoiceOver 会朗读)
// 3. 设置 Traits(Button、Static Text 等)
// 4. 设置动态 Value
public class AccessibleCard : MonoBehaviour {
public PlayingCard cardType;
public bool isFaceUp;
void Start() {
var node = GetComponent<AccessibilityNode>();
// 设置动态 Value delegate
node.accessibilityValue = GetCardValue;
}
private string GetCardValue() {
if (!isFaceUp) {
return "covered";
}
// 返回卡牌面值描述,如 "Ace of Spades"
return cardType.ToString();
}
}
// Dynamic Type 支持
public class DynamicTextSize : MonoBehaviour {
private float defaultTextSize;
void Start() {
defaultTextSize = GetComponent<Text>().fontSize;
}
void OnEnable() {
// 订阅文字大小变化事件
AccessibilitySettings.onPreferredTextSizesChanged += SettingsChanged;
}
void SettingsChanged() {
// 读取用户偏好并调整文字大小
float multiplier = AccessibilitySettings.PreferredContentSizeMultiplier;
GetComponent<Text>().fontSize = defaultTextSize * multiplier;
}
void OnDisable() {
AccessibilitySettings.onPreferredTextSizesChanged -= SettingsChanged;
}
}
最佳实践
- 为所有可交互元素添加 Accessibility Node。 文字、按钮、卡牌——任何用户需要知道或操作的对象都应该是无障碍元素。
- Label 需要本地化。 如果游戏支持多语言,无障碍标签也应该跟随语言切换。
- 动态内容用 delegate 而非固定值。 游戏状态频繁变化,Value 应该在每次读取时动态获取。
- 测试时开启控制中心的文字大小快捷控件。 随时调整文字大小验证 Dynamic Type 的效果。
还有什么值得关注
- 插件通过 Unity Package Manager 安装,源码在 Apple 的 GitHub 仓库中
- 推荐观看 “Plug-in and play: Add Apple frameworks to your Unity game projects” 了解其他 Apple Unity 插件
- VoiceOver 和 Switch Control 的测试应该用真实设备进行
- Accessibility Node 组件支持更多 Traits(不只是 Button 和 Static Text),可以根据元素类型选择