Voice Over

This sample plays a recorded voice clip with each line. It’s a short conversation between Tom, who’s floating in space with no idea where he is, and Anne, a voice who’s trying to help. The lines are shown at the bottom of the screen while the clips play. Tom’s text is yellow and Anne’s is cyan, and Tom’s mouth moves with his voice.

The text is translated into German, Simplified Chinese, Brazilian Portuguese and Spanish, and the lines are recorded in English, German, Chinese and Brazilian Portuguese.

The sample has two scenes that are the same apart from where the text and clips come from. VoiceOver-BuiltInLocalization uses Yarn Spinner’s own localisation, and VoiceOver-UnityLocalization uses Unity’s Localization package.

PLACEHOLDER — Screenshot needed
The Voice Over sample: Tom floating in space in his helmet, with his first line, ‘Uh.. hello?’, in yellow in the dialogue box at the bottom of the screen.

Running it

In the Project window, open the Voiceover and Localisation sample’s folder, open the VoiceOver-BuiltInLocalization scene, and press Play. The sample has sound.

  • The conversation starts by itself, and each line moves on by itself half a second after its clip finishes.
  • Press Space, or click the continue button, to skip ahead. If you skip before the clip has finished, it fades out quickly and the next line starts.
  • Click an option to choose it.

The VoiceOver-UnityLocalization scene needs Unity’s Localization package. If it isn’t installed, select the scene’s Dependency Installer GameObject, and click Install Unity Localization in the Inspector.

How it works

The Dialogue Runner has six Presenters, and gives every line to all of them:

VoiceOver-BuiltInLocalization
Scene
Main Camera CameraAudio ListenerUniversal Additional Camera Data
Directional Light LightUniversal Additional Light Data
Tom Character ControllerSimple CharacterCharacter AppearanceMouth ViewDialogue Interactable
Dialogue System Dialogue RunnerIn Memory Variable StorageBuiltin Localised Line Provider
Canvas CanvasCanvas ScalerGraphic Raycaster
Line Presenter Content Size FitterVertical Layout GroupCanvas GroupLine Presenter
Options Presenter Vertical Layout GroupContent Size FitterCanvas GroupOptions Presenter
Fade Out ImageFade Out Effect View
Markup Processors Palette Marker ProcessorStyle Marker Processor
Line Advancer Line Advancer
EventSystem Event SystemEnsure Input Module AvailableStandalone Input Module
Voice Over View Voice Over PresenterAudio Source
Lip Sync View Texture Lip Sync View
Character Color View Character Name Color View
The VoiceOver-BuiltInLocalization scene. Everything is in the Scene prefab.
  • The Line Presenter shows the line’s text.
  • The Options Presenter shows the choice, with the line before it above the options.
  • The Line Advancer lets the player skip ahead.
  • The Voice Over Presenter plays the line’s clip through the Audio Source next to it.
  • Lip Sync View, from the samples’ shared TextureLipSyncView.cs, moves Tom’s mouth in time with the clip.
  • Character Color View, from the sample’s CharacterNameColorView.cs, colours the text by who’s speaking.

The Dialogue Runner moves on once every Presenter has returned. The Voice Over Presenter has End Line When Voiceover Complete turned on, so when a clip finishes, it ends the line, and the dialogue moves on. Wait Time Before Line Start is 0.25 and Wait Time After Line Complete is 0.5, which leaves a short gap before and after each clip.

The Dialogue Runner’s Start Automatically and Run Selected Option As Line are on. When the player picks an option, like “Who are you?”, it runs as a line, so Tom says it aloud.

Colouring the text

CharacterNameColorView is a small Presenter of its own. It sets the colour of some text, then returns immediately:

public override YarnTask RunLineAsync(LocalizedLine line, LineCancellationToken token)
{
    Color color;

    if (string.IsNullOrEmpty(line.CharacterName) || !characterColors.TryGetValue(line.CharacterName, out color))
    {
        color = defaultColor;
    }

    foreach (var text in texts)
    {
        text.color = color;
    }

    return YarnTask.CompletedTask;
}
Lines 5–8 Look up the speaker in Character Colors, which has cyan for Anne and yellow for Tom. Anyone else gets Default Color, white.
Lines 10–13 Texts holds the Line Presenter’s Text and the Options Presenter’s Last Line.
RunLineAsync() in CharacterNameColorView.cs.

