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.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 5 of 6 of this article. Click here to view the first page.

Attaching the Descriptions to the Audio Sources

Return to Unity and type AudioSource into the search bar at the top of Hierarchy.

Finding audio sources in the 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.

applying overrides to prefabs

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.

Puzzley Dungeon with its new audio cues

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!

The importance of directional cues in games

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:

Diagram showing how to calculate distance between a noise and the player

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:

  1. By subtracting the position of the origin of the sound from the player's position, you get a vector representation of the heading.
  2. 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.
  3. 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.
  4. 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!

Cartoon of a confused-looking creature

Press Play in Unity and do some noisy stuff to see the results of your hard work!

Puzzley Dungeon with directional audio cues enabled

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.

The negative effects of too-loud sounds

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:

  1. Select the AudioMixer under Mixers. Then select the Master Group in the Groups list on the left.
  2. Click the Plus button to add a child group to the list.
  3. Rename it Torch.
  4. Creating the child group should select it, which exposes some settings in the Inspector.
  5. In the Attenuation section, right-click on Volume and select Expose 'Volume (of Torch)' to script.
  6. 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.

Setting up a new mixer group for your torch volume

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.

Enabling TorchVolumeSettingComponent

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.

Selecting the ColumnTorch objects and setting the Torch output

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!

Mark Placzek

Contributors

Mark Placzek

Author

Ben MacKinnon

Tech Editor

Aleksandra Kizevska

Illustrator

Sean Duffy

Final Pass Editor

Over 300 content creators. Join our team.