Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411275 Posts in 69323 Topics- by 58380 Members - Latest Member: bob1029

March 28, 2024, 08:57:00 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Dialog System in Unity
Pages: [1]
Print
Author Topic: Dialog System in Unity  (Read 3792 times)
Cheetah
Level 0
**



View Profile
« on: April 15, 2015, 03:44:37 AM »

I have been slowly teaching myself Unity and C# programming for the past few months. I am currently trying to get a simple and efficient dialog system going and am looking for some advice on best practices.

My current plan is to load a text file into a GUI element. I would then use a StreamReader to start writing down the text letter by letter, RPG style. This text file would also contain all the triggers for any functions by having the StreamReader run anything found within "<>". Functions could change the read speed, do sound effects, wait for an input, or load the next text file.

Questions:
1) Is there a more efficient, but not significantly more complex, way of doing this?
2) Any suggestions on how to have the StreamReader run functions found within "<>"?

Thanks, I hope to slowly post progress as I progress.
« Last Edit: April 15, 2015, 04:31:08 AM by Cheetah » Logged
Layl
Level 3
***

professional jerkface


View Profile WWW
« Reply #1 on: April 15, 2015, 05:15:56 AM »

First thing I would advice is not to worry about efficiency. This isn't a performance critical section, and it's generally better to optimize afterwards anyways.
Logged
Richard Kain
Level 10
*****



View Profile WWW
« Reply #2 on: April 15, 2015, 11:46:43 AM »

I'm not sure that loading in text files is the best way to go about it. It is a way to disconnect your dialog system from Unity's editor environment. But why would you ever want to do that? Unity has everything necessary in the editor itself for entering whatever text you please. You could easily devise a dialog system where you can write your dialog right in Unity.
Logged
Cheetah
Level 0
**



View Profile
« Reply #3 on: April 16, 2015, 06:30:10 AM »

Your right Kain. I wanted to do the streamreader because I didn't want a giant state machine moving between various lines of text in one giant script. But instead of dividing things up into different text files, I can just put it into different scripts with an overarching script which they pull functions from. Am I interpreting what you are saying correctly?
Logged
InfiniteStateMachine
Level 10
*****



View Profile
« Reply #4 on: April 16, 2015, 08:03:55 AM »

I'm not sure that loading in text files is the best way to go about it. It is a way to disconnect your dialog system from Unity's editor environment. But why would you ever want to do that? Unity has everything necessary in the editor itself for entering whatever text you please. You could easily devise a dialog system where you can write your dialog right in Unity.

I once designed a dialog system creator in WPF which exported to xml which I loaded in Unity because the unity gui tools are really anemic in comparison to wpf. Overall it saved me time. Plus the data is now engine agnostic and reusable for other non-unity projects.

Logged

Richard Kain
Level 10
*****



View Profile WWW
« Reply #5 on: April 16, 2015, 11:04:09 AM »

But instead of dividing things up into different text files, I can just put it into different scripts with an overarching script which they pull functions from. Am I interpreting what you are saying correctly?

In a manner of speaking, yes. Public script variables in Unity are serialized. That is to say, their values, however you alter them, are saved as part of the Unity scene that the objects are contained in. You could create a script with a public string variable, or even a list of string variables, and use that for storing dialog text. (for an individual character) Another script that you place on a GUI text box could then retrieve the values from the first script in order to display conversation options and responses.

And all of this could be set up to use the Unity interface, so that you could just type your writing right in Unity itself, without relying on an external text editor in any way. This would make it faster and easier to change up the text on-the-fly.
Logged
gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #6 on: April 17, 2015, 04:34:09 PM »

Be careful with string in unity they tend to kick the garbage collector, so I heard
Logged

Armageddon
Level 6
*



View Profile
« Reply #7 on: April 17, 2015, 07:01:02 PM »

