Quickstart of a VR storytelling game using Unity Dialogue System and XR Interaction Toolkit

2022-08-14

In the past three months, I got the chance to work on a VR interactive storytelling game called Deja Vu, which is about a Robot trying to conduct a soul experiment to find his reincarnated true love after going through a series of stories in memorable scenes like the library, beach and their old home, etc, and the player, you, needs to make choices to unlock different stories, endings and even an unexpected secret…

When I embarked on this project, we had envisioned the in-game choices to be totally based on natural human interactions, mainly through grabbing and teleportations. So in the first place, we needed to set up two core systems, a VR interaction input system and a dialogue system, and handle the event-based inter-communication across them. Given that it was only my first time using the Unity Dialogue System plugin and the second time creating a VR experience within Unity(with XR interaction toolkit), it took some time for me to come up with a strategy to link the two systems and flesh out the storyline. Thus, I would like to share this quick tutorial to help people who are also interested in making their own VR storytelling game for the very first time to get onboard much easier. 

First of all, you need to have both the XR interaction toolkit(2.0) and the Dialogue System properly set up in your scene. I highly recommend following this tutorial for the former and the official quickstart documentation for the latter. It’s okay if you are not sure, as we will go through most settings as we create the demo scene.

After successfully installing all the packages and setting up the dialogue system, you need to make sure that you have a DialogueManager object and at least one dialogue actor in the scene, and here in the demo we have two actors, Robot as the NPC and the XR Origin as the Player. 

The simple demo is about picking a ball where each ball corresponds to different dialogue branches from the NPC(i.e. The Robot). 

1. Create a dialogue database

In the Inspector window of DialogueManager, we will need to set the initial database to the dialogue database we are going to use over the entire story. If you already followed the QuickStart tutorial from PixelCrushers to create one, you can directly specify to that. Otherwise, create a Dialogues directory under Project window and then create a new database by: Right click -> Create -> Pixel Crushers -> Diaglogue System -> Dialogue Database. Name it Demo_Dialogues.

There are a few things we need to fulfill the choice-based storylines.

  1. Actors: Player(default), NPC
  2. Quests: Pick Ball
  3. Variables: Alert(default/optional), ballChosen
  4. Conversations: Opening

The Actors entity contains the two dialogue actors we need in the story, which is self-explanatory. The Quests entity is the key to keep track of the state of a task or action. It has 7 states by default, and here we will mainly use the unassigned and success states to keep track of whether the Pick Ball action was conducted or not. In relation to this, the Variables entity has a ballChosen record corresponding to which ball the player picks, which will be used for conditional checks to branch out different storylines.

Here is how the conversation tree should look like for the Opening dialogue.

conversation_tree.png

The first level of the tree is based on the current quest state, while the second level is based on the ballChosen variable’s state. Both of the conditional logics were injected with Lua code and can be viewed in the Inspector window. 

conversation_lv1.png
Left Entry Node on the First Level

conversation_lv2.png
Left-most Entry Node on the Second Level

2. Configure Dialogue Actors

Add a Dialogue Actor component to both of the XR Origin and Robot objects in the scene, and assign the Actor attribute to Player and NPC respectively. You can also customize the Dialogue UI to always override the default Standard Dialogue UI set under the DialogueManager. It is recommended to do it for all actors in the scene that are dedicated over the entire game.

Dialogue_Actor.png

In order to start a conversation based on a trigger, you would need to attach a Dialogue System Trigger component for the NPC dialogue actor to listen on certain events(e.g. On Use), and then execute callback actions like starting a conversation. In this example, we are using a Talk UI button to activate the Opening conversation.

Canvas_NPC_Trigger.png

Talk_Button.png

Dialogue_Trigger.png

3. Configure three Ball Objects

Now that we have the Dialogue System and actors set up, the next big step is to configure the interactable objects, the balls, to perform as event dispatchers(i.e. On Grab event) as well as handlers(i.e. update quest and variable states and resume a conversation).

There are two ways to deal with this type of scenario, one with C# scripts and the other purely with the editor’s inspector. The scripting idea would be to update quest and variable states with C# code on grab start(On First/Last Select) and resume the conversation directly. If you are interested in implementing that approach, please use their scripting API docs for reference.

Here, we are only going to demo the more straightforward and simpler approach without any scripting. And the only other helper you need is a Dialogue System Trigger instead of a script. All you need is as followed and please use the examples as a reference.

1. XR Grab Interactable (Event dispatcher)

XR_Interactable.png

2. Dialogue System Trigger (Event handler)

Ball_Trigger.png

Alright cool, that should be it! Now it’s time to try! 

Quite easy right? Thanks a lot for your time and efforts to make it to this step and feel free to let me know if you have any questions! If you are interested in Deja Vu, please feel free to check it out as well! Enjoy! :P

Built with Next.js, Tailwind and Vercel