I’m working on a casual project to develop an old-school style adventure game. I’m having trouble developing a C# script that will create GUI boxes with text for a dialogue. I can create the GUI boxes fine. I also want the boxes to disappear and have the next one appear at the press of a key, so that the dialogue progresses. I thought I found a way to do this but having written a script for three boxes, what’s actually happening is that just the third box opens. Here’s the script I was trying to use:
using UnityEngine;
using System.Collections;
public class oldmandialogue1 : MonoBehaviour
{
public GUISkin WindowStyle;
public bool ShowWindow01 = true;
public bool ShowWindow02 = false;
public bool ShowWindow03 = false;
void OnGUI()
{
if (ShowWindow01)
{
GUI.skin = WindowStyle;
GUI.Box(new Rect(435,100,500,50), "Are you listening?
Press Enter…");
}
if(Input.GetKeyDown(“return”))
{
ShowWindow01 = false;
ShowWindow02 = true;
}
if (ShowWindow02)
{
GUI.skin = WindowStyle;
GUI.Box(new Rect(435,100,500,50), “It’s time I told you the story of our land.
Press Enter…”);
}
if(Input.GetKeyDown(“return”))
{
ShowWindow02 = false;
ShowWindow03 = true;
}
GUI.skin = WindowStyle;
GUI.Box(new Rect(435,100,500,50), “Long ago, before man was born into this world, there was chaos.
Press Enter…”);
}
}
First off, because of how OnGUI works, you can’t use Input methods there. The right way to get key presses there is to use Event.current.
(Anyways, the third dialogue gets shown right away because on the first key press the script changes ShowWindow02 to true and enters the next if-block right away. Next dialogue gets drawn, and the GetKeyDown function evaluates true again, as it’s all happening during the same pass. Third dialogue then overwrites the second one.)
This exact problem could be corrected using an else-if structure, or having the key checking separately in the beginning of the function.
But, on a more important note, your code is kinda hard to reuse, modify or expand because of its structure. Consider having the following as class members:
An array of strings with the dialogue:
string[] dialogue = {"Are you listening?",
"It's time I told you a story...",
"Long ago, before man was born..."};
An index to point to current dialogue:
int index = 0;
The dimensions of the dialogue box separately:
Rect dialogueRect = new Rect(435,100,500,50);
Then, have a GetKeyDown increment the index in the Update method (this way it works correctly):
void Update() {
if (Input.GetKeyDown("return")) {
index++;
}
}
Draw the dialogue:
void OnGUI() {
if (index < dialogue.Length) {
GUI.Box(dialogueRect, dialogue[index]);
} else {
// do some stuff to end dialogue
}
}
And voila! Easy to modify and copy to other situations! =)
EDIT:
If you have many characters with many lines of dialogue and have all the text in the classes (as in my example), you will run into problems sooner or later with maintaining it all. The most robust and best solution would be having all the dialogue in some resource files that the scripts access, and create some editor functionality that would allow easy addition of dialogue. But if this is a casual project, as you said, that may be a bit overkill.
Thank you very much. I noticed there are just a couple of typos in the script you gave me that resulted in a couple of errors but I’ve fixed it and now it works perfectly. I’ll put the working script here so anyone who wants to can use it as a template.
using UnityEngine;
using System.Collections;
public class oldmandialogue1 : MonoBehaviour
{
public string[] dialogue = {"Are you listening?
Press Enter…",
“It’s time I told you the story of our land.
Press Enter…”,
“Long ago, before man was born into this world, there was chaos.
Press Enter…”};
int index = 0;
Rect dialogueRect = new Rect(435,100,500,50);