0:00 Useless Intro 0:49 Dialogue Base Class 1:30 Visual Example of how it works 2:29 Dialogue Line Class 3:36 First Working Version 4:09 Adding Custom Color and Font for each dialogue line 5:07 Customizing the speed with which letter appear 5:44 Adding Sounds 8:20 Sans Voice 8:50 Adding Graphics 9:50 Character Portraits 11:20 Making Multiple Lines appear in sequence 13:29 Adding Time Delays before changing lines 14:43 Changing Lines with mouse clicks 15:06 Turning off dialogue when done 15:30 Final version showcase 16:05 Want me to extend this and add more options? Hope this helps people navigate this long-ass video.
@@microwave1852 Alt-Enter while keeping your selection cursor on the ienumerator word. Check this out for more shortcuts: docs.microsoft.com/en-us/visualstudio/ide/default-keyboard-shortcuts-in-visual-studio?view=vs-2019
This is an EXCELLENT tutorial! Probably the best dialog tutorial I've watched, and I think I've watched almost all of them by now! Great explanations, editing and everything! I would LOVE to see another video on this about branching dialog, etc.
you have no idea how long I've looked for a proper dialogue system that would work for my game!!! I hope that you get popular enough for others to see your wisdom!
Ah, thank you for the kind words! I'll keep putting up content and hopefully people will find it :). BTW episode 2 of this series is being recorded now.
You guys might get an issue at 3:25 where the INPUT text does not register at the Dialogue1. Just don't use TextMeshPro and use the text on the legacy options of the UI. For some reason, textmeshpro sux so much.
Hi, awesome video! But I seem to have a problem at 13:16. When you play yours, dialogue 1 and dialogue 2 are separate but for me, the dialogues play at the same time. Hopefully you see my comment and help me with this problem. :(
Hey i don't know if you've figured it out, but i had the same problem. And the problem was no putting the DialogueHolder Script to the Dialogue holder object. Yeehaw
Hey, after I add the text color and text font functionality, it does not display when I hit start. The code is perfect, it's exactly what you have. But for whatever reason when I add these features, it does not display the text when I hit the start button.
@@holdenthompson1449 It happened to more people, the problem is that the color parameter has 0 opacity, so it's transparent. The text is there you just can't see it. Make sure to change the opacity to 100%.
Hello, I'm at 05:26 and I can't go ahead because the script has an error saying: Assets \ scripts \ Dialogo 2 \ DialogueLine.cs (21,28): error CS0103: The name 'WriteText' does not exist in the current context. I really need your help, and I'm on Unity 2019.2.0f1
check the DialogueBaseClass and see if you have the WriteText Ienumerator there. Check the name and make sure it's marked as protected, not private. Also check if DialogueLine class is inheriting from DialogueBaseClass not MonoBehaviour
At 12:48 dialogueSequence returns an error saying that it can't convert system.ienumerator to string. Do you know what could be the problem? Otherwise this video has been really useful :)
@@PandemoniumGameDev Yeah my colors are correct and the text is just not appearing. When I'm selected on the "Text" icon I can still see the script loading each letter one by one, but it doesn't appear in the actual game.
Hi, amazing tutorial. Just wanted to know, how would someone go about changing the background image in tune with the dialogue (like a cutscene). Very similar to the example you gave at the beginning. Thank you
Make a UI image and attach a script on it. Use the same logic we used in this tutorial, you make an array of sprites and every time your player presses Space or click, you change the image.sprite = arrayOfSprites[currentImage]. Let me know if it's clear
Awesome tutorial! Quick question, do you know how you could insert a standalone sound effects between dialogue lines? Like after the player mouse clicks past a line of dialogue an effect like a glass break or something plays before the next text line reads?
Sure, you can do that easily. Notice the line I added after Input.GetMouseButton(0), that's the one you need, you'll also need to replace "_newSound" that I added in there, you'll figure it out, good luck :) public class DialogueBaseClass : MonoBehaviour { public bool finished { get; private set; } protected IEnumerator WriteText(string input, Text textHolder, Color textColor, Font textFont, float delay, AudioClip sound, float delayBetweenLines) { textHolder.color = textColor; textHolder.font = textFont; for (int i = 0; i < input.Length; i++) { textHolder.text += input[i]; SoundManager.instance.PlaySound(sound); yield return new WaitForSeconds(delay); } //yield return new WaitForSeconds(delayBetweenLines); yield return new WaitUntil(() => Input.GetMouseButton(0)); SoundManager.instance.PlaySound(_newSound); //Sound that plays between lines, you need to replace _newSound with an Audioclip finished = true; } }
@@PandemoniumGameDev Awesome that worked! Last question, haha. Do you know if I can add the ability to change text color, font, or facing (bold, italic, underline) of individual strings in the text?
Hey thanks so much for this video! Do you how would implement this using timeline? I want a certain dialogue to start at a certain point of the cutscene and only advance in the cutscene once the continue key is pressed. Basically just like an undertale cutscene
For the first part 0-0:06 seconds is that just a black background, with changing pictures and your dialogue? How did you get the pictures to go in order and fade out/in?
That's not a part of this project, it's a cutscene from Undertale. You could make it tweaking this system though, just need add the image to each dialogue line, and to create the fade effect you can use a CanvasGroup component.
NullReferenceException: Object reference not set to an instance of an object DialogueSystem.DialogBaseClass+d__0.MoveNext () (at Assets/Scripts/DialogBaseClass.cs:13) UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at :0) UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) DialogueSystem.DialogLine:Awake() (at Assets/Scripts/DialogLine.cs:24) Error
@@PandemoniumGameDev Like, if i want a character to move to a specific place after a text or during a text, or event play a specific animation, or change the camera focus, etc.
@@PandemoniumGameDevHi, thanks for your response. But I cant find how to increase opacity. When i remove feature with custom color from code, it starts working. Then I've made a line textHolder.color=Color.black in Awake() section and it did everything right. Could you please say where is opacity option in unity? I've searched the net but didn't found info about it
Abstraction. In this way you can make other scripts that behave differently but still have the ability to show text in way. For example you can make a Cutscene script and make it load the game when it's done, etc. In this case it's not strictly necessary, I agree, but just in case you want to extend it into something more.
Hello ! I have a problem with my coding : when I play the game, the console says that " Field'DialogueLines.textColor' is neever assigned to, and will always have its default value" and it says that for every elements of my game, the DialogueLines.imageHolder, DialogueLine.textFont, ... So I have no idea where does it come from and how I can fix it ? Does anybody have an idea ?
trying this and have canvas, background/dialogue , Text .... added in dialogue line and with input " Sans " as soon as i hit play and it starts ... and then pauses with only "S" in the Text....with error NullReferenceException: Object reference not set to an instance of an object DialogueSystem.DialogueBaseClass+d__4.MoveNext () (at Assets/Dialog System/Scripts/DialogueSystem/DialogueBaseClass.cs:19) UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17) UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) DialogueSystem.DialogueLine:Start() (at Assets/Dialog System/Scripts/DialogueSystem/DialogueLine.cs:38) using Unity version 2018.4.20f1
The exception is on line 19 of DialogueBaseClass.cs so 2 options: 1. Soundmanager instance is missing 2. textHolder is missing. But from what you said that S appears then it stops it seems like you have a problem with the SoundManager, check if you create an instance of it inside Awake() or if the object is present in the scene at all.
Try in DialogueLine get "StartCoroutine..." from Awake() and put it to Update() and add IF statement to it (for example: if you push SPACE, then dialog will start). I have same problem. And it help
It says this when i try to make multiple lines of dialogue Assets\C#\DialogueHolder.cs(22,96): error CS1061: 'DialogueLine' does not contain a definition for 'finished' and no accessible extension method 'finished' accepting a first argument of type 'DialogueLine' could be found (are you missing a using directive or an assembly reference?)
@@enigmatic3280 also check it DialogueLine.cs is inheriting from DialogueBaseClass.cs. Otherwise not sure, you may need to go through all the code again or download the complete project from the link in the description
Hey, first of all, thank you very much for this tutorial, its awesome! Im new to Unity, I'm a media science student from germany and we are programming our first game, so this video really helps! I dont know if you'll read this and if you can help me out, but I do have a question. I get a nullreferenceexception error with this line "SoundManager.instance.PlaySound(sound);" even though the sound plays perfectly. I would be really happy if you could help me out! And thanks again!
The fact that the sound plays perfectly means this exception is happening only once I assume. I think you're trying to start the dialogue in the Awake() method in some script. If that's the case change the Awake() to Start(). The problem is that the SoundManager.instance is being created in Awake, and you're trying to access it in another Awake and it's not ready. Let me know if that's the case.
I have a strange problem. When I manually write text in the text section in the inspector I can see the text appear on screen. But when I press play, I hear the sans sfx but I dont see any text written on the screen.
That's the trick here, you don't write the text into the text section, you write it in your Dialogue Line(Script) component, there's an input field there for it. Hope this helps :)
@@PandemoniumGameDev yeah I did that. I write it in the input section of the script and it shows it typing in my text section on the text gameobject, but I don't see it in game. Just the blank dialog box image.
@@toxiconflict Weird, did you make the script run in Editor Mode? If not follow the video or alternatively just download the entire project, link is in the description. Let me know how it goes :)
@@PandemoniumGameDev I'm having the exact same error. Maybe has it something to do with the DialogueLine being a DialogueBase class, instead of a Monobehaviour one?? How do you run the script in Editor Mode?
@@edywiiii DialogueBaseClass derives from Monobehaviour, therefore the DialogueLine class also derives from it + the DialogueBaseClass. Now it you get an error try checking the log, maybe there's something else causing it. If you still can't figure it out download the complete project(link in description), as you can see in the video it's working, tried to run it now and it works fine.
I am stuck after "Making multiple lines appear in sequence", In Dialogue Holder.cs, I did everything same as yours, but in this coroutine private IEnumerator dialogueSequence() { for (int i = 0; i < transform.childCount; i++) { Deactivate(); transform.GetChild(i).gameObject.SetActive(true); yield return new WaitUntil(() => transform.GetChild(i).GetComponent().finished ); //In this line unity says Null reference exception... its not going to dialogue 2 } } Also, the first letter of my input text is duplicating .... Eg: If i want to show "I am hero :D", it displays "II am hero :D"
Check if your dialogue holder in Unity doesn't have any other stuff except dialogue lines. You should only have dialogue lines there, otherwise it's searching for a dialogue line component and can't find it therefore the null reference.
Instead of using the mouse click how can i replace with mobile button on click()? a small code/ info line please, really liked this tutorial just wanted to know how to use the skip with button usage? Thanks
at 13.15 the two texts appear at the same time, I have already tried to check the scripts and settings and everything is OK. Does anyone have any idea what the problem is?
@@PandemoniumGameDev I can't because it's always trying to convert TMP to Unity default text. I tried "TextMeshPro.SetText" instead of "WriteText" but it doesn't work
@@belebs WriteText is not a preset function, it's one I made, that's why TextMesh doesn't have it built it. Instead what you want to do is this: public class DialogueBaseClass : MonoBehaviour { public bool finished { get; set; } protected IEnumerator WriteText(string input, TextMeshPro textHolder, Color textColor, TMP_FontAsset textFont, float delay, AudioClip sound, float delayBetweenLines) { textHolder.color = textColor; textHolder.font = textFont; for (int i = 0; i < input.Length; i++) { textHolder.text += input[i]; SoundManager.instance.PlaySound(sound); yield return new WaitForSeconds(delay); } yield return new WaitUntil(() => Input.GetMouseButton(0)); finished = true; } } Notice that the logic is the same but I replaced Text with TextMeshPro and Font with TMP_FontAsset, it will work now if you everything else right. Good luck! :)
@@PandemoniumGameDev Thank you! I appreciate your help and patience. I was doing something like that before but realized it wasn't working because I was modifying it in a different script and forgot to change the class name. Now there aren't any errors in the scripts, but when I press play and activate the dialogue, I got some NullReferenceException errors: DialogueSystem.DialogueLineTMP.ResetLine () DialogueSystem.DialogueLineTMP.Awake () UnityEngine.GameObject:SetActive(Boolean) DialogueSystem.DialogueLineTMP.ResetLine () DialogueSystem.DialogueHolderTMP.Deactivate () DialogueSystem.DialogueHolderTMP+d__1.MoveNext () UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at :0) UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) DialogueSystem.DialogueHolderTMP:OnEnable() my DialogueLineTMP and DialogueHolderTMP code: using System.Collections; using UnityEngine; using UnityEngine.UI; using TMPro; namespace DialogueSystem { public class DialogueLineTMP : DialogueBaseClassTMP { private TextMeshPro textHolder; [Header("Texto")] [SerializeField] private string input; [SerializeField] private Color textColor; [SerializeField] private TMP_FontAsset textFont; [Header("Delay")] [SerializeField] private float delay; [Header("Icon")] [SerializeField] private Sprite characterSprite; [SerializeField] private Image imageHolder; private IEnumerator lineShow; private void Awake() { imageHolder.sprite = characterSprite; imageHolder.preserveAspect = true; ResetLine(); } public void ResetLine() { textHolder = GetComponent(); textHolder.text = ""; end = false; } private void OnEnable() { lineShow = WriteText(input, textHolder, textColor, textFont, delay); StartCoroutine(lineShow); } private void Update() { if (Input.GetMouseButtonDown(0) && lineShow != null) { if (textHolder.text != input) { textHolder.text = input; } else { end = true; } StopCoroutine(lineShow); } } } } ///////////////////// ///////////////////// using System.Collections; using UnityEngine; namespace DialogueSystem { public class DialogueHolderTMP : MonoBehaviour { private void OnEnable() { StartCoroutine(dialogueSequence()); } private IEnumerator dialogueSequence() { for (int i = 0; i < transform.childCount; i++) { Deactivate(); transform.GetChild(i).gameObject.SetActive(true); yield return new WaitUntil(() => transform.GetChild(i).GetComponent().end); } gameObject.SetActive(false); } private void Deactivate() { for (int i = 0; i < transform.childCount; i++) { transform.GetChild(i).gameObject.SetActive(false); transform.GetChild(i).GetComponent().ResetLine(); } } } } The DialogueBaseClass is pretty much the same you wrote, but the name is "DialogueBaseClassTMP", using TMPro; and without the AudioClip sound and delayBetweenLines because I won't use them. I've been trying to figure it out for hours and still don't know what is wrong...
hi im getting this error Assets\DialougueLine.cs(19,45):error CS1503: Arguement 2: cannot convert from 'TMPro.TextMeshPro' to UnityEngine.UI.Text' Can someone please tell me what Ive done wrong and how to fix it also Ive looked at opacity but my text isnt displaying so I think it has something to do with this
AH sorry, getting stuck with a NullReferenceException... I think my textHolder.text is returning a null? I see it really wants to have a bracket suffix {x,y} but not sure what to have. Any help would be SO helpful!
Hey! Thanks for the tutorial! I've actually figured out how to trigger the dialogue after pressing a key while in a certain place. Yet, I can't understand how can I create a system with infinitely repeating lines. I want it to work this way, but can't understand how to implement it: - Start dialogue - Text being written - End of dialogue - Start again - The same text being written again - End - Start again And on and on like this. I've tried everything out, but when I start a dialogue again it just prints the last line of dialogue and doesn't let me close it. And also, how can I make it so when I press a certain key the line prints fully, so I can skip waiting for the line to end? Please, make a video explaining this topic. I've searched all throughout the Internet and haven't found anything useful!
Glad to hear it helped, I've been reading all your messages and I can't wait to make another episode. Finishing one of my jobs this week and making the new episode this weekend for sure, it will include everything you wanted in the comment.
Meanwhile, if you need a quick solution here's what I did in a couple minutes: 1. find a way to activate/deactivate DialogueHolder object from another script. 2. use the changes I did below and it will work every time you you want to start the dialogue again //Dialogue holder using System.Collections; using UnityEngine; namespace DialogueSystem { public class DialogueHolder : MonoBehaviour { private void OnEnable() { StartCoroutine(dialogueSequence()); } private IEnumerator dialogueSequence() { for (int i = 0; i < transform.childCount; i++) { Deactivate(); transform.GetChild(i).gameObject.SetActive(true); yield return new WaitUntil(() => transform.GetChild(i).GetComponent().finished); } gameObject.SetActive(false); } private void Deactivate() { for (int i = 0; i < transform.childCount; i++) { transform.GetChild(i).gameObject.SetActive(false); transform.GetChild(i).GetComponent().ResetLine(); } } } } //DialogueBaseClass using System.Collections; using UnityEngine; using UnityEngine.UI; namespace DialogueSystem { public class DialogueBaseClass : MonoBehaviour { public bool finished { get; set; } protected IEnumerator WriteText(string input, Text textHolder, Color textColor, Font textFont, float delay, AudioClip sound, float delayBetweenLines) { textHolder.color = textColor; textHolder.font = textFont; for (int i = 0; i < input.Length; i++) { textHolder.text += input[i]; SoundManager.instance.PlaySound(sound); yield return new WaitForSeconds(delay); } //yield return new WaitForSeconds(delayBetweenLines); yield return new WaitUntil(() => Input.GetMouseButton(0)); finished = true; } } } //DialogueLine using UnityEngine; using UnityEngine.UI; namespace DialogueSystem { public class DialogueLine : DialogueBaseClass { private Text textHolder; [Header ("Text Options")] [SerializeField] private string input; [SerializeField] private Color textColor; [SerializeField] private Font textFont; [Header("Time parameters")] [SerializeField] private float delay; [SerializeField] private float delayBetweenLines; [Header("Sound")] [SerializeField] private AudioClip sound; [Header("Character Image")] [SerializeField] private Sprite characterSprite; [SerializeField] private Image imageHolder; private void Awake() { imageHolder.sprite = characterSprite; imageHolder.preserveAspect = true; ResetLine(); } public void ResetLine() { textHolder = GetComponent(); textHolder.text = ""; finished = false; } private void OnEnable() { StartCoroutine(WriteText(input, textHolder, textColor, textFont, delay, sound, delayBetweenLines)); } } }
Thank you so much! I'll try it as soon as I can! I've already found out a way to activate Dialogue Holder from the NPC's script! I think this may work if I put it together rightly. Thank you again!
@@PandemoniumGameDev HAHAHAHA YES! IT WORKS! I just needed to put the "OnActive" function into the scripts and reset the text lines, but I didn't know how to do this before. Thank you!
@@wutbuffe4734 put it in the DialogueHolder.cs: private IEnumerator dialogueSequence() { if (!dialogueFinished) { for (int i = 0; i < transform.childCount - 1; i++) { DeactivateLines(); transform.GetChild(i).gameObject.SetActive(true); yield return new WaitUntil(() => transform.GetChild(i).GetComponent().finished); } } else { DeactivateLines(); int index = transform.childCount - 1; transform.GetChild(index).gameObject.SetActive(true); yield return new WaitUntil(() => transform.GetChild(index).GetComponent().finished); } gameObject.SetActive(false); dialogueFinished = true; //put your event here! }
I was stuck at the exact same problem. After I also got stuck with the color part not showing any text, and the solution being that oppacity was 0 by standart, I expected my mistake to be something similiar this time too... I solved it by adding an audio Listener to the scene....
Hello, I would like to modify it, could you help me? I want the exchange of phrases to be when clicking on the "space" button, it could help me. How do I do?
This is an excellent tutorial. But I have an issue, when I added text color and text font, I get 3 errors, "No overload method for WriteText takes 4 arguments" "The name textColor does not exist in the current context" "The name textFont does not exist in the current context" I'm pretty new to Unity and I'm not exactly the best at C#, so I was wondering if there was something wrong that would have caused this. My code is exact (im pretty sure) to what is in your video, but these errors come up anyway. Is there something I may have done incorrectly to cause these?
For the the font and color not existing it just means that you forgot to reference them, after the line '' private Text textHolder; " Add the two following lines lines : [SerializeField] private Font textFont; [SerializeField] private Color textColor;
Really good tutorial :D Well explained and showing :) this is simular to what i need for my game :) am thinking on a DeltaForce inspired game and DF1&DF2 both had text like that with smal delay between each Letter and you hear a military type wrighter Sound :D idea of tutorial: do you know how to make a Track selection screen simular to the older ones in arcade selecting a car you had a car in senter and arrow on each side, and you select the cars via arrow keys(or on pc clikcing on the arrows or using arrows), and simular on track that shows image of track& info text on track and 2 arrows, the image and info change for each track. amd strugeling with his in my car game, and am not sure how to code it good/working without alott of IF Statements& i kind of struggle with communicating between scripts :)
Hey Stig, thanks a lot, really appreciate it! Regarding your idea, yeah I could make something like that for you by the end of this week, stay tuned ;) PS: don't worry that you have a lot of IF/ELSE statements for now, it's a part of the learning process, just make your game work and continue to improve gradually :) we all start out as beginners
@@PandemoniumGameDev Great :D Awsome :D oh ok hehe, That`s true, some times i have read my old code and improved it sort of hehe, few days ago i actually fixed&improved my sniper/scope script :)
I honestly have no idea because I haven't worked with Unreal. I believe the logic should be the same, so that's the good part. The challenge will be to adapt all the code from C#/Unity to C++/Unreal. Good luck, hope you find a way to do it!
So i finally reach 5:03 and i want to try how the text work, but when i try it, it has error like this NullReferenceException: Object reference not set to an instance of an object DialogText+d__5.MoveNext () (at Assets/New Folder 1/DialogText.cs:22) UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at :0) UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) DialogText:Start() (at Assets/New Folder 1/DialogText.cs:15) Does anyone know how to fix this?
From what I'm reading here I assume you don't have a text component on your DialogText object. But I might be wrong because I see that you didn't copy my code exactly so let me know if it solves it.
@@PandemoniumGameDev i'm so stupid, the error was from other script that i made for cutscene, but now after i fix it, the text still didn't show up, but there's no error about it
@@PandemoniumGameDev dude, i got more error NullReferenceException: Object reference not set to an instance of an object DialogueSystem.DialogueBaseClass+d__0.MoveNext () (at Assets/New Folder 2/Script/DialogueSystem/DialogueBaseClass.cs:17) UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at :0) UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) DialogueSystem.DialogueLine:Awake() (at Assets/New Folder 2/Script/DialogueSystem/DialogueLine.cs:33)
Hi, I have gotten to the part where you make the dialogue, but when I hit play, the text will show in the Unity text sidebar, but on the play screen, nothing shows. Can you help me? My Script //DialogueLine using UnityEngine.UI; using UnityEngine; using System.Collections; namespace DialogueSystem { public class DialogueLine : DialogueBaseClass { private Text textHolder; [Header ("Text Options")] [SerializeField]private string input; [SerializeField]private Color textColor; [SerializeField]private Font textFont;
private void Awake() { textHolder = GetComponent(); StartCoroutine(WriteText(input, textHolder, textColor, textFont)); } } } //DialogueBaseClass using UnityEngine.UI; using UnityEngine; using System.Collections; namespace DialogueSystem { public class DialogueBaseClass : MonoBehaviour { protected IEnumerator WriteText(string input, Text textHolder, Color textColor, Font textFont) { textHolder.color = textColor; textHolder.font = textFont; for (int i = 0; i < input.Length; i++) { textHolder.text += input[i]; yield return new WaitForSeconds(0.1f); } } } }
@@PandemoniumGameDev It still doesn't display the text. If you have discord, I can send you a clip of the code running. My discord name is Howie Nation#9225
Hey Mate. Firstly you changing lines bu using WaitForSeconds method; Secondly you use WaitUntil method with mouse click. I want to use them both. But How? I cant work with OR between WaitForSeconds and WaitUntil. Little help would be nice...Thank you.
@@fromoldcity this is not very elegant but it works: if(Input.GetMouseButton(0)) yield return new WaitUntil(() => Input.GetMouseButton(0)); else yield return new WaitForSeconds(2); finished = true;
@@PandemoniumGameDev I Used your new code for my game. Only one problem left that i'm faced. In this method; if I dont click mouse button, all 4 dialogue lines passed and finished nicely by order of 2 seconds row. İf I hit mouse button when the dialogue is playing, Dialog speeds up and code is stopped. The problem is; dialog is stopped. This is not passing to other dialog lines. Is there a solution for this. Thank you. ( In addition to reason that i want to do that : My game is rapid and sometimes i cannot hit the mouse button for pass the dialog.
@@YozyXD well you're gonna have to use all the scripts and the exact structure as I did in the video. Check that the DialogueHolder is the parent object and has the DialogueHolder script. Then place multiple text objects as it's children and give them each the DialogueLine script.
@@masterlewzilla2116 Yes definitely, thought it will take a bit of work. Take a look at this: docs.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-read-from-a-text-file
Thank you so much but i am trying to do when you press a button when you near a npc, run a dialogue with this system but it is just run single dialogue and when i press a button it doesn't skip. Here is my interaction script: namespace DialogueSystem { public class interaction : MonoBehaviour { public LayerMask myLayer; public Transform myObj; public Transform player; [SerializeField] private float radius; private bool playerDetector; public dialogueHolder dialogue; void FixedUpdate() { playerDetector = Physics2D.OverlapCircle(myObj.position, radius, myLayer); if (playerDetector) { if (Input.GetKey(KeyCode.E)) { dialogue.gameObject.SetActive(true); } } } } }
0:00 Useless Intro
0:49 Dialogue Base Class
1:30 Visual Example of how it works
2:29 Dialogue Line Class
3:36 First Working Version
4:09 Adding Custom Color and Font for each dialogue line
5:07 Customizing the speed with which letter appear
5:44 Adding Sounds
8:20 Sans Voice
8:50 Adding Graphics
9:50 Character Portraits
11:20 Making Multiple Lines appear in sequence
13:29 Adding Time Delays before changing lines
14:43 Changing Lines with mouse clicks
15:06 Turning off dialogue when done
15:30 Final version showcase
16:05 Want me to extend this and add more options?
Hope this helps people navigate this long-ass video.
0:59 what did you clicked, that you could click "IEnumerator - using System.Collections;"?
@@microwave1852 Alt-Enter while keeping your selection cursor on the ienumerator word.
Check this out for more shortcuts:
docs.microsoft.com/en-us/visualstudio/ide/default-keyboard-shortcuts-in-visual-studio?view=vs-2019
@@PandemoniumGameDev thx
Here with my small contribution, because now we use TextMeshPro:
Replace Text with TMP_Text in both scripts
Dude, thank you so much, you saved my game!
bless you man. i was struggling with this
Thank you so much!
This is an EXCELLENT tutorial! Probably the best dialog tutorial I've watched, and I think I've watched almost all of them by now! Great explanations, editing and everything! I would LOVE to see another video on this about branching dialog, etc.
This is really high praise, thank you! Episode 2 is 50% done, it won't have branching dialogue unfortunately, will leave that for episode 3 I guess.
Pandemonium Games Excited for an episode 2 and beyond! Even getting these attached to certain NPCs to trigger sequences would be AWESOME. Thanks!
@@rmcquade19 Managed to get rid of that error?
It works perfectly!
please keep doing these tutorials, I'd love to see how to add multiple answers!
Super helpful! Not making an Undertale or Deltarune game, but learning how the dialogue actually works is essential.
you have no idea how long I've looked for a proper dialogue system that would work for my game!!! I hope that you get popular enough for others to see your wisdom!
Ah, thank you for the kind words! I'll keep putting up content and hopefully people will find it :). BTW episode 2 of this series is being recorded now.
One of the best tutorials I have come across! thanks
for the people having nullreference error:
create new ui/legacy/text
not text mesh (idk why it doesnt work but dont use text mesh use legacy text)
Thank you for this comment! It now works for me
soo true bestie!!! thank you
This was super helpful. I appreciate how you explain each line along the way. Thanks for this!
You guys might get an issue at 3:25 where the INPUT text does not register at the Dialogue1. Just don't use TextMeshPro and use the text on the legacy options of the UI. For some reason, textmeshpro sux so much.
3:27 i followed all the code and steps but the Example Text didn't appear when I went into playmode. do you know why?
Props! You've done a great Job! Helped me a lot.
omg what a great level this tutorial has, thanks for existing
This is just, amazing!!! Thank you so much for your video and for sharing your knowledge!
more than happy to help :)
Thanks for the video man! Super detailed and helpful, love it!
Ngl this is actually perfect for a story mode part of my game!
Your amazing! Just wow! Thank you so much man! You can't believe how much you helped me!!!!
Amazing tutorial! Please make more dialouge!
hey thanks a ton! You mean to make this more advanced? Branching dialogue and stuff?
@@PandemoniumGameDev Yes please!
@@moonstonestudios8719 you got it, I'll do my best to make some time for it this week
@@PandemoniumGameDev thank you!
Thank you for this beautiful video! It's awesome!
Hi, awesome video! But I seem to have a problem at 13:16. When you play yours, dialogue 1 and dialogue 2 are separate but for me, the dialogues play at the same time. Hopefully you see my comment and help me with this problem. :(
Hey i don't know if you've figured it out, but i had the same problem. And the problem was no putting the DialogueHolder Script to the Dialogue holder object. Yeehaw
@@jibyap7790 Thank you! You saved my life.
The way you solve it is by attaching the DialogueHolder script to the text box UI!
@@jibyap7790 bro you just saved my entire project thanks so much
this tutorial is really good and easy to follow and has good explaining, my only feedback is to zoom in onto the code and go a bit slower
Hey, after I add the text color and text font functionality, it does not display when I hit start. The code is perfect, it's exactly what you have. But for whatever reason when I add these features, it does not display the text when I hit the start button.
It does however work with your unity project. Yours works just fine when I boot it up and play it, after I enable the sprites and sounds that is.
@@holdenthompson1449 It happened to more people, the problem is that the color parameter has 0 opacity, so it's transparent. The text is there you just can't see it. Make sure to change the opacity to 100%.
@@PandemoniumGameDev My God 🤦. How could I be so foolish? Thank you! I appreciate the quick response!
@@holdenthompson1449 as I said, easy to miss. Lotta people got this problem.
@@PandemoniumGameDev I had the same error, thank you very much xD
Great video! It helped a lot :D Thank you!
Hello, I'm at 05:26 and I can't go ahead because the script has an error saying:
Assets \ scripts \ Dialogo 2 \ DialogueLine.cs (21,28): error CS0103: The name 'WriteText' does not exist in the current context.
I really need your help, and I'm on Unity 2019.2.0f1
check the DialogueBaseClass and see if you have the WriteText Ienumerator there. Check the name and make sure it's marked as protected, not private.
Also check if DialogueLine class is inheriting from DialogueBaseClass not MonoBehaviour
@@PandemoniumGameDev Thanks, man, what went wrong is that I switched DialogueBaseClass to MonoBehaviour, on DialogueLine
@@UpBeeGames yep, no inheritance, no access to WriteText. Glad you found it.
I've never seen such an interesting tutorial. The example of Undertale was cool !
Thank you for this i Subscribed and Liked the video
Thanks for this! It is a great video!
Hey man, this means the world to me, thanks!
😃Woh, thanks! It's just what I was looking for 💖
At 13:16 Yours plays Dialogue 1 then Dialogue 2. For me it plays them both at the same time and I dont know what to do to fix it
i have the same problem. have you found an answer
@@aceking1266 Nope
@@aceking1266 @Ploushie Hi, I have exactly this problem too and I can't solve it, has anyone succeeded?
Check if you started couroutine for dailoguesequence
@@alok8744 what do u mean
It's absolutely what I want!Thank you so much!:)
if anyone else has the problem of the sound only playing once at the start of the text, enable an audio listener for the main camera!
Thanks for this, was really scratching my head to no end over it.
thank you so much, you just saved my project :')
Thanks for the tutorial!
At 12:48 dialogueSequence returns an error saying that it can't convert system.ienumerator to string. Do you know what could be the problem? Otherwise this video has been really useful :)
Here's the code:
using UnityEngine;
using System.Collections;
namespace DialogueSystem
{
public class DialogueHolder : MonoBehaviour
{
private void Awake()
{
StartCoroutine(dialogueSequence());
}
private IEnumerable dialogueSequence()
{
for (int i = 0; i < transform.childCount; i++)
{
Deactivate();
transform.GetChild(i).gameObject.SetActive(true);
yield return new WaitUntil(()=>transform.GetChild(i).GetComponent().finished);
}
}
private void Deactivate()
{
for (int i = 0; i < transform.childCount; i++)
{
transform.GetChild(i).gameObject.SetActive(false);
}
}
}
}
nvm I found the mistake, i wrote ienumerable instead of ienumerator ;)
How come when I get to step "Adding Custom Color and Font for each dialogue line" the text input isn't visible when I press play?
Make sure the color is correct, if you have black text on black background it might not be visible. That's just a guess if that's not it let me know
@@PandemoniumGameDev Yeah my colors are correct and the text is just not appearing. When I'm selected on the "Text" icon I can still see the script loading each letter one by one, but it doesn't appear in the actual game.
@@kittyherobrine might be that the text is not fitting in your text box, hop on to Discord and send me a video and I'll tell you for sure
@@PandemoniumGameDev Sent it
im having the same problem
7:29 time stamp. a=225!
THX man you are my hero !
random but I'm gonna have to watch this on my TV. My monitor doesn't fit two tabs at the same time lol
Hi, amazing tutorial. Just wanted to know, how would someone go about changing the background image in tune with the dialogue (like a cutscene). Very similar to the example you gave at the beginning. Thank you
Make a UI image and attach a script on it. Use the same logic we used in this tutorial, you make an array of sprites and every time your player presses Space or click, you change the image.sprite = arrayOfSprites[currentImage]. Let me know if it's clear
@@PandemoniumGameDev Awesome, thank you
Awesome tutorial! Quick question, do you know how you could insert a standalone sound effects between dialogue lines? Like after the player mouse clicks past a line of dialogue an effect like a glass break or something plays before the next text line reads?
Sure, you can do that easily. Notice the line I added after Input.GetMouseButton(0), that's the one you need, you'll also need to replace "_newSound" that I added in there, you'll figure it out, good luck :)
public class DialogueBaseClass : MonoBehaviour
{
public bool finished { get; private set; }
protected IEnumerator WriteText(string input, Text textHolder, Color textColor, Font textFont, float delay, AudioClip sound, float delayBetweenLines)
{
textHolder.color = textColor;
textHolder.font = textFont;
for (int i = 0; i < input.Length; i++)
{
textHolder.text += input[i];
SoundManager.instance.PlaySound(sound);
yield return new WaitForSeconds(delay);
}
//yield return new WaitForSeconds(delayBetweenLines);
yield return new WaitUntil(() => Input.GetMouseButton(0));
SoundManager.instance.PlaySound(_newSound); //Sound that plays between lines, you need to replace _newSound with an Audioclip
finished = true;
}
}
@@PandemoniumGameDev Awesome that worked! Last question, haha. Do you know if I can add the ability to change text color, font, or facing (bold, italic, underline) of individual strings in the text?
@@sudahi51 harder to do with this system, will think about it but for now I'd recommend to put this stuff in a different line.
@@PandemoniumGameDev this absolute chad took out the time to paste the code for a confused commenter. sub earned
@@inxendere thanks :D I try to do it on all my videos
Hey thanks so much for this video! Do you how would implement this using timeline? I want a certain dialogue to start at a certain point of the cutscene and only advance in the cutscene once the continue key is pressed.
Basically just like an undertale cutscene
For the first part 0-0:06 seconds is that just a black background, with changing pictures and your dialogue? How did you get the pictures to go in order and fade out/in?
That's not a part of this project, it's a cutscene from Undertale. You could make it tweaking this system though, just need add the image to each dialogue line, and to create the fade effect you can use a CanvasGroup component.
@@PandemoniumGameDev Do you do paid 1 on 1 sessions?
@@christophera434 never thought about this. DM me on discord
Why my DialogueHolder.cs is not working? It doesnt proceed to the next child of the DialogueHolder, just the first one? Thanks
Same issue, im trying to figure it out. If i do ill tell you the solution
@@KKatsuragiMusic i fixed it, im using the wrong gameobject with the dialogue holder
My dialogue lines get played at the same time. I have no clue how to fix it. I've triple checked all lines. Everything is as in the video. Plz help
I've literally incorporated your unity package of the finished project and it's still doing it. Man :/...
You needed to move the DialogueHolder code you just wrote to the background for the text, which is also called DialogueHolder in the video.
NullReferenceException: Object reference not set to an instance of an object
DialogueSystem.DialogBaseClass+d__0.MoveNext () (at Assets/Scripts/DialogBaseClass.cs:13)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at :0)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
DialogueSystem.DialogLine:Awake() (at Assets/Scripts/DialogLine.cs:24)
Error
did you solved it
I think the hardest part is making things work in synchrony without having a timeline.
Not sure I got what you mean. Could you elaborate?
@@PandemoniumGameDev Like, if i want a character to move to a specific place after a text or during a text, or event play a specific animation, or change the camera focus, etc.
@@PorthoGamesBR oh yeah, for sure. That would require setting up events and having multiple scripts subscribe to them and do certain stuff.
@@PandemoniumGameDev I created a cutscene script, but i still need to refine it. It depends too much on brute code yet
can u make something like when i come to guy and press c to start conversation
It is strange but after making feature with custom color and font in my game, the dialogue stopped showing text to the player
The text has 0 opacity so it's transparent, make sure to change the color and increase opacity.
@@PandemoniumGameDevHi, thanks for your response. But I cant find how to increase opacity. When i remove feature with custom color from code, it starts working. Then I've made a line textHolder.color=Color.black in Awake() section and it did everything right. Could you please say where is opacity option in unity? I've searched the net but didn't found info about it
@@annoyingGnome press on the color, and it's the fourth slider on it, you RGB and the fourth is A so opacity
@@PandemoniumGameDev thank you very much! I really appreciate you. Very helpful tutorial!
What is the advantage of making DialogueBaseClass and inheriting it? So what if we write the WriteText function directly into the DialogueLine script?
Abstraction. In this way you can make other scripts that behave differently but still have the ability to show text in way. For example you can make a Cutscene script and make it load the game when it's done, etc. In this case it's not strictly necessary, I agree, but just in case you want to extend it into something more.
Hello ! I have a problem with my coding : when I play the game, the console says that " Field'DialogueLines.textColor' is neever assigned to, and will always have its default value" and it says that for every elements of my game, the DialogueLines.imageHolder, DialogueLine.textFont, ... So I have no idea where does it come from and how I can fix it ? Does anybody have an idea ?
it means there is no code that sets those values. Maybe check if you're setting the values correctly?
trying this and have canvas, background/dialogue , Text .... added in dialogue line and with input " Sans "
as soon as i hit play and it starts ... and then pauses with only "S" in the Text....with error
NullReferenceException: Object reference not set to an instance of an object
DialogueSystem.DialogueBaseClass+d__4.MoveNext () (at Assets/Dialog System/Scripts/DialogueSystem/DialogueBaseClass.cs:19)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
DialogueSystem.DialogueLine:Start() (at Assets/Dialog System/Scripts/DialogueSystem/DialogueLine.cs:38)
using Unity version 2018.4.20f1
The exception is on line 19 of DialogueBaseClass.cs so 2 options: 1. Soundmanager instance is missing 2. textHolder is missing. But from what you said that S appears then it stops it seems like you have a problem with the SoundManager, check if you create an instance of it inside Awake() or if the object is present in the scene at all.
Try in DialogueLine get "StartCoroutine..." from Awake() and put it to Update() and add IF statement to it (for example: if you push SPACE, then dialog will start). I have same problem. And it help
Or just make in DialogueBaseClass.cs something like this:
if(sound != null)
{
SoundManagerScr.instance.PlaySound(sound);
}
When i put the characterimage as a child of the dialogue line, it doesnt become active when i press play. please help
It says this when i try to make multiple lines of dialogue
Assets\C#\DialogueHolder.cs(22,96): error CS1061: 'DialogueLine' does not contain a definition for 'finished' and no accessible extension method 'finished' accepting a first argument of type 'DialogueLine' could be found (are you missing a using directive or an assembly reference?)
Did you make finished public in the DialogueBaseClass.cs?
@@PandemoniumGameDev it was public already so i'm not sure what the problem is
@@enigmatic3280 also check it DialogueLine.cs is inheriting from DialogueBaseClass.cs. Otherwise not sure, you may need to go through all the code again or download the complete project from the link in the description
Hey, first of all, thank you very much for this tutorial, its awesome! Im new to Unity, I'm a media science student from germany and we are programming our first game, so this video really helps!
I dont know if you'll read this and if you can help me out, but I do have a question. I get a nullreferenceexception error with this line "SoundManager.instance.PlaySound(sound);"
even though the sound plays perfectly. I would be really happy if you could help me out! And thanks again!
The fact that the sound plays perfectly means this exception is happening only once I assume. I think you're trying to start the dialogue in the Awake() method in some script. If that's the case change the Awake() to Start(). The problem is that the SoundManager.instance is being created in Awake, and you're trying to access it in another Awake and it's not ready. Let me know if that's the case.
@@PandemoniumGameDev I was stuck with this problem for 2 hours. Thanks for the help!
Hello I tried to solve the problem many times, but after applied 05:02 script, the letter disappears. can any1 explain me how to fix it?
For me, the alpha of the text was at 0. You can change it when change the color. Underneath the RGB values, you'll find Alpha values.
@@dingusproductions3708 thanks a lot, I fixed problem by this solution
eh... it didn't work! dialog base class and already I'm stuck.... It's giving me a null exception. what??
what if i want that when dialogue ends it transition to a different scene like to main level
I have a strange problem. When I manually write text in the text section in the inspector I can see the text appear on screen. But when I press play, I hear the sans sfx but I dont see any text written on the screen.
That's the trick here, you don't write the text into the text section, you write it in your Dialogue Line(Script) component, there's an input field there for it. Hope this helps :)
@@PandemoniumGameDev yeah I did that. I write it in the input section of the script and it shows it typing in my text section on the text gameobject, but I don't see it in game. Just the blank dialog box image.
@@toxiconflict Weird, did you make the script run in Editor Mode? If not follow the video or alternatively just download the entire project, link is in the description. Let me know how it goes :)
@@PandemoniumGameDev I'm having the exact same error. Maybe has it something to do with the DialogueLine being a DialogueBase class, instead of a Monobehaviour one?? How do you run the script in Editor Mode?
@@edywiiii DialogueBaseClass derives from Monobehaviour, therefore the DialogueLine class also derives from it + the DialogueBaseClass. Now it you get an error try checking the log, maybe there's something else causing it. If you still can't figure it out download the complete project(link in description), as you can see in the video it's working, tried to run it now and it works fine.
Idk Why but the DialogueLine class doesnt read the DialogueBaseClass
what do you mean doesn't read?
@@PandemoniumGameDev idk dude, it just doesnt work. it says it doesnt exist
@@Brick69 if you're sure you did everything right and it doesn't work, download the complete project (link in bio)
@@PandemoniumGameDev dw i found the problem, it was just Aa vs problem
@@Brick69 great
Hi, thx for this tutorial!) Its very helps me a lot) And not only for me! Pls continue your tutorials, they are so good and awful. And be so slower)
I am stuck after "Making multiple lines appear in sequence",
In Dialogue Holder.cs, I did everything same as yours, but in this coroutine
private IEnumerator dialogueSequence()
{
for (int i = 0; i < transform.childCount; i++)
{
Deactivate();
transform.GetChild(i).gameObject.SetActive(true);
yield return new WaitUntil(() => transform.GetChild(i).GetComponent().finished );
//In this line unity says Null reference exception... its not going to dialogue 2
}
}
Also, the first letter of my input text is duplicating .... Eg: If i want to show "I am hero :D", it displays "II am hero :D"
Check if your dialogue holder in Unity doesn't have any other stuff except dialogue lines. You should only have dialogue lines there, otherwise it's searching for a dialogue line component and can't find it therefore the null reference.
@@PandemoniumGameDev NVM NVM NVM :DD I fixed all the problems, thanks for your help :D, sorry I deleted all those spam replies lol
My texthoulder variable is NULL, how can I fix this
hey, I was wondering how I would make the Karma system for health
Instead of using the mouse click how can i replace with mobile button on click()? a small code/ info line please, really liked this tutorial just wanted to know how to use the skip with button usage? Thanks
at 13.15 the two texts appear at the same time, I have already tried to check the scripts and settings and everything is OK.
Does anyone have any idea what the problem is?
yes i also have same problem did you find the solution yet
The way you solve it is by attaching the DialogueHolder script to the text box UI!
The sound does not turn off after the writing process is finished. How can I fix this?
I Am Getting "No Overload for method Writetext takes 6 arguments" issue
3:28 ah okay
my thingy dindt workz!!11!
pls add a fixz!11
Great tutorial! How can I make it work with TextMesh Pro instead of Text?
Pretty small change, the textHolder variable has to be of type TextMeshPro not text, the rest of the logic stays the same basically
@@PandemoniumGameDev I can't because it's always trying to convert TMP to Unity default text. I tried "TextMeshPro.SetText" instead of "WriteText" but it doesn't work
@@belebs WriteText is not a preset function, it's one I made, that's why TextMesh doesn't have it built it.
Instead what you want to do is this:
public class DialogueBaseClass : MonoBehaviour
{
public bool finished { get; set; }
protected IEnumerator WriteText(string input, TextMeshPro textHolder, Color textColor, TMP_FontAsset textFont, float delay, AudioClip sound, float delayBetweenLines)
{
textHolder.color = textColor;
textHolder.font = textFont;
for (int i = 0; i < input.Length; i++)
{
textHolder.text += input[i];
SoundManager.instance.PlaySound(sound);
yield return new WaitForSeconds(delay);
}
yield return new WaitUntil(() => Input.GetMouseButton(0));
finished = true;
}
}
Notice that the logic is the same but I replaced Text with TextMeshPro and Font with TMP_FontAsset, it will work now if you everything else right. Good luck! :)
@@PandemoniumGameDev Thank you! I appreciate your help and patience. I was doing something like that before but realized it wasn't working because I was modifying it in a different script and forgot to change the class name. Now there aren't any errors in the scripts, but when I press play and activate the dialogue, I got some NullReferenceException errors:
DialogueSystem.DialogueLineTMP.ResetLine ()
DialogueSystem.DialogueLineTMP.Awake ()
UnityEngine.GameObject:SetActive(Boolean)
DialogueSystem.DialogueLineTMP.ResetLine ()
DialogueSystem.DialogueHolderTMP.Deactivate ()
DialogueSystem.DialogueHolderTMP+d__1.MoveNext ()
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at :0)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
DialogueSystem.DialogueHolderTMP:OnEnable()
my DialogueLineTMP and DialogueHolderTMP code:
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
namespace DialogueSystem
{
public class DialogueLineTMP : DialogueBaseClassTMP
{
private TextMeshPro textHolder;
[Header("Texto")]
[SerializeField] private string input;
[SerializeField] private Color textColor;
[SerializeField] private TMP_FontAsset textFont;
[Header("Delay")]
[SerializeField] private float delay;
[Header("Icon")]
[SerializeField] private Sprite characterSprite;
[SerializeField] private Image imageHolder;
private IEnumerator lineShow;
private void Awake()
{
imageHolder.sprite = characterSprite;
imageHolder.preserveAspect = true;
ResetLine();
}
public void ResetLine()
{
textHolder = GetComponent();
textHolder.text = "";
end = false;
}
private void OnEnable()
{
lineShow = WriteText(input, textHolder, textColor, textFont, delay);
StartCoroutine(lineShow);
}
private void Update()
{
if (Input.GetMouseButtonDown(0) && lineShow != null)
{
if (textHolder.text != input)
{
textHolder.text = input;
}
else
{
end = true;
}
StopCoroutine(lineShow);
}
}
}
}
/////////////////////
/////////////////////
using System.Collections;
using UnityEngine;
namespace DialogueSystem
{
public class DialogueHolderTMP : MonoBehaviour
{
private void OnEnable()
{
StartCoroutine(dialogueSequence());
}
private IEnumerator dialogueSequence()
{
for (int i = 0; i < transform.childCount; i++)
{
Deactivate();
transform.GetChild(i).gameObject.SetActive(true);
yield return new WaitUntil(() => transform.GetChild(i).GetComponent().end);
}
gameObject.SetActive(false);
}
private void Deactivate()
{
for (int i = 0; i < transform.childCount; i++)
{
transform.GetChild(i).gameObject.SetActive(false);
transform.GetChild(i).GetComponent().ResetLine();
}
}
}
}
The DialogueBaseClass is pretty much the same you wrote, but the name is "DialogueBaseClassTMP", using TMPro; and without the AudioClip sound and delayBetweenLines because I won't use them.
I've been trying to figure it out for hours and still don't know what is wrong...
@@belebs It's hard to point it out here without screenshots. Join discord and let's see what we can do: discord.gg/eVDD5m9
How would I make it so the audio just plays once? Like a character reading a line?
Just move the SoundManager.instance.PlaySound method before the for loop, that way it will only play once instead of on each letter
hi im getting this error
Assets\DialougueLine.cs(19,45):error CS1503: Arguement 2: cannot convert from 'TMPro.TextMeshPro' to UnityEngine.UI.Text'
Can someone please tell me what Ive done wrong and how to fix it
also Ive looked at opacity but my text isnt displaying so I think it has something to do with this
AH sorry, getting stuck with a NullReferenceException... I think my textHolder.text is returning a null? I see it really wants to have a bracket suffix {x,y} but not sure what to have. Any help would be SO helpful!
FIXED dumb me didn’t realize I was using a TextMeshPro object instinctually-still learning!!
How did you solve the problem? Please help I'm always getting NullReferenceException errors...
Very good video! Can you make a tutorial how to make a Undertale Battle System?
Thanks! The battle system is not on my list yet, you can check out this video though: ruclips.net/video/XjGHyKBSkX4/видео.html
Hi! I want to know how to play an animation after the dialogue ends but i dont know how. any help?
Hey! Thanks for the tutorial! I've actually figured out how to trigger the dialogue after pressing a key while in a certain place. Yet, I can't understand how can I create a system with infinitely repeating lines.
I want it to work this way, but can't understand how to implement it:
- Start dialogue
- Text being written
- End of dialogue
- Start again
- The same text being written again
- End
- Start again
And on and on like this.
I've tried everything out, but when I start a dialogue again it just prints the last line of dialogue and doesn't let me close it.
And also, how can I make it so when I press a certain key the line prints fully, so I can skip waiting for the line to end?
Please, make a video explaining this topic. I've searched all throughout the Internet and haven't found anything useful!
Glad to hear it helped, I've been reading all your messages and I can't wait to make another episode. Finishing one of my jobs this week and making the new episode this weekend for sure, it will include everything you wanted in the comment.
Meanwhile, if you need a quick solution here's what I did in a couple minutes:
1. find a way to activate/deactivate DialogueHolder object from another script.
2. use the changes I did below and it will work every time you you want to start the dialogue again
//Dialogue holder
using System.Collections;
using UnityEngine;
namespace DialogueSystem
{
public class DialogueHolder : MonoBehaviour
{
private void OnEnable()
{
StartCoroutine(dialogueSequence());
}
private IEnumerator dialogueSequence()
{
for (int i = 0; i < transform.childCount; i++)
{
Deactivate();
transform.GetChild(i).gameObject.SetActive(true);
yield return new WaitUntil(() => transform.GetChild(i).GetComponent().finished);
}
gameObject.SetActive(false);
}
private void Deactivate()
{
for (int i = 0; i < transform.childCount; i++)
{
transform.GetChild(i).gameObject.SetActive(false);
transform.GetChild(i).GetComponent().ResetLine();
}
}
}
}
//DialogueBaseClass
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
namespace DialogueSystem
{
public class DialogueBaseClass : MonoBehaviour
{
public bool finished { get; set; }
protected IEnumerator WriteText(string input, Text textHolder, Color textColor, Font textFont, float delay, AudioClip sound, float delayBetweenLines)
{
textHolder.color = textColor;
textHolder.font = textFont;
for (int i = 0; i < input.Length; i++)
{
textHolder.text += input[i];
SoundManager.instance.PlaySound(sound);
yield return new WaitForSeconds(delay);
}
//yield return new WaitForSeconds(delayBetweenLines);
yield return new WaitUntil(() => Input.GetMouseButton(0));
finished = true;
}
}
}
//DialogueLine
using UnityEngine;
using UnityEngine.UI;
namespace DialogueSystem
{
public class DialogueLine : DialogueBaseClass
{
private Text textHolder;
[Header ("Text Options")]
[SerializeField] private string input;
[SerializeField] private Color textColor;
[SerializeField] private Font textFont;
[Header("Time parameters")]
[SerializeField] private float delay;
[SerializeField] private float delayBetweenLines;
[Header("Sound")]
[SerializeField] private AudioClip sound;
[Header("Character Image")]
[SerializeField] private Sprite characterSprite;
[SerializeField] private Image imageHolder;
private void Awake()
{
imageHolder.sprite = characterSprite;
imageHolder.preserveAspect = true;
ResetLine();
}
public void ResetLine()
{
textHolder = GetComponent();
textHolder.text = "";
finished = false;
}
private void OnEnable()
{
StartCoroutine(WriteText(input, textHolder, textColor, textFont, delay, sound, delayBetweenLines));
}
}
}
Thank you so much! I'll try it as soon as I can! I've already found out a way to activate Dialogue Holder from the NPC's script! I think this may work if I put it together rightly. Thank you again!
@@drakoronus Sure, stay tuned, I see people really want to see this grow so I'll make more videos on this.
@@PandemoniumGameDev HAHAHAHA YES! IT WORKS! I just needed to put the "OnActive" function into the scripts and reset the text lines, but I didn't know how to do this before. Thank you!
I have a question, how do I pause the game during the dialogue and unpause it after the dialoogue turns off
Is there a way to skip to the end of a dialogue line with a mouse click?
in this function:
yield return new WaitUntil(()
Yeah that's because the sign is => not
@@PandemoniumGameDev thank you :D
how do i make it so an event plays right after the last dialouge box is finished?
@@wutbuffe4734 put it in the DialogueHolder.cs:
private IEnumerator dialogueSequence()
{
if (!dialogueFinished)
{
for (int i = 0; i < transform.childCount - 1; i++)
{
DeactivateLines();
transform.GetChild(i).gameObject.SetActive(true);
yield return new WaitUntil(() => transform.GetChild(i).GetComponent().finished);
}
}
else
{
DeactivateLines();
int index = transform.childCount - 1;
transform.GetChild(index).gameObject.SetActive(true);
yield return new WaitUntil(() => transform.GetChild(index).GetComponent().finished);
}
gameObject.SetActive(false);
dialogueFinished = true;
//put your event here!
}
@@PandemoniumGameDev thanks this helped so much!
Eres muy bueno, crack ;b
muchas gracias :D
xd
Hello, sorry for bothering but my audio is just playing once. It's inside for loop. what should i do ?
Late reply, sorry about that. Are you getting any errors?
@@PandemoniumGameDev I fixed it but thanks for reply anyway :)
I was stuck at the exact same problem. After I also got stuck with the color part not showing any text, and the solution being that oppacity was 0 by standart, I expected my mistake to be something similiar this time too...
I solved it by adding an audio Listener to the scene....
@@flekiblue444 I solved by writing my own audio manager.
Hello, I would like to modify it, could you help me?
I want the exchange of phrases to be when clicking on the "space" button, it could help me. How do I do?
Go to 14:50, DialogueBaseClass.cs and replace Input.GetMouseButton(0) with Input.GetKeyDown(KeyCode.Space)
@@PandemoniumGameDev thanks man
This is an excellent tutorial.
But I have an issue, when I added text color and text font, I get 3 errors,
"No overload method for WriteText takes 4 arguments"
"The name textColor does not exist in the current context"
"The name textFont does not exist in the current context"
I'm pretty new to Unity and I'm not exactly the best at C#, so I was wondering if there was something wrong that would have caused this. My code is exact (im pretty sure) to what is in your video, but these errors come up anyway.
Is there something I may have done incorrectly to cause these?
For the the font and color not existing it just means that you forgot to reference them, after the line '' private Text textHolder; " Add the two following lines lines : [SerializeField] private Font textFont;
[SerializeField] private Color textColor;
didnt even work on the first try :/ dialogueline dont even work
Really good tutorial :D Well explained and showing :)
this is simular to what i need for my game :)
am thinking on a DeltaForce inspired game and DF1&DF2 both had text like that with smal delay between each Letter and you hear a military type wrighter Sound :D
idea of tutorial:
do you know how to make a Track selection screen simular to the older ones in arcade
selecting a car you had a car in senter and arrow on each side, and you select the cars via arrow keys(or on pc clikcing on the arrows or using arrows),
and simular on track that shows image of track& info text on track and 2 arrows, the image and info change for each track. amd strugeling with his in my car game, and am not sure how to code it good/working without alott of IF Statements& i kind of struggle with communicating between scripts :)
Hey Stig, thanks a lot, really appreciate it!
Regarding your idea, yeah I could make something like that for you by the end of this week, stay tuned ;)
PS: don't worry that you have a lot of IF/ELSE statements for now, it's a part of the learning process, just make your game work and continue to improve gradually :) we all start out as beginners
@@PandemoniumGameDev Great :D Awsome :D oh ok hehe, That`s true, some times i have read my old code and improved it sort of hehe, few days ago i actually fixed&improved my sniper/scope script :)
It replaced my game scene it was almost complete. Now its all lost
My dialog1 isnt showing up in the Game is just the text and i don't know why
tysm wise man !! :)
You're very welcome Toast man :D
JK, thanks a ton for watching this :)
Why is it not the same to have everything in the same script?
unity keeps saying there's no overload method for WriteText that takes 6 arguments
ok I've fixed that (I just had to add AudioClip sound to the Dialogue Base Class)
How to trigger it on action? When I try it stucks to the first letter...
I assume you're trying to say that is shows the first letter then it stops. It must be an error in this case, check your console and check the code.
Um, hopefully someone can help me with this but, WriteText int he bottom line keeps being underlined by red and I can't fix it any comments?
It just fixed itself nevermind.
Could this work with Unreal? I was interested in implementing a system like this for my game, but unfortunately I don't use Unity.
I honestly have no idea because I haven't worked with Unreal. I believe the logic should be the same, so that's the good part. The challenge will be to adapt all the code from C#/Unity to C++/Unreal. Good luck, hope you find a way to do it!
So i finally reach 5:03 and i want to try how the text work, but when i try it, it has error like this
NullReferenceException: Object reference not set to an instance of an object
DialogText+d__5.MoveNext () (at Assets/New Folder 1/DialogText.cs:22)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at :0)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
DialogText:Start() (at Assets/New Folder 1/DialogText.cs:15)
Does anyone know how to fix this?
From what I'm reading here I assume you don't have a text component on your DialogText object. But I might be wrong because I see that you didn't copy my code exactly so let me know if it solves it.
@@PandemoniumGameDev i'm so stupid, the error was from other script that i made for cutscene, but now after i fix it, the text still didn't show up, but there's no error about it
nvm, the problem is fixed, the text is finally show up, thanks dude :D
@@PandemoniumGameDev dude, i got more error NullReferenceException: Object reference not set to an instance of an object
DialogueSystem.DialogueBaseClass+d__0.MoveNext () (at Assets/New Folder 2/Script/DialogueSystem/DialogueBaseClass.cs:17)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at :0)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
DialogueSystem.DialogueLine:Awake() (at Assets/New Folder 2/Script/DialogueSystem/DialogueLine.cs:33)
@@PandemoniumGameDev if you want to check my script, im gonna send it on discord, my discord is Taki#9027
Hi, I have gotten to the part where you make the dialogue, but when I hit play, the text will show in the Unity text sidebar, but on the play screen, nothing shows. Can you help me?
My Script
//DialogueLine
using UnityEngine.UI;
using UnityEngine;
using System.Collections;
namespace DialogueSystem
{
public class DialogueLine : DialogueBaseClass
{
private Text textHolder;
[Header ("Text Options")]
[SerializeField]private string input;
[SerializeField]private Color textColor;
[SerializeField]private Font textFont;
private void Awake()
{
textHolder = GetComponent();
StartCoroutine(WriteText(input, textHolder, textColor, textFont));
}
}
}
//DialogueBaseClass
using UnityEngine.UI;
using UnityEngine;
using System.Collections;
namespace DialogueSystem
{
public class DialogueBaseClass : MonoBehaviour
{
protected IEnumerator WriteText(string input, Text textHolder, Color textColor, Font textFont)
{
textHolder.color = textColor;
textHolder.font = textFont;
for (int i = 0; i < input.Length; i++)
{
textHolder.text += input[i];
yield return new WaitForSeconds(0.1f);
}
}
}
}
Same Problem. Do you have the answer yet?
the code is correct, can you check if you attached the script to the Text object like at 3:23?
@@PandemoniumGameDev It still doesn't display the text. If you have discord, I can send you a clip of the code running. My discord name is Howie Nation#9225
@@omori8112 sent you a request
та же проблема, что делать?
i love tiby fox i never knew hes russian voice :D
Hey Mate. Firstly you changing lines bu using WaitForSeconds method; Secondly you use WaitUntil method with mouse click. I want to use them both. But How? I cant work with OR between WaitForSeconds and WaitUntil. Little help would be nice...Thank you.
You're trying to do something like this: if mouse is clicked skip the line, otherwise if player waits X seconds skip the line automatically?
@@PandemoniumGameDev Exactly. I trying to do that.
@@fromoldcity this is not very elegant but it works:
if(Input.GetMouseButton(0))
yield return new WaitUntil(() => Input.GetMouseButton(0));
else
yield return new WaitForSeconds(2);
finished = true;
@@PandemoniumGameDev I Used your new code for my game. Only one problem left that i'm faced. In this method; if I dont click mouse button, all 4 dialogue lines passed and finished nicely by order of 2 seconds row. İf I hit mouse button when the dialogue is playing, Dialog speeds up and code is stopped. The problem is; dialog is stopped. This is not passing to other dialog lines. Is there a solution for this. Thank you. ( In addition to reason that i want to do that : My game is rapid and sometimes i cannot hit the mouse button for pass the dialog.
Hey man, i really like ur vid. But i have a problem in here, my text doesn't show up
Gonna need a bit more info to help you. At which minute into the video are you? And do you have any errors?
@@PandemoniumGameDev i use your script in the description, then when i use it my character image working, but my dialogueline1 doesn't even show up
@@YozyXD well you're gonna have to use all the scripts and the exact structure as I did in the video. Check that the DialogueHolder is the parent object and has the DialogueHolder script. Then place multiple text objects as it's children and give them each the DialogueLine script.
@@PandemoniumGameDev ok, i will try it
what kind of music is playing in the background?
Underbelly - Bodega
whenever i add the component it doesnt say that i can add an input i did the line script it still didnt work can you tell me what the problem is?
need more info to help you. Which component? The DialogueLine.cs? And are you getting any errors?
@@PandemoniumGameDev dont think i have any errors but ill try to find some if i do
@@Cakestarr alright, you can DM me on discord to solve this faster
You are my hero
I'm honored to hear that :D
@@PandemoniumGameDev Do you know where in the code i can increase the size of the textfield? [TextArea(3, 10)]
@@masterlewzilla2116 you can adjust it directly from Unity, no need to code that
@@PandemoniumGameDev I could not find it :X also is there a way to load the input text from a text file?
@@masterlewzilla2116 Yes definitely, thought it will take a bit of work. Take a look at this: docs.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-read-from-a-text-file
Thank you so much but i am trying to do when you press a button when you near a npc, run a dialogue with this system but it is just run single dialogue and when i press a button it doesn't skip. Here is my interaction script: namespace DialogueSystem {
public class interaction : MonoBehaviour
{
public LayerMask myLayer;
public Transform myObj;
public Transform player;
[SerializeField] private float radius;
private bool playerDetector;
public dialogueHolder dialogue;
void FixedUpdate()
{
playerDetector = Physics2D.OverlapCircle(myObj.position, radius, myLayer);
if (playerDetector)
{
if (Input.GetKey(KeyCode.E))
{
dialogue.gameObject.SetActive(true);
}
}
}
}
}
hey man, episode 2 is all done, releasing it today, you're gonna find what you're looking for there
@@PandemoniumGameDev Alright then, thanks