Improving Accessibility in Unity Games – Part 1
Take your games to the next level with support for a range of accessibility options. Help deal with subtitles, color blindness, audio controls and more! By Mark Placzek.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Improving Accessibility in Unity Games – Part 1
45 mins
- Getting Started
- Trying Out Puzzley Dungeon
- Addressing Visual Impairment
- Substituting the Subtitles
- Adjusting the In-Game Text
- Setting Up Your New UI Elements
- Adding Your Font Changes to the Game’s Menus
- Changing the Font Styles in the Subtitles
- Adding an Outline to the Subtitles
- Setting Up a Separate Material for the Subtitles
- Standardizing Your Outlines
- Implementing the Outlines
- Adaptations for Color Vision Impairment
- Making a Color-Based Puzzle More Accessible
- Putting Your Requirements to Work
- Addressing Hearing Impairments
- Adding Closed Captions
- Adding Scripts to Noisy GameObjects
- Attaching the Descriptions to the Audio Sources
- Adding Directional Closed Captions
- Adding Subtitles to Sounds
- Determining Where the Sound Is
- Volume Controls
- Audio Puzzle Considerations
- Where to Go From Here?
Attaching the Descriptions to the Audio Sources
Return to Unity and type AudioSource into the search bar at the top of Hierarchy.
This should reveal several GameObjects in the scene with AudioSource components attached. Adding the AudioDescription will be simple for most of these objects, but you need to be a little careful to ensure you don't get unwanted duplicates and that you pass changes to prefabs and prefab variants correctly.
- Hold down Control, or Command on Mac, and select the following: BlueGem, ColumnTorch (just one of them), GateDoorway1, GoldKey, PressurePlate (E) and StartDoorway.
- In the Inspector, click Add Component, type AudioDescription and click Add.
You only add the AudioDescription component to one ColumnTorch; otherwise, you'll get a duplicate subtitle if both report the audio. You don't add a description to Inventory, because you already receive a subtitle when you pick up an item, so an audio cue is unnecessary.
Each of these items needs to have an appropriate message to send. In the Inspector, populate the MyDescription
in the Audio Description components with an appropriate subtitle. Here's a list you can use if you aren't feeling particularly creative:
- BlueGem: Gem clinks.
- ColumnTorch: Fire crackling.
- GateDoorway1: The ancient mechanism grinds and clanks.
- GoldKey: Metal clanks.
- PressurePlate (E): The musical note E.
- StartDoorway: The ancient mechanism grinds and clanks.
Next, you'll need to make sure the changes pass to the prefabs and prefab variants.
With the exception of the ColumnTorch, select each of these items in the Hierarchy. At the top of the InspectorOverrides drop-down and select Apply All.
There's one final change to make: While all the gems clink the same, the pressure plates need to report different sounds. Individually select PressurePlates A, B, F and G, and change the notes in the subtitle to their respective letter.
Done! Great work!
Back in Unity, click Play, make sure you enable Audio Description in the Settings menu and play through the level. Try kicking some gems, dropping some keys and so on.
Adding Directional Closed Captions
Closed captions in movies and TV generally report on the sounds and music in the scene only. In a game, however, the direction of the sounds can be very important. Knowing there's a moaning zombie, or a moaning zombie RIGHT BEHIND YOU, makes a big difference in whether you live or die!
Your next task is to add some additional code to report the direction and distance of the sounds in the subtitle, as well.
Adding Subtitles to Sounds
Head back into the AudioDescription script and add one tiny change. Within Update
´, change the following line:
settingsManager.HandleAudioDescription(myDescription);
To this line:
settingsManager.HandleAudioDescription(myDescription, gameObject);
When an object somewhere in the scene plays its audio, it will now send a subtitle to the SettingsManager and a reference to the GameObject itself.
Return to SettingsManager so that you can adjust HandleAudioDescription
to take advantage of this.
First, add the new GameObject argument to the method:
public void HandleAudioDescription(string subtitle, GameObject origin)
Determining Where the Sound Is
Secondly, what use is a reference to the source of the audio if SettingsManager does not know where the player is? To fix this problem, add this new variable at the top of the class:
private GameObject player;
And wire it up in Start
by adding this line of code:
player = GameObject.FindGameObjectWithTag("Player");
To calculate the distance and the direction from the player that a sound comes from, you need to do some calculations. This diagram shows you the theory behind the calculations:
To put that theory into practice, go to the HandleAudioDescription
method and replace this line:
gameManager.PublishSubtitle(subtitle);
With this monster:
//1
var heading = origin.transform.position - player.transform.position;
//2
var distance = heading.magnitude;
if (distance <= 5.0)
{
subtitle = subtitle + " (close ";
}
else if (distance >= 15)
{
subtitle = subtitle + " (far ";
}
else if (distance >= 20)
{
return;
}
else
{
subtitle = subtitle + " (";
}
//3
Quaternion rotation = Quaternion.LookRotation(heading, Vector3.up);
Vector3 angles = rotation.eulerAngles;
//4
// Adjust for the rotation of the player
var direction = player.transform.eulerAngles.y - angles.y;
if (direction >= -45 && direction <= 45)
{
subtitle = subtitle + "infront of you)";
}
else if (direction > 135 || direction < -135)
{
subtitle = subtitle + "behind you)";
}
else if (direction < -45 && direction >= -135)
{
subtitle = subtitle + "to your right)";
}
else if (direction > 45 && direction <= 135)
{
subtitle = subtitle + "to your left)";
}
gameManager.PublishSubtitle(subtitle);
Here's what this code does:
- By subtracting the position of the origin of the sound from the player's position, you get a vector representation of the heading.
- The magnitude, or length, of this vector will give you the distance of sound from the player. Use the distance value to determine whether the sound is close to or far from the player and add that info to the subtitle.
- LookRotation converts that heading vector into a rotation from the player to the source of the sound. You then convert this value into an angle.
- Angle is a bearing in 3D space from the player's location, so you also need to take the player's rotation into account. You subtract the player's from the angle to give you a direction that you can use to describe the location of the sound. You then add this information to the subtitle.
Wow, that was super simple!
Press Play in Unity and do some noisy stuff to see the results of your hard work!
This is a simple implementation of directional audio cues. But with the math you worked out above, you can create all sorts of interesting on-screen notifications.
For example, have a look at Fortnight. A simple compass-like ring intuitively uses icons and color to show what sounds your character hears, where they come from and how close they are.
Volume Controls
Another important consideration for players with hearing difficulties is control over the volume. Giving players control of both music and FX volume can help separate important audio cues, effects or speech from background music.
There's no music in your simple game, but the principle will be the same. You'll attach one of the AudioSources to its own channel to independently adjust its volume. You'll use the torch for this example, as it could use a volume boost. You could also adjust the terrifying and loud door/gate opening sound if you prefer.
First, in the Project view, click on the AudioMixer in Assets/RW/Audio. Open the Audio Mixer window by selecting Window ► Audio ► Audio Mixer from the toolbar.
You'll need to add a new mixer group and expose a parameter to allow you to access its volume by script. Here's how you'll do it:
- Select the AudioMixer under Mixers. Then select the Master Group in the Groups list on the left.
- Click the Plus button to add a child group to the list.
- Rename it Torch.
- Creating the child group should select it, which exposes some settings in the Inspector.
- In the Attenuation section, right-click on Volume and select Expose 'Volume (of Torch)' to script.
- The exposed parameters should appear in a drop-down on the top-right of the Audio Mixer window. Click on the drop-down to find your new exposed parameter, which is intuitively named MyExposedParam. Click on it to rename it to something even more intuitive, such as TorchVolume.
As you've done previously, navigate to the SettingsPanel in the Hierarchy under Canvas ► SettingsMenu ► SettingsPanel to activate a new control.
Find and select TorchVolumeSettingComponent and enable it in the Inspector.
Now, open the SettingsManager.cs script and add the following code to the empty SetTorchLevel
method.
mixer.SetFloat("TorchVolume", Mathf.Log10(sliderValue) * 20);
SaveSettings("TorchVolume", sliderValue);
The volume in the mixer is logarithmic, not linear. Therefore, Mathf.Log10
will ensure a smooth increase or decrease of the volume when the player adjusts the slider.
The final step is to tell the torch to use the new mixer you created. Find the two ColumnTorch objects in the Hierarchy. The search bar will help with this.
Next, select both objects and find the AudioSource in the Inspector. One of the parameters, Output, routes the sound through the selected audio mixer ground. Click the selection circle and select Torch in the presented list.
Click Play in Unity to enter play mode. You should now be able to adjust the volume of the FX independently to the sound of the torch's crackling fire... ahh!