I thought about making a thread on this topic. I'm having such a difficult time with making a dialogue system. I tried some of the ones on the Unity asset store and they're just so bloated or they don't promote extendability or they don't support translation. I wish I could just do it like Valve. Have a .txt with keys and then the text on the next line, then the file name just ends with _<languagename> and you load it that way. I just have zero idea how to parse things with C#. Then once you parse it how do you display it and then time it to audio, or just on next click display the next dialogue.
Also how do you deal with a lot of multiple choices in dialogue? I'd maybe wrap each whole dialogue with a dialogue number tag or something and then have a visualized editor like ChatMapper export it out so while writing you don't have to keep up with each choice moving down the text file. Could get messy.

I'm not sure that loading in text files is the best way to go about it. It is a way to disconnect your dialog system from Unity's editor environment. But why would you ever want to do that? Unity has everything necessary in the editor itself for entering whatever text you please. You could easily devise a dialog system where you can write your dialog right in Unity.
I'd prefer external file reading for ease of translation. Hard coding any text would be very bad.
Logged

nickgravelyn
Guest
« Reply #8 on: April 17, 2015, 07:54:02 PM »

Here's some tips based on my experience with text and dialog.

Localization

Personally I like to use Google Docs and spreadsheets for the text. The first column is the text key (i.e. what it's called in code) and then I have a column for each language. The headers give the language names for me. I like this approach because it's far easier to see which languages are missing what text rather than having to compare multiple separate files.

Google Docs can nicely export CSV files which are fairly easy to parse but you can also find lots of open source solutions as well: https://github.com/search?l=C%23&q=csv&ref=searchresults&type=Repositories&utf8=✓

I have a build step for our game that reads in our CSV file and generates separate language binary files we read in at runtime. This makes it easier to update individual languages post-ship as well as not requiring that we load all languages all the time (though in our game we have little text so we just load everything to make life easy). Also we generate an enum with all the text keys so that we have some type safety around our string lookups.

That said, in Shipwreck we did use a basic text file which looked something like this:

Code:
string_key_001
    This is a string!

We read each line one at a time. If we saw a line that didn't start with spaces, we knew it was a string key. Otherwise we built up the string given the lines and associated it with the last key we read. This worked, but was also a bit of a pain. I'd recommend CSV instead.

Dialog

We had dialog in Shipwreck, albeit in a fairly basic form. All of our dialog was also a text format that looked something like this:

Code:
== take_care ==
start: true
condition: visited_node give_pickaxe
text: miner_pickaxe_take_care

== no_pickaxe ==
start: true
text: miner_pickaxe_not_available
switch:
    check_marker mayor_permission_pickaxe : yes_pickaxe

== yes_pickaxe ==
start: false
text: miner_pickaxe_mayor_permission
goto: give_pickaxe

== give_pickaxe ==
start: false
add_item: pickaxe
destroy_object: pickaxe
goto: lantern

== lantern ==
start: false
text: miner_pickaxe_lantern
goto: take_care

Each of the lines with the == wrapped around is the name of a "node". Each node then has a set of properties. Start is whether or not the dialog can start there. Condition let us set up some basic scripting conditions that could check variables. We also had a text property for the string key to lookup. Switch was like a set of conditions that are checked in order, which let us jump around a bit. Then we had things like goto to jump between nodes, add_item to give the player stuff, destroy_object to remove things from the world, and others.

Parsing this was also pretty straightforward since we could look for the == starting a line to know we had a new node and each property was its own line so we just checked the start of each line for our keywords. Here's a chunk from our parser that shows how we handled the text: http://pastebin.com/AkVaSMFj. As you can see it's not terribly complicated or clever. But we also ran this code at build time to generate more optimized binary files to read at runtime, so our text parsing didn't have to think about performance or garbage collection, really.

General Parsing

General tips for text parsing in C#:

- StreamReader is a great class for reading in text from files.
- String has some great methods you can use: IndexOf, StartsWith, and Split.
- Focus on making it work rather than being super complicated. You don't need every feature for every game; you only need the features for your game.

Hope that helps!  Coffee
« Last Edit: April 17, 2015, 08:53:39 PM by nickgravelyn » Logged
Richard Kain
Level 10
*****



View Profile WWW
« Reply #9 on: April 20, 2015, 10:00:02 AM »

I'd prefer external file reading for ease of translation. Hard coding any text would be very bad.

I'm not talking about hard-coding text into source files. I'm talking about defining string variables in source files, and then adding the actual text in the Unity Editor. (most likely via the inspector panel) And since the text would be defined by a string variable, it shouldn't be that hard to integrate different versions for different languages.

I'm just encouraging people to use the flexibility of Unity's editing environment over trying to come up with some bizarre import solution. I know first-hand how frustrating it can be to parse lengthy and complicated text files that store data. And at the end of the day, all you really want to do is translate those text files into variables anyway. Just cut out the middle man and do all the work in Unity itself.
Logged
nickgravelyn
Guest
« Reply #10 on: April 20, 2015, 01:07:32 PM »

I'd prefer external file reading for ease of translation. Hard coding any text would be very bad.

I'm not talking about hard-coding text into source files. I'm talking about defining string variables in source files, and then adding the actual text in the Unity Editor. (most likely via the inspector panel) And since the text would be defined by a string variable, it shouldn't be that hard to integrate different versions for different languages.

I'm just encouraging people to use the flexibility of Unity's editing environment over trying to come up with some bizarre import solution. I know first-hand how frustrating it can be to parse lengthy and complicated text files that store data. And at the end of the day, all you really want to do is translate those text files into variables anyway. Just cut out the middle man and do all the work in Unity itself.
While the original poster didn't ask about localized text, it got mentioned and discussed a little bit so I wanted to point out that your strategy is not ideal for localization. Most indies don't/shouldn't do their own localization. When you hire a localization firm you can't expect them to have Unity and you can't expect them to go into Unity to update those strings (and to be fair you probably don't want them in your Unity project). So you're left copying out all your text, putting it in a file, sending that to the localization firm, getting the new text, and copying it back in.

