Creating Custom Dialogue Views
Learn how to create Dialogue Views that are designed for the specific needs of your game.
While the Line View and Options List View are useful for lots of situations, your game might need to display lines and options in specific ways. In these situations, you can write your own custom Dialogue View, and handle the presentation of lines and options in ways that are entirely in your control.
To create a Dialogue View, you subclass the
DialogueViewBaseclass, and add it as a component to a game object in your scene. You can then add this game object to the Dialogue Views list on your scene's Dialogue Runner.
On its own, an empty subclass of
DialogueViewBasewill not do anything useful. To make it display lines and options, you'll need to implement certain methods.
Yarn Spinner scripts deal in three different kinds of content: lines, options, and commands. Of these, only the first two - lines and options - are content that need to be shown directly to the player.
When the Dialogue Runner encounters lines or options, it first needs to determine the specific content the user needs to see. Once it has this, it sends the content to each of its Dialogue Views.
Lines and options are represented in compiled Yarn scripts as line IDs. A line ID is a unique identifier for the text of a line or an option. When Yarn Spinner needs to show a line or option to the user, it asks its Line Provider to provide it with a
LocalizedLineobject. This object contains the text of the line or option, in the user's current locale.
LocalizedLinehas been created, the Dialogue Runner has everything that it needs to show content to the user. The next steps vary depending on whether it's showing a line or an option.
When Yarn Spinner encounters a line of dialogue, it calls the RunLine method on each Dialogue View. This method takes two parameters: the first is the
LocalizedLinethat the Line Provider created, and the second is a delegate that the Dialogue View should call when the line has finished being presented.
In Dialogue Views, a line is presented when the user has received the entire line, and is ready to move on to the next line. The practical outcome of what this means depends on the Dialogue View itself; for example, a Dialogue View that plays voice-over audio might finish presenting when all of the audio has played, while a Dialogue View that gradually reveals the text of a line might finish presenting when all of the text is visible.
The Dialogue Runner will wait until all Dialogue Views report that they've finished presenting the line. Once this happens, it moves on to the next part of the dialogue.
At any point during a line's presentation, a Dialogue View can interrupt the line. It does this by calling the requestInterrupt method, which is a delegate that's set by its controlling Dialogue Runner. When this method is called, all Dialogue Views that have not yet finished their presentation receive a call to their InterruptLine method.
InterruptLineis very similar to
RunLine, in that it receives a line to present and a completion handler to call when the presentation is complete. However, while
RunLineis expected to present the line at its own pace,
InterruptLineis a signal to finish the presentation as quickly as possible.
As before, the actual details of this depend on the Line View. To continue the examples from before, a Dialogue View that plays voice-over audio might fade out the audio over a short period of time, or even cut off playback immediately; a Dialogue View that's gradually revealing text might reveal the remaining text all at once, or rapidly reveal the remaining text.
Any Dialogue View may request that a line be interrupted. If multiple Dialogue Views request it, only the first request does anything.
When the last Dialogue View reports that its presentation is complete, either because
RunLinefinished its presentation, or because
InterruptLinewas called and it quickly finished its presentation, it needs to tell the dialogue views to get rid of the line, and potentially prepare for more content.
The Dialogue Runner does this by calling
DismissLineon all Dialogue Views. As with
DismissLinereceives a completion handler to call when it has finished dismissing the line.
As before, the details of how a line is dismissed vary with what the Dialogue View actually does. A Dialogue View that plays voice-over audio may not need to do anything to dismiss a line, because the playback has already finished; a Dialogue View that shows line text on screen might need to hide the text, possibly with an animation.
When the last Dialogue View reports that it has finished dismissing its line, the Dialogue Runner continues running the script.
Options are slightly different to lines, in that they rely on receiving some kind of user input before the dialogue can continue: the Dialogue Runner needs to know which option was selected.
When this method is called, the Dialogue View uses the information contained within the
DialogueOptionobjects to present the choices to the player, and then awaits user input. Once it knows which option was selected, it calls the completion handler, passing in the DialogueOptionID of the selected option.
Dialogue Runners can use multiple Dialogue Views. This is actually recommended, because it makes it easier to separate the code for handling lines, from that of running options.
All of the methods in
DialogueViewBaseare optional. If you don't implement a method, then the default implementation of that method is used instead; the default implementation either does nothing, or as close to nothing as it can while still working. For example, the default implementation of
RunLineimmediately signals that presentation is complete.
- To create a Dialogue View that shows lines, implement
- To create a Dialogue View that shows options, implement
- To create a Dialogue View that supports both, implement all four.
During gameplay, your user may wish signal that they want to advance the dialogue: that is, they want to proceed to the next line, or they want the current line to be presented more quickly.
In most cases, it is generally appropriate for implementations of
UserRequestedViewAdvancementto call the
requestInterruptmethod, which tells the Dialogue Runner to interrupt the line (across all views) and to proceed to the next one. However, a Dialogue View may choose to perform other actions that deliver the line more quickly.
UserRequestedViewAdvancementcan be called by any part of your code. Additionally, you may wish to use
DialogueAdvanceInput, which is a class that listens for user input, and when it receives it, calls
UserRequestedViewAdvancementon a view you specify.