Line IDs and assets

Every line in VoiceOver.yarn has a #line: tag, and each line’s assets are named after its line ID:

<<set_fade_color 1>>

<<wait 2>>

<<fade_up 2>>

<<wait 1>>

<<play_animation Tom Gesture LookAround wait>>

Tom: Uh.. hello? #line:tutorial-tom-01
<<turn Tom 0.5 0.5>>
<<tilt_forward Tom -0.5 0.5>>
Tom: Is anyone there? #line:tutorial-tom-02
Lines 1–5 Commands from FadeOutEffectView.cs, which fade the Fade Out Image. The screen goes black, then fades in over two seconds.
Line 9 Commands like <<play_animation>>, <<turn>> and <<tilt_forward>> come from the samples’ shared character scripts, and act on the GameObject called Tom.
Line 11 This line’s assets are named tutorial-tom-01: the line ID without the line: part.
Part of VoiceOver.yarn.

Each language has a LipSync folder and an Audio folder. The clip for the first line in English is Dialogue/assets-en/Audio-en/tutorial-tom-01.wav, and its lip sync data is Dialogue/assets-en/LipSync-en/tutorial-tom-01.lipsync.

The line’s asset is the lip sync file, not the clip. The samples’ LipSyncDataImporter imports each .lipsync file as a LipSyncedVoiceLine, which holds the mouth shapes and their timings, and a reference to the matching audio clip. LipSyncedVoiceLine implements IAssetProvider, so other Presenters can ask it for the kind of asset they need:

  • The Voice Over Presenter checks whether the line’s asset is an AudioClip. It isn’t, so it asks the IAssetProvider for one, and plays the clip it gets back.
  • TextureLipSyncView asks the IAssetProvider for the LipSyncedVoiceLine itself, finds the Mouth View for the speaking character, and changes the mouth’s texture to match each mouth shape as the clip plays.

See Line and Asset Providers.

Built-in localisation

In VoiceOver-BuiltInLocalization, the Dialogue Runner’s Line Provider is a Builtin Localised Line Provider, on the Dialogue System GameObject.

The Yarn Project, VoiceOver-BuiltInLocalization, has a localisation for each language. English is the base language, and its text comes from the Yarn Script. Each other language has a strings file, such as VoiceOver - de.csv, with a row for each line keyed by its line ID. Each language also has an assets folder:

LanguageStringsAssets
enThe Yarn Scriptassets-en/LipSync-en
deVoiceOver - de.csvassets-de/LipSync-de
zh-HansVoiceOver - zh_Hans.csvassets-zh/LipSync-zh
pt-BRVoiceOver - pt_BR.csvassets-pt-BR/LipSync-pt-BR
esVoiceOver - es.csvNone. There are no Spanish recordings.
The localisations in the VoiceOver-BuiltInLocalization Yarn Project.
language,id,text,file,node,lineNumber,lock,comment
The first row of each strings file.

The Builtin Localised Line Provider has two languages: Text Locale Code picks the strings, and Asset Locale Code picks the assets folder. Both are set to English in the scene. Use Fallback is on, with Fallback Locale Code set to English. See Localising Your Game.

Unity localisation

In VoiceOver-UnityLocalization, the Dialogue Runner’s Line Provider is a Unity Localised Line Provider instead, and the Yarn Project is VoiceOver-UnityLocalization.

The text and the assets come from Unity Localization tables in the sample’s Localization Tables folder: a string table collection called VoiceoverSample, and an asset table collection called VoiceoverSampleAssets. The line provider’s Strings Table and Asset Table point at them. Each table has an entry for each line ID, in each locale. The language follows Unity Localization’s selected locale.

Things to try

  • In VoiceOver-BuiltInLocalization, select Dialogue System and set both Text Locale Code and Asset Locale Code on the Builtin Localised Line Provider to German. Play the scene, and both the text and the voices are in German.
  • Set Text Locale Code to Spanish and leave Asset Locale Code on English. The text is in Spanish, and the English clips play.
  • Select Voice Over View and turn off End Line When Voiceover Complete. Each line now stays on screen after its clip finishes, until you press Space.
  • On Voice Over View, set Fade Out Time On Line Finish to 1, then skip part way through a line. The clip fades out over a second instead of stopping almost at once.
Next step Yarn Spinner+ and Add-Ons Ready-made Presenters and integrations with popular third-party assets.