Now if your game was just reading in an external file already, you'd just hand that file off to the firm, let them work, and put it back into your project. Your game now has localized text at very minimal work to you. This is important because you may have to go back and forth for localization as you find bugs or find that strings in some languages don't quite fit and you need a different phrasing to make it work.

Unity's editor is a great help for lots of things, but for localized text you will hurt yourself to not have a separate file. You can use all sorts of cool Unity editor tricks to parse the file, put it into a custom data structure, generate some code, or whatever, but if you plan to localize your text you'll want your source text outside of Unity.
Logged
archgame
Level 2
**


I program architecture and build video games


View Profile WWW
« Reply #11 on: February 21, 2018, 05:40:29 PM »

This thread has been helpful in conceptualizing my own dialogue system.

I had a architecture question i'm hoping a veteran can answer:

When creating the dialogue text files, do people generally favor having a dialogue text file on each interactive element or do people prefer a single text file with everything in it. I can see pros and cons with each and was hoping others would have input/suggestions/alternatives. I could see the localization method described above used in a similar manner for different states in the game (thinking adult/young link from LoZ:OoT, or day 1/2/3 for LoZ:MM).

I know the original post is rather old, so maybe there is an asset or open source project that has been working well for people?
Logged

TonyLi
Level 0
***


View Profile
« Reply #12 on: February 22, 2018, 08:53:22 AM »

A single file is easier for localization and spelling/grammar checks, although you could write a tool that gathers up loose files and puts them into a big CSV file that you could send off to translators. Either way, you need a good way to get those translations back into your project.

Inkle has an open source Unity integration for Ink. DA Terre wrote an open source Twine importer for Unity. Talk-It a simple, open source node-based dialogue editor that writes JSON, which you can read with JsonUtility. You can get a cheap copy of Neverwinter Nights on GOG and use Bioware's editor to make XML files that you can read into Unity. (Personal plug: there's also the Dialogue System for Unity, which imports all these formats as well as Chat Mapper and articy:draft.)
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic