Commands work very similar to Yarn functions, but use a different syntax and are able to modify the game world. As a consequence of their similarity, registering custom commands is very similar to registering custom functions.
Just as with Yarn functions, registration happens when creating a DialogueRunner
. Let's again modify the example from the Quick Start:
We call the command like this:
You will have seen one crucial difference to Yarn functions immediately. The parameters are not passed in directly to the Rust function, but are wrapped in an In
struct. This is because Rust functions that are registered as commands are always valid Bevy systems. The In
parameter just tells the function which values come from the Yarn file, but we can additionally query the Bevy world as we want:
which we call like this:
The Rust functions serving as commands always require an In
parameter. If your Yarn command doesn't accept any parameters, specify the first parameter in Rust like this: fn my_command(_: In<()>, ...)
In contrast to functions, commands cannot have any Yarn facing return types. The Rust functions however can use a return value to indicate that Yarn Spinner should wait a while before continuing the dialogue. This is useful for times when you want to change something in the world before the dialogue goes on, e.g. move the camera to another speaker. To do this, simply return a type implementing TaskFinishedIndicator
, for example Arc<AtomicBool>
. This way, you can keep a copy of the Arc
and change its content to true
whenever your transition is over.
For a practical example, check out how we implement a fade out at the end of the demo.