Thanks for watching! 🙂 There was a small bug with how choices are being made towards the end of the video. If you're experiencing odd behavior (dialogue closing instead of choice being made) then this might be the fix. Thank you to @Baran for pointing out a solution to this. I wanted to pin a comment here so people don't have to dig through the other comments and piece things together to find the solution. You can follow the below instructions - or watch the first part of this video where I go over the fix - ruclips.net/video/HP1EYVwAhRg/видео.html *1.* In the MakeChoice method, add a call to 'ContinueStory()'. public void MakeChoice(int choiceIndex) { story.ChooseChoiceIndex(choiceIndex); *ContinueStory();* } *2.* Ensure that if there are choices, it's going through the MakeChoice method and NOT the Update method when you press a button. You can modify this if statement in your Update method to accomplish this. // handle continuing to the next line in the dialogue when submit is pressed if ( *currentStory.currentChoices.Count == 0 &&* InputManager.GetInstance().GetSubmitPressed()) { ContinueStory(); } *3.* If you're using the custom InputManager script that I'm using in the video. I modified it slightly and am now registering the button press in 'MakeChoice' so that way the input doesn't carry over. This is specific to how I'm handling input, so if you're not using that script you probably won't need to do this step. public void MakeChoice(int choiceIndex) { story.ChooseChoiceIndex(choiceIndex); *InputManager.GetInstance().RegisterSubmitPressed(); // this is specific to my InputManager script* *ContinueStory();* } This has all been modified on the Github project in the DialogueManager script - github.com/trevermock/ink-dialogue-system/blob/2-choices-implemented/Assets/Scripts/Dialogue/DialogueManager.cs
I had problems with it not executing the action and hollering about "choice out of range". I had to look at the project's GitHub to figure out the problem. It was in the MakeChoice and the additional lines fixed the problem. That aside, thanks for the tutorials! Good Job!
Just 2 minutes in but I already want to thank you for actually taking the effort to teach why you are using things instead of just showing what you do without any explanation why you are doing it like 90% of other videos. This is excellent.
I am also relieved you did this! Some other people just run right into the information without really any explanation. II also love that within the first few minutes of the video you are showing a common design pattern (singleton). I can't tell you how helpful it is to see a singleton outside of the classroom setting and in something im working with. thank you!
I was trying to do this a year ago and in the past few months all of these amazing tutorials come out. I'm glad people won't have to go through the annoying process I had to go through
Thanks so much for the kind words! 🙂 It's definitely a tough subject to find good info on, so I'm really glad people have been finding the videos useful!
I had an issue where the second line of the dialogue, is always the first shown. So here's my solution, if anyone else is struggling as well! x) In the DialogueManager script, under EnterDialogueMode, remove the ContinueStory(); function, otherwise it will continue no matter what. should look like this: public void EnterDialogueMode(TextAsset inkJSON) { currentStory = new Story(inkJSON.text); dialogueIsPlaying = true; dialoguePanel.SetActive(true); } Anyways amazing video Trever, really helped me out! ✌(:
Thanks for this solution! This fixed the issue when I'm making choices with one NPC. It was missing its first line of text. However, now when I talk to an NPC with normal dialogue and no choices, the first dialogue is just a blank panel before it starts the actual text 🤔
@@discipleofmana same here, trying to make a fix ;-; Edit: Found a fix! When you delete ContinueStory(), replace it with dialogueText.Text = currentStory.currentText. Hope it helps!
love your way of teaching!! very concise and well-explained:) i just discovered ink a few days ago and your videos were such a great introduction to using it !! thank you! really excited to see future content:) 🌼
For optimization, it may be better to have the player object check for npcs in *his* range instead of a million NPCs all spherecasting for the player in *their* range.
Really great video! Finally found a tutorial for a dialogue system that gives me good groundwork to scale and change the system as my game grows. Thanks!!
This series has been immensely helpful, thanks! I just left a comment about memoizing the playlist but apparently I Just missed it earlier because it's in the description. Sooo yeah I have no notes! thanks again and please keep teaching.
Man, thanks so much for this. I rarely see tutorials with great code that actually follows OOP methods and rules. The way you explain everything is also great.
@@ShapedByRainStudios I do have a probably dumb question though. How do I make the dialog choices disappear after choosing one?? They stick around after I answer the only correct answer, Charmander of course.
@@GeraldClarkAudio Hey there! 🙂 The code at around 25:17 in the video _should_ disable all of the choice buttons when there are no choices. If the choice buttons are sticking around after choosing one, there's a good chance something is going wrong within that method. I would start with double checking your DisplayChoices() code, as that bit can be tricky to code up and it's easy to make a mistake even when following along to the video. If that looks correct, I would put some Debug.Log() statements in the DisplayChoices method to make sure it's getting called as you'd expect as well as in the MakeChoice() method to make sure that's also getting called as you'd expect when a choice is made. Hopefully through putting some Debug.Log() statements in there you'll be able to work your way backwards to figure out the issue. It can also help to check the code against the DialogueManager.cs file on the Github project for this video which can be found here - github.com/trevermock/ink-dialogue-system/blob/2-choices-implemented/Assets/Scripts/Dialogue/DialogueManager.cs I hope that helps a bit!
@@ShapedByRainStudios Thanks. I'll give it a whirl. I've set up something in my game where there is a question, then choices, then a question once one of those choices is selected. The new choices appear, but then when they are chosen they dont go away. Even after I've progressed through the rest of the dialog. I havent taken a lot of time to check with Debug.Logs. Thats the next step. Thanks again!
@@GeraldClarkAudio No problem! It's possible it could be how your Ink file is set up as well. You could plug it in to the project that's on Github to try and verify if that's the case or not. Best of luck and feel free to stop by my Discord server if you hit a block with troubleshooting this and we can dig deeper! 🙂
Wow this really makes me thankful for the Dreams engine. The way my mind works I just wouldn't be able to keep all those codes stored in my brain. I used to make web pages but I would copy and paste the codes and I could edit it a little bit but I couldn't do I think it was ccs, but java was simple enough I could remember. You must have the most wrinkly of big brains!
Haha, you get use to it after awhile and you also get really good at Googling things! 😅 The Dreams engine looks really interesting. I've been meaning to check it out to see how it works! 🙂
@@ShapedByRainStudios the hardest part is getting used to the controls but after that it's very simple wired connections to gadgets that do different things. It's basically Little Big planet on steroids that are also on steroids 😆
Absolutely fantastic video, easy to follow I also appreciate how easy it was to modify the script for my purposes, while still keeping the ink-based system intact. Thanks!
probably the best tutorial i've found for a dialogue system. keep up the good work! Only issue I'm having right now is, when I use the selection button on my keyboard, it ends the dialogue instantly. But when I use my mouse to click the dialogue option, the dialogue will continue like normal.
Hey there! Thanks so much for the kind words! 🙂 Are you using Unity's old (default) input system by chance? If so, are you using Input.GetKeyDown() or Input.GetKey()? Make sure you're using Input.GetKeyDown() - as that will be true for only the frame it's pressed. Input.GetKey() will be true for as long as the key is down - which would cause it to blow through all of the dialogue pretty quickly. That's just a guess though based on some common issues others have had. If that's not the case, it could also be related to a race condition bug found which I go over in the first timestamp of this video (if you haven't already seen it) - ruclips.net/video/HP1EYVwAhRg/видео.html&t If neither of those seem to be it, then I would recommend putting Debug.Log() statements in and around the ContinueStory() method to see if it's getting called how you'd expect. That'll at least hopefully help you narrow it down a bit. I hope one of those things helps!
I had a similar problem when exiting the dialog as you had (my character did shoot because it was the same Button). I fixed it by using ButtonDown for Shooting but ButtonUp for ContinueDialog. That might be a bit of a cleaner way solve the problem. With the coroutine you always have that tiny sliver of time at the end of the dialog where you can't use the function. That probably makes a bigger difference in my case, but I thought I mention it here if someone else wants to get around the problem. PS: That was a great tutorial!
this is a great tutorial to get the idea of dialogue system. for everyone who isnt using the new input system maybe this could help you. to choose one of the choice you can add this line to your dialogue manager private IEnumerator SelectFirstChoice() { // Get the first choice component that inherits from UnityEngine.UI.Selectable UnityEngine.UI.Selectable firstChoice = choices[0].GetComponent(); // Set the first choice as selected firstChoice.Select(); // Wait for spacebar to be pressed while (true) { if (Input.GetKeyDown(KeyCode.Space)) { // Do something when spacebar is pressed Debug.Log("Spacebar was pressed!"); break; } yield return null; } // Return a value at the end of the method yield return null; } public void MakeChoice(int choiceIndex) { currentStory.ChooseChoiceIndex(choiceIndex); ContinueStory(); }
Thank you so much for this video! It was exactly what I needed and so well explained too. I already subscribed and I really hope more people find your channel soon. I just ran into one problem when creating another NPC: The dialogue box closed on its own as soon as I talked to them (they only had one line of dialogue) when I tested out adding a second line, it didn't close on it's own anymore but skipped the first line altogether. I'm not sure why this only happened with my second NPC? Thank you so much for the video again!
Thanks so much for the kind words! 🙂 Hmm, that’s definitely strange that you’re only seeing it on another NPC. First, I’d double check your DialogueManager script against this file on GitHub (if you haven’t already) to make sure there aren’t any key differences - github.com/trevermock/ink-dialogue-system/blob/choices-implemented/Assets/Scripts/Dialogue/DialogueManager.cs Triple check the ‘ContinueStory’ method, since this sounds like it might be an issue with how the story is being continued. If all of that looks good, it’s hard to say what could be going on - but it sounds like you might be able to narrow the issue down by comparing the two NPCs since one of them is working. If they both look the same, that might point to something being wrong in the DialogueTrigger script, so I’d double check that one against the one on GitHub next. I hope you’re able to figure it out and I hope that helps a bit!
hey, im having the same issue.. have you figured out a fix for this? EDIT: i literally saved my project, opened it back up again, and it worked fine haha
Hi, loving this series of tutorials, they’ve been really helpful with a project I’ve started working on, do you know if there is a way to allow a player to select the choice buttons with a mouse as well as the game pad/keyboard? I’ve been able to highlight the choices with the cursor but it won’t select a choice to be picked. Thanks and keep up the good work!
Hey there! Thanks so much for the kind words! 🙂 Yes, that should be doable. I'm not as familiar with using mouse clicks myself, but it might have to do with how your Event System is configured. I would start troubleshooting there and work your way out. If you're using Unity's new Input System like I did in this video, you'll want to add a MouseClick option to your Input Action Asset in addition to whatever you're using as a submit button. With Unity's old (default) Input System, it might be something you need to configure in Project Settings (Edit -> Project Settings -> Input Manager). Of course - it could be something completely different than those suggestions, but those are the first things that come to mind. I hope that helps!
That's awesome and I really appreciate that! 🙂 I would like to get a Discord set up at some point; however, I'm not sure how soon that'll be. Keep an eye out in the coming months! 😁
Glad you enjoyed the series and thanks for the feedback! I've come to realize this myself and I'm taking a different approach to the background music for future videos, haha. 😁
Amazing guide even for beginners! I have a problem encountered while following through, so I am using the old input system and set my interaction to be (Input.GetKeyDown(KeyCode.E)), everything works fine and well however I cannot exit the dialogue as it loops back from the beginning and the player is unable to move.
Really glad to hear you found the video helpful! 🙂Here are my thoughts on what might be happening - but keep in mind it could be something else. What I imagine is happening here is that when the dialog ends, that same button press used to end the dialog is starting the dialog back up. If that's the case, there are a couple ways you could go about it off the top of my head. *1 - Manage your Input in a separate class and ensure a button press can only be registered once per frame.* This is actually really similar to how I have the InputManager class set up in the video. Of course, I'm using Unity's new input system; however, you could do something very similar with Unity's default Input System. See how the 'RegisterSubmitButtonPressed()' method works in this class for an example - github.com/trevermock/ink-dialogue-system/blob/7-dialogue-audio-implemented/Assets/Scripts/Input/InputManager.cs The idea here is that you'd use a separate boolean to micro-manage the players input so that the input can't happen twice in the same frame. *2 - Add a bit of wait time before the dialog closes* A more quick and dirty fix, which I think will work fine for most games, would be to put a bit of delay between closing the dialog and being able to start a new dialog. I believe this should be as simple as exiting dialogue in a Coroutine, waiting until the next frame or some small amount of time when dialogue is exited, and then setting dialogueIsPlaying=false only after that time has been waited. That said, it's been a little while since I've touched the system built in these videos so I'm not sure if there's a bit more to it then that. I hope that at least helps you get started with fixing that issue! Best of luck!
Hello! This was extremely helpful, I was struggling with ink so I appreciate this video a ton! I have a question, how would you go around getting a variable from ink to be used in another script in unity? I was trying to read ink's documentation but I was having problems with it. Thanks!
I'm glad you found it helpful! 🙂 I played around with this a bit and found two ways that worked for me. *First way - Variable State* You can use the below line (where currentStory is a 'Story' object) to access a variables current state in the story. _currentStory.variablesState.GetVariableWithName("pokemonName")_ One thing I noticed with this is that the State won't actually change until after the current line has been Continued in the story. So imagine the below Ink file: _VAR pokemonName = ""_ _First line of text_ _~ pokemonName = "Charmander"_ _Second line of text_ _Third line of text_ In that example, if you try to access the pokemon name before the 'Second line of Text' has been 'Continued', it won't be updated yet. So really, you won't see the change until you're on the 'Third line of text'. *Second way - Variable Observer* You basically create a 'listener' function that will fire off whenever a specified variable changes. It'd be ideal to put this in a 'Start' method somewhere; however, if following the example in the video you could put this in the 'EnterDialogueMode' function and it should work just fine. _// make sure the variable name exists before creating a listener_ _if (currentStory.variablesState.GlobalVariableExistsWithName("pokemonName"))_ _{_ _// create a 'listener' that will fire whenever that variable changes in the story_ _currentStory.ObserveVariable("pokemonName", (string variableName, object newValue) => {_ _// do something once the variable changes_ _Debug.Log(newValue);_ _});_ _}_ Then, you can remove the Observer in the 'ExitDialogueMode' method (or wherever you're doing clean up stuff) with the below line. _currentStory.RemoveVariableObserver(null, "pokemonName");_ I hope that helps!
This video is fantastic! Thank you so much for the clear and concise explanations for everything. I wonder, would you happen to have a method for setting character sprite/portraits to change along with each line of dialogue on the dialogue panel? For example, setting a happy portrait to go along with a happy dialogue and then switching to a more neutral portrait on the next line. I'll need to look into it, but I imagine it would involve setting some tag within the ink file/JSON and parsing it somehow? Edit: Actually, I just saw you have another video addressing this exact question, I plan to check it out next!!
Thank you! 🙂 Yes, words will automatically jump to the next line once the text has reached the end of the TextMeshPro boundary (the yellow border I mention at 13:17 in the video determines this).
So i need some help here, basically i followed your tutorial but I’m using the old input system of unit, there were no error showing up in the code so I thought it would appear, but when I pressed play and tried interacting with the object nothing showed up.
This was an awesome video which I will DEFINITELY reference too when making the dialog system for my game. I have one question though. How could we make it so that the options have a short version of our dialog option, but then display a the full length dialog on the speech bubble?
Great video Trever, really clear explanation! I got one quick design question. I'm trying to change the singleton design to the event driven design. I presume the idea is to trigger the dialogue event in the NPC and send the inkJSON file to the DialoguePanel so that it manages the display of the file. Would you send the file to all the possible listeners which probably won't use it or would you send the file especifically to the DialoguePanel? The latter makes more sense but I can't figure out how to do it without creating a dependency between the NPC and the Dialogue Panel. Thanks again for the video!
Hey! Great question and I'm glad you found the video helpful! The InkJSON file would go to all possible listeners for that *specific type of event* ; however, you would set up the *DialoguePanel* as the *only listener* for that type of event. Your DialoguePanel would now be dependent on that type of event rather than the NPC. It's a bit strange to think about, but it is quite different from being dependent on the NPC like in the Singleton pattern. I highly recommend checking out this short, but concise video by *Game Dev Guide* on setting up an event driven design pattern. It's an excellent introduction to doing Event Driven Design in Unity. - ruclips.net/video/gx0Lt4tCDE0/видео.html In that video, you can think of *TriggerArea.cs* as *DialogueTrigger.cs* and *DoorController.cs* as the *DialogueManager or DialoguePanel* scripts (depending on how you have things set up.). Creating the *GameEvents.cs* script is optional; however, it's a great way to organize your events and I would recommend doing that as well. *In short* 1 - The DialogueTrigger script will *publish* an event with the InkJSON instead of calling EnterDialogueMode(). 2 - The DialogueManager/DialoguePanel will *subscribe* to and listen for those types of events. When an event of that type is received, it'll use the InkJSON for that event to display dialogue information accordingly. 3 - Create a GameEvents script to better organize and manage your events. I hope this helps! 🙂
@@ShapedByRainStudios Thanks for all the info! The Game Dev Guide video was great but my system is working with Scriptable Objects and I found it kinda different to get my way around the problem. I found a great video of Nathan (Dapper Dino) that solves the problem: ruclips.net/video/iXNwWpG7EhM/видео.html Thanks again!
Great video! Really loved how you explained it all thank you!! I wanted to ask, could something like this be implemented for a text-adventure game? One where you just click/select choices and that progresses the story, with a still background and some sound effects. I know you mentioned in the intro that more narrative-focused games would benefit from a single ink file. Any help would be appreciated, thank you!
Thank you for the kind words! 🙂 Yeah, this system should work just fine for a text-adventure game like you described. What it really comes down to is how self-contained you want each section of dialogue to be. If there's a lot of cause/effect between dialogue (a choice you make in one story directly effects other stories) it might be a bit easier to do in a single story for the entire project. That would allow Ink to keep track of the state of everything (which it does automatically) rather than having to keep track of state in C# code between different stories. I'm actually working on a video right now that will go over how to keep track of variable state between multiple stories which will hopefully be out by next week. So if you go the multiple stories route, be sure to keep an eye out for that! If you wanted to go the single story route, you can do so with this system by making a few small changes. The idea here is that each Knot is self-contained for that piece of the story. Then, you'd navigate to a specific Knot for each click/select. *1* - Write your dialogue in a single Ink story. This can be multiple Ink files using INCLUDE statements for organization. As you're writing your story, separate each 'click/select' dialogue into different Knots. *2* - Initialize the single Ink story in the DialogueManager (Awake or Start method) instead of in the DialogueTrigger scripts. *3* - In your DialogueTrigger scripts, send a string _knotName_ to the DialogueManager instead of an inkJSON file. The Knot name should correspond with the click/select the DialogueTrigger is attached to. *4* - In the DialogueManager EnterDialogueMode method, call *currentStory.ChoosePathString(knotName)* which will take you directly to that knot in the story. Again though, this comes down to preference more than anything else. Do you want to manage multiple small stories or a single large story? They both have their pros and cons. If you're not sure, I'd just start with multiple stories like in this video and then switch over to a single one if you feel the need to. I hope that helps!
@@ShapedByRainStudios Thank you so so much for this, I really appreciate it! Looking forward to that video! I'll start working on it with what you suggested. Thank you once again!
Hi, I’m not sure if you answer this in another video, but how do you switch between regular dialogue and choice dialogue using the inkJSON? Like what if there is a file that has regular dialogue, then it asks you a question that you have a few options to choose between? How do you write code that checks for that in order to switch between the UI?
Hey there! I'm glad you've found the videos helpful! 🙂 Off the top of my head, the only difference between 2D and 3D for these tutorials should be how the DialogueTrigger class detects the player. In 2D, we used OnTriggerEnter2D/OnTriggerExit2D to detect if the player is in range (around 9:53 in the video). In 3D, you'll instead use the corresponding 3D methods OnTriggerEnter/OnTriggerExit. More details on the Enter method can be seen here (should be easy to find the Exit method docs through Google if needed) - docs.unity3d.com/ScriptReference/Collider.OnTriggerEnter.html Hopefully that helps and best of luck!
Hi! I know that this is two years old and the tutorials have been very helpful but I'm running into this issue where when one of the choices is the end of the dialogue and should close but its coming up with a blank before closing? It's like trying to load dialogue that doesn't exist before closing. eg: [No Comment] -> END This comes up as just a blank before closing instead of just closing the dialogue. Is there a fix for this? Thanks!
Hey! Really glad you've found these tutorials to be helpful! :) I imagine you're hitting a similar case to what happens when an external function is used at the end of dialog. See the timestamp "8:58 External Functions at the end of the dialogue" in this video - ruclips.net/video/dwxu4Q-GJU0/видео.html I believe that will solve the issue you're running into. I hope that helps and best of luck!
thank you for a nice tutorial. one question though: is it possible to use input.getkeydown(button) to trigger the whole dialogue instead of using the new input system? will it work that way aswell? edit: I just saw you answered this in another comment. thanks!
@@ShapedByRainStudios btw, in that case, in the choices part, we can skip the event system reference in script and just use the button event in each button to reference the number of choice when button is pressed?
I think you'll still need to reference the Event System in the DialogueManager script for that first selected choice. And yeah, you should be able to assign onClick functions for the buttons just like in the video. With all of that said, I haven't had time to try this myself with the older input system, so there could be some other hurdles or oddities I'm not thinking of. If you end up having trouble, let me know and I'll set aside some time to dig into it a bit more! 🙂
Thanks for this! great tutorial that helped me get very far and have a clear understanding! I do have a question that I hope you can help me with (or someone else here?): In a specific moment I would want to have an input field instead of a choice. My idea was to pass the information typed in the field as a global variable in Ink, and depending on the value, the story will continue one way or another. I managed to get the UI appear/hide and get the information in Unity but for some reason I do not manage to get the variable pushed to the story. Any idea how I could get this done?
Hello there, I have a problem with this, after you made your choices appear, that’s where I’m currently stuck at, The problem: The choices aren’t appearing correctly, and it’s only one that appears without the actual text as well, I have checked and compared the code and I can say for sure that it’s the same as the GitHub code, at the current stage of course, Another thing I did was use a different ink file set up they ways yours was set up in the video. Unfortunately that didn’t work either. There is also an error message that pops up: NullReferenceException: Object reference not set to an instance of an object The area where this error leads to is in the Dialogue Manager script in the DisplayChoices() function inside the Foreach loop where I think we are trying to set the choicesText[index].text = choice.text; I would appreciate it if someone could tell me where I’m going wrong
Great video! I am having an issue that when using your input manager script, when I try and enter dialogue a second time with the same NPC, it will not register my initial input to start a conversation (I have a multi-path dialogue system that was working without the input manager system you're using, but I couldn't figure out how to "select" the buttons appropriately without using your method). Not sure if that's an issue you've encountered, might be something on my end I messed up with the Input Event System, but if you have any recommendations that would be greatly appreciated :)
Hi Trever! Thanks for teach us a working and easy to manage dialogue system. This work wonderfully on pc by using sumbit and arrow button. But I wonder, is there is a way to make the button can be clicked using mouse cursor?
Hey there and thanks so much for the kind words! There's definitely a way to make the button clickable by a mouse cursor, but it can depend on what Input System you're using. I personally haven't done a lot of 'mouse click' input myself, so my best recommendation is learning a bit more about whichever Input System you're using and how it works for mouse clicks. I hope that helps and best of luck to you!
Hey there Trever! The tutorial is great so far, but my game doesn't seem to be registering that the Interact button is pressed (I set it to E). I've gotten all the way to 19:00 and set up all the scripts as well as the player interaction system and still can't seem to get it to work. The box collider detector works, it's just that the canvas and panel aren't popping up when interacting. I know this could be a variety of issues, but I was just looking for a bit of help to at least find out where this is coming from!
I'm glad you found it helpful! I might do a future video covering this, but until then - here's a couple ways you could go about it. You can feed variable state to/from the Ink story using *story.variablesState.GetVariableWithName("pokemon");* and *story.variablesState.SetGlobal("pokemon", pokemon);* . The second parameter in SetGlobal ('pokemon') is a _Ink.Runtime.Object_ type which would be used to store and access the value on the C# side. I have a detailed explanation on how to initially set this up on Discord under the _Unity_ channel if you want to check that out - discord.gg/99gcnaHFf9 *OR* Alternatively , you could also use _Ink Tags_ to pass metadata to your C# code. I cover setting that up in this video if you haven't seen it - ruclips.net/video/tVrxeUIEV9E/видео.html I hope that helps! 🙂
I know the video is old but maybe somoene can still help me! Whenever The Dialogue Ends (in the Ink file i say -> End) in the game it still displays one more empty panel (without text or buttons). Then the Player needs to Click again to close it. Thats really weird and i have no idea where this issue could come from.
Hey there! 🙂Here's some troubleshooting steps though that we can use to narrow the issue down in the code. 1 - Put some Debug.Log() statements in and around the ContinueStory() method. Ensure it's getting called exactly how you'd expect it to when you continue the dialogue. 2 - When calling currentStory.continue() method, is there a last line that's coming out as blank? This might help you determine if it's something to do with your Ink file; however, with what you mentioned already, I think this seems unlikely. 3 - Put some Debug.Log() statements in your ExitDialogueMode() method. Is this getting called before or after that empty panel shows up? That might help you narrow down if it's something with your ExitDialogueMode() method or not. Since this is happening at the end of the dialogue, it's possible something is going wrong here. 4 - It could also be worth checking your code against the Github project to see if anything seems off. The code can be found here for this tutorial - github.com/trevermock/ink-dialogue-system/tree/2-choices-implemented/Assets/Scripts/Dialogue I hope that helps a bit! If you're still stumped on this after going through the above steps, then let me know the results of anything you found and we can try to go from there.
It worked until I tried to confirm a choice. For some reason my buttons only work if you click on them, no way to confirm a choice with the keyboard, and yet I can navigate through choices. How can I make that you can press a button with the keyboard?
Hey there! Assuming you have the code set up to register button presses, usually issues like this are due to something in the Event System not being configured correctly. The first thing I would do is check your Event System button mappings to ensure your Submit button is correctly mapped. This will look a bit different depending on if you're using Unity's new Input System (like I am in the video) or Unity's old/default Input System. For reference, see around 13:50 in the video where I switch the component to be compatible with the new input system. I know of a couple others who have had issues with it not defaulting the submit button correctly in the Event System, so there's a good chance that's it. If those mappings look correct, the next troubleshooting step I recommend is to double check your Input System button mappings. For Unity's new Input System, this will be in the Input Actions Asset. For Unity's old/default Input System, these will be under Edit -> Project Settings -> Input Manager (top left menu of Unity). In addition to the above - a good troubleshooting step would be to try and print out some logging in a script when your submit button is pressed. That'll help you figure out if it's an Input issue (which is what it sounds like) OR potentially an issue specifically with your choice buttons. If it's the latter, you'll want to make sure your OnClick function for each Choice button is correctly hooked up to the MakeChoice() function. Hopefully that helps and best of luck! 🙂
I don't have a video specifically on the Input Manager used, but there is an excellent video by Samyam I've been recommending which goes over Unity's new Input System in detail that might help. It can be found here - ruclips.net/video/m5WsmlEOFiA/видео.html Or if you don't want to deal with Unity's new Input System at all, everything in this tutorial should work with Unity's old (default) input system if you replace those calls appropriately. There are some responses I've made to other comments with more details on how to go about this if that route interests you. Appreciate the kind words and best of luck! 🙂
Thank you so much!! this video is really helpful. How can I make the choice buttons show up when I press submit button once again after seeing the line?
Hi Trevor. Thank you for this amazing tutorial. I was able to add a Typewritting effect to the Dialogue System, but when typing a word using bold or color the Rich Text appear briefly on the dialogue box. Also, when the word is being written on the edge of the dialogue box and it runs out of space, the entire word disappears and appears on the next line. I saw you managed to avoid this 2 issues in your game (that looks fantastic by the way). Could you please give me a little guide on how to achieve it? A tutorial on how to do this would also be great as a follow-up to this one. Thank you very much!
You're welcome! 🙂 For your first issue with the Rich Text appearing in the dialogue box, you'll need to account for that when adding letters for the typewritter effect. The below Coroutine is close to what I'm using in my game and should do the trick. Note that if you're using '' symbols as part of your dialogue text that aren't intended to be tags, then you'll have to handle this differently. private IEnumerator DisplayLine(string line) { bool isAddingRichTextTag = false; foreach (char letter in line.ToCharArray()) { if (letter == '') { isAddingRichTextTag = false; } } else { dialogueTextDisplay.text += letter; yield return new WaitForSeconds(typingSpeed); } } } In that Coroutine, once we hit a Rich Text Tag, it'll put out the whole tag without waiting, and then go back to doing each letter. When it puts out the whole tag like that, it won't appear in the TextMeshPro text and the following text will be colored. Of course, this will do the same for the end of the tag as well. As for your other issue with text going to the next line - I believe the text in my game also does that. The clips in this video happened to be cases where the words line up with the dialogue frames length. If you really wanted to, you could come up with an algorithm to detect when a words width will exceed the current frame and then insert a newline character in those cases so the word shows up on the next line - but that's definitely more than I'd be able to get into in a RUclips comment. I hope all that helps!
@@ShapedByRainStudios Thank you SO MUCH for your quick and awesome response. Where we can see updates about your game? By the way. The Coroutine worked perfectly fine. Thanks!
@@rubpty No problem! 😁 I post updates roughly 2-3 times a week on both Twitter and Instagram! Both are @trevermock (links in description of the video).
Hi! First of all this is an awesome tutorial, thank you very much for doing this. I used this tutorial in a visual novel type setup where the dialogue is started with a simple raycast to mouseclick and it worked perfectly but I can't get multiple dialogues to work on separate NPCs, it just starts the same one. I assume the problem is with how the script picks the textfile, would you have a suggestion of where I should start troubleshooting? 😄
I'm glad you found the tutorial helpful! 🙂 Hmm. I'd start by looking at the _EnterDialogueMode_ method in the _DialogueManager_ . Maybe put some log statements in there to make sure it's getting called like you think it is. You could also play around with setting the currentStory to null in the _ExitDialogueMode_ method. That'll make sure the 'older' currentStory isn't still set when new dialogue is triggered and might help you narrow down if this is an issue with the _DialogueManager_ or an issue with how you're triggering it. If the _DialogueManager_ code seems correct, it's possible that the raycast is hitting both objects at once - but of course, the _DialogueManager_ will only handle one of them. I imagine this would result in the issue that you described. In that case, I'd put some logging in the _DialogueTrigger_ script to see if both are getting called at the same time when you click. I hope that helps!
@@ShapedByRainStudios Thank you Sir, this was extremely helpul! The problem was that in my raycast I basically just ran the script if the raycast was tagged interactable so I ended up running every instance of that script in every NPC. If anyone else is having similar problem with their implementation I fixed this issue by putting "hit.collider.gameObject.GetComponent().GetRaycast();" if an interactable object was hit and added a new function named GetRaycast in the DialogueTrigger script where I ran "DialogueManager.GetInstance().EnterDialogueMode(inkJSON);" to run the function only in the raycast object. I'm not sure if this is the best, cleanest way to go about it but it worked and I learned something today 😂
Hey there! The InputManager is a custom Singleton class created to make interacting with Unity's new Input Manager a bit more convenient for this tutorial. You have a couple of options. I would recommend the second option if you don't know much about Unity's new input system. *Option 1 - Unity's new Input System (like I'm using in the video)* It's mentioned very briefly at 4:54 in the video. You'll need to set up a InputManager gameobject just like I show there with a (1) InputManager script and (2) Player Input component. You can get the InputManager script I'm using here - github.com/trevermock/ink-dialogue-system/blob/end-of-video/Assets/Scripts/Input/InputManager.cs You'll also need Unity's new InputSystem installed and configured for this to work. If you're not familiar with Unity's new Input System, here's an excellent video by Samyam that goes over setting it up - ruclips.net/video/yRI44aYLDQs/видео.html *Option 2 - Unity's old (default) Input System* If you're using Unity's default input system and/or don't want to bother with the above, you can simply replace any line where I call the InputManager with a line like the one below (the below example shows pressing the 'i' button). if (Input.GetKeyDown(KeyCode.I)) A list of keycodes to get different input can be found here - docs.unity3d.com/ScriptReference/KeyCode.html I hope that all helps! 🙂
Hello! Oh, I just didn't know about the new control system. I was also trying to adapt the script for 3D control. I ended up replacing everything with button activation, but it looks like I broke something... The dialogue wouldn't end until I left the cube collider space. Then I saw your message! That helped a lot. Now I'll just write the controls for the new system and hopefully everything will be fine)
Thanks for your great video. It really helps me a lot about how to designing the system, and I am going to experiment with UI toolkit. By the way, I have a question: at 27:26, to select the first choice, you said "event system requires it to be cleared first and the have the selected object be set". But in my own project, I try to directly set the first choice selected without select to null first, and it works just fine, so there is no need for coroutine in my case. So can you tell me why you said that? Note: my Unity version: 2022.2(Beta) Thanks again😊
Hey there and thank you for the kind words! Really glad you got use out of these videos! 🙂 As for that part at 27:26, if the issue isn't happening for you I wouldn't worry about it. It's happened to some and not to others, but I think it just comes down to a Unity version difference. TL;DR - if you don't see any issues you can ignore that part of the video. Hope that helps clear that up!
Hello really thank you for the tutorial . i was wondering what you said in 03:45 , is there an example , for example , putting all props description under 1 ink file (since having separate ink file for just one-three liner dialogue seems could get messy real fast if theres ton of objects in the scene)
Hey there! I don't have a concrete example anywhere, but I know a few others that have gone that route with only a couple modifications to this system. Here's one way you could go about it. With the below approach, you'd keep all of your dialogue in a single Ink file and use Ink Knot's to organize that file depending on the dialogue you want to happen for each dialogue trigger. 1 - Write all of your dialogue in a single Ink file organized into _'Knots'_ that should correspond to each dialogue trigger you want to use. 2 - In your DialogueManager script, you can load the entire Ink Story there rather than having it come from the DialogueTrigger script. 3 - In your DialogueTrigger script, instead of passing along an entire Ink Story to the DialogueManager EnterDialogueMode(..) method, pass along a string instead which represents the *knot name* for that specific triggers' dialogue. 4 - In your DialogueManager *_EnterDialogueMode(string knotName)_* method, call *_currentStory.ChoosePathString(knotName);_* to start your story from that specific knot. You can see more info about the _ChoosePathString(..)_ method in these docs (scroll to the "Jumping to a Particular Scene" section) - github.com/inkle/ink/blob/master/Documentation/RunningYourInk.md I hope that helps a bit! 🙂
I implemented this in my game. I like the Ink system, but I feel like having a singleton DialogueManager is a bit of an anti-pattern. I've been trying to come up with a better way using dependency injection, in keeping with your design of having reusable components.
Make sure besides having a RigidBody for the Player also the function ...OnTriggerEnter2D(Collider2D... is written with "2D" instead of "2d". It's a small mistake in the reference script i guess.
Does anyone know why the JSON file wont convert to text? I triple checked I have all the code correct and in unity. It logs the inkJSON.text but it does not show up in the DiolageText.
Hey there! Hmm, it might be a bit hard to figure out without seeing your project/code. I know you said you triple checked, but make sure you also check against the project code on Github if you haven't already. - github.com/trevermock/ink-dialogue-system/tree/2-choices-implemented/Assets/Scripts/Dialogue Here are some things that come to mind that you could try/quadruple check. 1. In the top left menu bar in Unity, you can go to 'Assets -> Rebuild Ink Library'. Make sure it builds without any errors to ensure that Ink is installed properly. 2. When you log the inkJSON text, are you doing it with _currentStory.Continue()_ ? If so, the dialogue line is getting removed when you do the log and then the story is empty when you actually try to set the dialogue text. Be sure to put _currentStory.Continue()_ into a variable and then log/use the variable. 3. Totally a shot in the dark, but have you closed and reopened Unity? Someone else was having some issues with Ink and they mentioned that things were working correctly after restarting Unity. Worth a try! I hope that helps! 🙂
This is a very helpfull tutorial, thank you very much! I would like to use the scroolwheel to select the buttons instead of W and A. Would you mind explaining how to achieve this?
I'm glad you found the tutorial helpful, thanks for the kind words! 🙂That should be possible, although I haven't tried this myself. The solution will likely depend on which Input System you're using. Here's a couple links I found that _might_ help get you started. If you're using Unity's new Input system like I am in these tutorials, this seemed like a pretty good video to get you started using a scroll wheel - ruclips.net/video/2kUaS-55atA/видео.html . If you're using Unity's old (default) Input System, upon first searching this it looks like a lot of the ways people are doing it is through code. With that said, I imagine that there's an easier way to do it where the Event System handles it, but without playing around with it myself I'm not sure how. Here's a link to someone who wrote a script that might act as a good starting point if you want to go the code route - answers.unity.com/questions/340772/how-to-use-the-mouse-wheel-to-switch-blocks.html . The 'blocks' being referred to could be switched out to select the choice buttons by code instead. The important bit from that link is how they're getting the scroll wheel axis information. You can use that information to write your own logic to select the buttons. I hope that helps a bit and best of luck getting that working! Again - please take the above recommendations with a grain of salt as I personally haven't worked with scroll wheel controls before.
@@ShapedByRainStudios Thank you very much for your answer, I greatly eppreciate that :) With your help I was able to implement the feature I wanted. Here is the code snippet I added in the Update Method: if(currentStory.currentChoices.Count > 0) { if(Input.mouseScrollDelta.y != 0) { currentSelectedChoice -= (int) Input.mouseScrollDelta.y; currentSelectedChoice = (currentSelectedChoice < 0) ? 0 : (currentSelectedChoice > currentStory.currentChoices.Count - 1) ? currentStory.currentChoices.Count - 1 : currentSelectedChoice; EventSystem.current.SetSelectedGameObject(choices[currentSelectedChoice].gameObject); } }
hi there! this is a really useful tutorial, thanks so much! i'm a super beginner and i encountered a problem i can't figure out - i'm at about 19:00 in the video, but when i test out getting the dialogue to show up, it pulls the dialogue panel up as intended, shows the first line of text, but then when you press continue it speeds through all my lines of text really fast and then immediately closes. do you have any tips for this, or have any idea what went wrong? :0 thanks again! (and sorry if this is a dumb question, i'm very new to unity! :) )
Hey there! This could be due to a lot of different things, but here are the first things I would try. 1 - How are you taking in input? Are you using Unity's default input system? If so, are you using Input.GetKeyDown(..) OR Input.GetKey(..)? Input.GetKeyDown() will only be true for a moment when the key is first pressed; however, Input.GetKey() will be true for as long as the key is held down. The latter would result in it blowing through the dialogue lines like you're seeing and is a really common mistake for beginners. 2 - Put some logging at the top of your ContinueStory() method - like Debug.Log("ContinueStory called") - so you can see every time it's getting called. It should only get called once every button press you do. I imagine it's getting called more for some reason though. From there, you can put more Debug.Log(..) statements around the code to try and figure out where things are going wrong. 3 - You can double check your DialogueManager code against the file on Github. This sounds like it's either something in your Update method or ContinueStory method, so I would start with double checking those. Here's the file at the end of this video - github.com/trevermock/ink-dialogue-system/blob/2-choices-implemented/Assets/Scripts/Dialogue/DialogueManager.cs I hope that helps! If you try those things and don't feel like it's getting you anywhere, feel free to comment back and we can try digging deeper. 🙂
@@ShapedByRainStudios omg thank you so so much, i was using "GetKey" instead of "GetKeyDown" just like you said lol! that was a super easy fix, thanks for getting back so quick, i appreciate the help! :D
I have a problem, hope you can help me with this For example when we choose the answer Charmander and it's not the correct answer so how can we go back and choose another answer for the question?
Hey! You can do that by modifying the Ink file for the dialogue. Replace _pokemon .ink_ with the below contents and it should do what you described, where Squirtle is the correct answer. Check out this video as well if you're interested in learning more about how the syntax works (if you haven't seen it already) - ruclips.net/video/KSRpcftVyKg/видео.html --- *pokemon .ink file contents below* --- -> main === main === Which pokemon do you choose? + [Charmander] -> incorrect("Charmander") + [Bulbasaur] -> incorrect("Bulbasaur") + [Squirtle] -> correct("Squirtle") === incorrect(pokemon) === You chose {pokemon}, but that wasn't correct. Try again. -> main === correct(pokemon) === You chose {pokemon}! That was correct! -> END
Thanks for the tutorial, its a complicated (for newbies like me at least), but clean way to show dialogues with NPCs. I only have a problem where the logic works perfectly, but the visual feedback of the choices when selected doesnt work at all. I tried with a lot of configurations over the button components but none of them show me when i select the option.😱
I'm glad you found it helpful! 🙂 That sounds like it could be that the 'Selected Color' needs to be changed (22:12 in the video for reference). Double check the alpha value of that color as well, which should be 100. Sometimes those default to an alpha value of 0. If that doesn't work, you could also play around with the other color values for the button if you haven't already. Especially the alpha values. Based on your comment though, it sounds like you might have already tried what I mentioned above. In that case, it could be worth downloading this project from Github, loading it up in Unity, and seeing if the issue still occurs. That'll at least help you narrow it down and also give you something to compare against. github.com/trevermock/ink-dialogue-system/tree/2-choices-implemented Best of luck and I hope that helps a bit!
FIXED! IDK what happened, but i re opened unity now and seems to be working with the exact same setup as earlier. Anyways, thank you a lot for the explanation! (you gained a sub)
when I transfer from one scene to another scene my dialogue is not working it provides an error called gameobject has been destroyed, what should I do?
Hey there, just checked out this video pretty recently and am a big fan of it. Followed it all the way through and it works pretty well. I have encountered one issue though at the end if you do see this. Basically the issue comes from the choice selection. It works so far where you can select and choose the pokemon, but after choosing a Pokemon the final text does not get displayed and the dialogue interaction ends early. How do I fix this?
Great video! But i had a problem. When I'd have multiple choices, I'd have to first click the choice with a mouse button and then I could proceed with my submit button later on. Is there any way to fix this? Can I make the OnClick() method be triggered by assigned button? I am not using the new input system.
Is it a good thing to write a storytellingManager class that holds all the dialogues init and all the "states" that has been switched in the game, for instance if you have succeed with quest , and already talked with X and Y and picked up item B etc and also handles all the Cutscenes etc ? should these dialogue be dialoguemanager then also or just normal classobjects with MonoBehaviour ?
Hey! I think there are lots of ways you could go about what you're describing. I think a StorytellingManager class is fine, but I would lean towards a normal class object that's controlled by the DialogueManager rather than a MonoBehaviour if you're just trying to keep state. Of course, it completely depends on your use case. I would do something similar to what I have in this video that goes over variable data persistence (which it looks like you've seen and I'll reply to you there in just a moment as well🙂) - ruclips.net/video/fA79neqH21s/видео.html I also just put out this video which covers using story.ToJson() and story.LoadJson() methods for a really simple save system which you might find as a useful reference for keeping story state. Skip ahead to the Save/Load timestamp - ruclips.net/video/HP1EYVwAhRg/видео.html&t I hope that helps!
Hey there! 🙂To my knowledge, Ink currently doesn't have direct support for localization. The last I checked, they recommend having separate Ink files for each language (which is definitely a big downside if you have a lot of dialogue). There are some other creative solutions people have done out there, but I'm personally not as knowledgeable on them. You'll find some threads and short articles on the subject if you search '_Ink localization_' on Google that might give you some ideas. I hope that helps!
this video has been a great help to me so far, I just have one question. I am near the end of the video, where you have just shown that you can now click on a choice, the problem is, I can't click or even highlight any choice, I am using both unity input systems, but have tailored this part of my project to the new one, if thats any help. I have an action in my control panel and code inside my input script for a mouse click, but I dont mind using the arrow keys like you have. i've also put everything into the inspector, like under the event system, and in the inputmanager inspector too. sorry if this didnt make much sense
Hey there, I'm glad the video has been helpful and I believe I understand. 🙂 Working with both Input Systems at once can definitely be a bit tough. It sounds like the issue is maybe related to having a 'first selected choice' in the event system as mentioned at around 26:46 in the video. That said, the Event System behaves differently depending on which input system you're using - which might be where you're running into an issue. It's really hard to say what could be going on. I would start by troubleshooting the 'first selected choice' coroutine code around that part of the video, putting in some Debug.Log() statements to ensure it's being called. With any luck, that might give you a lead as to what's happening (or not happening). If all else fails, I would recommend sticking with one input system over the other unless you have a good reason to need to use both. Others have gotten this Dialogue System working with Unity's old (default) input system with a few small modifications. If you want to go that route and are having trouble - let me know and I can try to give more specific guidance to do that. Best of luck! It definitely seems like a tricky issue!
@@ShapedByRainStudios interesting, I do feel like it might be to do with having both input systems, however it does work for the interact and submit button, just not the choices. I tried debugging the coroutine for firstselectedchoice, and it seems to be working, it comes up when i open up the text box. how would I go about only using the old unity input system? no worries if its too much to explain, but thank you anyway:)
@@ShapedByRainStudios it seems to be working now, i deleted the event system and readded without clicking the button that changes it to the new input system and it works, really not sure how but im glad its fixed! I appreciate your help and thanks for the tutorial:)
Thanks for watching! 🙂 There was a small bug with how choices are being made towards the end of the video. If you're experiencing odd behavior (dialogue closing instead of choice being made) then this might be the fix.
Thank you to @Baran for pointing out a solution to this. I wanted to pin a comment here so people don't have to dig through the other comments and piece things together to find the solution.
You can follow the below instructions - or watch the first part of this video where I go over the fix - ruclips.net/video/HP1EYVwAhRg/видео.html
*1.* In the MakeChoice method, add a call to 'ContinueStory()'.
public void MakeChoice(int choiceIndex)
{
story.ChooseChoiceIndex(choiceIndex);
*ContinueStory();*
}
*2.* Ensure that if there are choices, it's going through the MakeChoice method and NOT the Update method when you press a button. You can modify this if statement in your Update method to accomplish this.
// handle continuing to the next line in the dialogue when submit is pressed
if ( *currentStory.currentChoices.Count == 0 &&* InputManager.GetInstance().GetSubmitPressed())
{
ContinueStory();
}
*3.* If you're using the custom InputManager script that I'm using in the video. I modified it slightly and am now registering the button press in 'MakeChoice' so that way the input doesn't carry over. This is specific to how I'm handling input, so if you're not using that script you probably won't need to do this step.
public void MakeChoice(int choiceIndex)
{
story.ChooseChoiceIndex(choiceIndex);
*InputManager.GetInstance().RegisterSubmitPressed(); // this is specific to my InputManager script*
*ContinueStory();*
}
This has all been modified on the Github project in the DialogueManager script - github.com/trevermock/ink-dialogue-system/blob/2-choices-implemented/Assets/Scripts/Dialogue/DialogueManager.cs
I saw 20 people fork your project there was no need for them to do that
I had problems with it not executing the action and hollering about "choice out of range".
I had to look at the project's GitHub to figure out the problem. It was in the MakeChoice and the additional lines fixed the problem.
That aside, thanks for the tutorials! Good Job!
Just 2 minutes in but I already want to thank you for actually taking the effort to teach why you are using things instead of just showing what you do without any explanation why you are doing it like 90% of other videos. This is excellent.
Thanks so much for the kind words! I'm glad you found the video helpful! 🙂
I am also relieved you did this! Some other people just run right into the information without really any explanation. II also love that within the first few minutes of the video you are showing a common design pattern (singleton). I can't tell you how helpful it is to see a singleton outside of the classroom setting and in something im working with. thank you!
@@heartofthemountain9200 @Mark Doghramji thank you so much for the kind words! 🙂I'm really glad to hear all of that!
I was literally about to do the same thing. Even 2 yrs later this video continues to help ppl.
I was trying to do this a year ago and in the past few months all of these amazing tutorials come out. I'm glad people won't have to go through the annoying process I had to go through
Thanks so much for the kind words! 🙂 It's definitely a tough subject to find good info on, so I'm really glad people have been finding the videos useful!
I had an issue where the second line of the dialogue, is always the first shown. So here's my solution, if anyone else is struggling as well! x)
In the DialogueManager script, under EnterDialogueMode, remove the ContinueStory(); function, otherwise it will continue no matter what.
should look like this:
public void EnterDialogueMode(TextAsset inkJSON)
{
currentStory = new Story(inkJSON.text);
dialogueIsPlaying = true;
dialoguePanel.SetActive(true);
}
Anyways amazing video Trever, really helped me out! ✌(:
Thank you for the kind words and for sharing your problem/solution! That's much appreciated and I'm certain this will help some others! 🙂
Thanks for this solution! This fixed the issue when I'm making choices with one NPC. It was missing its first line of text. However, now when I talk to an NPC with normal dialogue and no choices, the first dialogue is just a blank panel before it starts the actual text 🤔
@@discipleofmana same here, trying to make a fix ;-;
Edit: Found a fix! When you delete ContinueStory(), replace it with dialogueText.Text = currentStory.currentText. Hope it helps!
@@munch8399 Thx for helping out - Doesn't seem to work for me :(
Thanks Bro
love your way of teaching!! very concise and well-explained:)
i just discovered ink a few days ago and your videos were such a great introduction to using it !! thank you! really excited to see future content:) 🌼
Thank you so much for the kind words! That means a lot and I'm really glad you found the tutorials helpful! 🙂
I used scriptable objects, xml, json and almost cancelled my project. But you saved me. Thanks a lot. Will thank you in out project. Thanks again.
THis was littarly a month ago. Consistant tutorials of every topic in game dev!👍👍😀
Appreciate it! 🙂
As a 12 year old trying to make a dialouge system in unity this is perfect tutorial understood everything
Right on! I'm really glad to hear that! 🙂
Not only is an useful feature, also I learn how to improve my Unity programming. Thanks a lot!
For optimization, it may be better to have the player object check for npcs in *his* range instead of a million NPCs all spherecasting for the player in *their* range.
Yes, I was screaming in my head when I saw he was checking if player was in range for every frame.
Wait woah, I was looking for a tutorial as in depth as this a while back! Thanks!
Really great video! Finally found a tutorial for a dialogue system that gives me good groundwork to scale and change the system as my game grows. Thanks!!
Really glad to hear you found it helpful and thank you for the kind words! 🙂
Fucking gold, man. Most of the top search results on the subject aren't very good, but this guide is just... chef's kiss!
Thanks so much for the kind words! I'm really glad you found it helpful! 🙂
This is an incredible tutorial. Helped me immensly - thank you so much!
I usually don't comment on youtube, but i really wanted to say thank you for making this, it helped me A LOT, i hope you have a wonderful year.👍
I really appreciate the kind words - that means a lot! I'm glad this helped and I hope you have a wonderful year as well! 🙂
This series has been immensely helpful, thanks! I just left a comment about memoizing the playlist but apparently I Just missed it earlier because it's in the description. Sooo yeah I have no notes! thanks again and please keep teaching.
Man, thanks so much for this. I rarely see tutorials with great code that actually follows OOP methods and rules. The way you explain everything is also great.
Hey, this tutorials saved my project, super recommended!
This is my favorite video on the internet right now.
Haha, really glad to hear you're finding it to be useful! 🙂
@@ShapedByRainStudios I do have a probably dumb question though. How do I make the dialog choices disappear after choosing one?? They stick around after I answer the only correct answer, Charmander of course.
@@GeraldClarkAudio Hey there! 🙂 The code at around 25:17 in the video _should_ disable all of the choice buttons when there are no choices. If the choice buttons are sticking around after choosing one, there's a good chance something is going wrong within that method.
I would start with double checking your DisplayChoices() code, as that bit can be tricky to code up and it's easy to make a mistake even when following along to the video.
If that looks correct, I would put some Debug.Log() statements in the DisplayChoices method to make sure it's getting called as you'd expect as well as in the MakeChoice() method to make sure that's also getting called as you'd expect when a choice is made.
Hopefully through putting some Debug.Log() statements in there you'll be able to work your way backwards to figure out the issue.
It can also help to check the code against the DialogueManager.cs file on the Github project for this video which can be found here - github.com/trevermock/ink-dialogue-system/blob/2-choices-implemented/Assets/Scripts/Dialogue/DialogueManager.cs
I hope that helps a bit!
@@ShapedByRainStudios Thanks. I'll give it a whirl. I've set up something in my game where there is a question, then choices, then a question once one of those choices is selected. The new choices appear, but then when they are chosen they dont go away. Even after I've progressed through the rest of the dialog. I havent taken a lot of time to check with Debug.Logs. Thats the next step. Thanks again!
@@GeraldClarkAudio No problem! It's possible it could be how your Ink file is set up as well. You could plug it in to the project that's on Github to try and verify if that's the case or not.
Best of luck and feel free to stop by my Discord server if you hit a block with troubleshooting this and we can dig deeper! 🙂
Such a cool and comprehensive tutorial. Thank you for making videos like this, I learned a lot and it was easy to follow.
I'm glad to hear! 🙂
Thank you for this!! I'm making a mobile game for a project in my university and this helped me a lot!!!
You're welcome! 🙂 I'm glad it helped!
Wow this really makes me thankful for the Dreams engine. The way my mind works I just wouldn't be able to keep all those codes stored in my brain. I used to make web pages but I would copy and paste the codes and I could edit it a little bit but I couldn't do I think it was ccs, but java was simple enough I could remember. You must have the most wrinkly of big brains!
Haha, you get use to it after awhile and you also get really good at Googling things! 😅
The Dreams engine looks really interesting. I've been meaning to check it out to see how it works! 🙂
@@ShapedByRainStudios the hardest part is getting used to the controls but after that it's very simple wired connections to gadgets that do different things. It's basically Little Big planet on steroids that are also on steroids 😆
Amazingly simple way to add dialogue with choices, thank you very much!
No problem! Glad you found it helpful! 🙂
Absolutely fantastic video, easy to follow
I also appreciate how easy it was to modify the script for my purposes, while still keeping the ink-based system intact. Thanks!
No problem! I'm really glad to hear that! 🙂
probably the best tutorial i've found for a dialogue system. keep up the good work!
Only issue I'm having right now is, when I use the selection button on my keyboard, it ends the dialogue instantly. But when I use my mouse to click the dialogue option, the dialogue will continue like normal.
Hey there! Thanks so much for the kind words! 🙂
Are you using Unity's old (default) input system by chance? If so, are you using Input.GetKeyDown() or Input.GetKey()? Make sure you're using Input.GetKeyDown() - as that will be true for only the frame it's pressed. Input.GetKey() will be true for as long as the key is down - which would cause it to blow through all of the dialogue pretty quickly. That's just a guess though based on some common issues others have had.
If that's not the case, it could also be related to a race condition bug found which I go over in the first timestamp of this video (if you haven't already seen it) - ruclips.net/video/HP1EYVwAhRg/видео.html&t
If neither of those seem to be it, then I would recommend putting Debug.Log() statements in and around the ContinueStory() method to see if it's getting called how you'd expect. That'll at least hopefully help you narrow it down a bit.
I hope one of those things helps!
i LOVE the way you think and translate that into a graphic and then into code :) incredible tutorial
Thank you for the kind words! I'm really glad you found the video helpful! 🙂
Hey dude, great video! This is definetly the best tutorial there is! It worked perfectly, thank you very much!
Thank you for the kind words! I'm glad you found it to be helpful! 🙂
Another awesome video dude! ill be doing the portraits one next!
Really glad to hear! I hope you find that one helpful as well! 🙂
Thanks for the very useful tutorials man, you got my sub for sure, gonna watch all your tutorials right now!
No problem and thank you for the kind words! I hope you find the other tutorials just as useful! 🙂
I had a similar problem when exiting the dialog as you had (my character did shoot because it was the same Button).
I fixed it by using ButtonDown for Shooting but ButtonUp for ContinueDialog.
That might be a bit of a cleaner way solve the problem. With the coroutine you always have that tiny sliver of time at the end of the dialog where you can't use the function.
That probably makes a bigger difference in my case, but I thought I mention it here if someone else wants to get around the problem.
PS: That was a great tutorial!
Didn't know about InK. Thanks!
Really like your input manager design!
Glad to hear! It's definitely convenient! 🙂
this is a great tutorial to get the idea of dialogue system. for everyone who isnt using the new input system maybe this could help you.
to choose one of the choice you can add this line to your dialogue manager
private IEnumerator SelectFirstChoice()
{
// Get the first choice component that inherits from UnityEngine.UI.Selectable
UnityEngine.UI.Selectable firstChoice = choices[0].GetComponent();
// Set the first choice as selected
firstChoice.Select();
// Wait for spacebar to be pressed
while (true)
{
if (Input.GetKeyDown(KeyCode.Space))
{
// Do something when spacebar is pressed
Debug.Log("Spacebar was pressed!");
break;
}
yield return null;
}
// Return a value at the end of the method
yield return null;
}
public void MakeChoice(int choiceIndex)
{
currentStory.ChooseChoiceIndex(choiceIndex);
ContinueStory();
}
This is amazing ! Thank you so much for the video!
You're welcome and thank you for the kind words! 🙂
Thanks dude this really helped me a lot I did the steps that's you did thanks man!
OMG! I love you thaks for your tutorial!
Thank you! This helped me a lot!
No problem! I'm really glad to hear! 🙂
yo bro, really thankya. Big respect
Thank you so much for this video! It was exactly what I needed and so well explained too. I already subscribed and I really hope more people find your channel soon. I just ran into one problem when creating another NPC: The dialogue box closed on its own as soon as I talked to them (they only had one line of dialogue) when I tested out adding a second line, it didn't close on it's own anymore but skipped the first line altogether. I'm not sure why this only happened with my second NPC? Thank you so much for the video again!
Thanks so much for the kind words! 🙂
Hmm, that’s definitely strange that you’re only seeing it on another NPC.
First, I’d double check your DialogueManager script against this file on GitHub (if you haven’t already) to make sure there aren’t any key differences - github.com/trevermock/ink-dialogue-system/blob/choices-implemented/Assets/Scripts/Dialogue/DialogueManager.cs
Triple check the ‘ContinueStory’ method, since this sounds like it might be an issue with how the story is being continued.
If all of that looks good, it’s hard to say what could be going on - but it sounds like you might be able to narrow the issue down by comparing the two NPCs since one of them is working. If they both look the same, that might point to something being wrong in the DialogueTrigger script, so I’d double check that one against the one on GitHub next.
I hope you’re able to figure it out and I hope that helps a bit!
I have the same issue of the 2nd NPC skipping the first line of text. Were you able to fix it?
hey, im having the same issue.. have you figured out a fix for this?
EDIT: i literally saved my project, opened it back up again, and it worked fine haha
Well explained! Thank you!
Amazing tutorial!
Hi, loving this series of tutorials, they’ve been really helpful with a project I’ve started working on, do you know if there is a way to allow a player to select the choice buttons with a mouse as well as the game pad/keyboard? I’ve been able to highlight the choices with the cursor but it won’t select a choice to be picked. Thanks and keep up the good work!
Hey there! Thanks so much for the kind words! 🙂
Yes, that should be doable. I'm not as familiar with using mouse clicks myself, but it might have to do with how your Event System is configured. I would start troubleshooting there and work your way out.
If you're using Unity's new Input System like I did in this video, you'll want to add a MouseClick option to your Input Action Asset in addition to whatever you're using as a submit button.
With Unity's old (default) Input System, it might be something you need to configure in Project Settings (Edit -> Project Settings -> Input Manager).
Of course - it could be something completely different than those suggestions, but those are the first things that come to mind. I hope that helps!
Hi, did you manage to solve this problem?
Hi, did manage solve ? I still waiting this problem. I really new to Unity 😅
btw great video!
This is really useful. Thanks!
No problem! Glad you found it useful! 🙂
@@ShapedByRainStudios would you consider making a Discord? I would love to join your community! 😊
That's awesome and I really appreciate that! 🙂
I would like to get a Discord set up at some point; however, I'm not sure how soon that'll be. Keep an eye out in the coming months! 😁
thank you for this series but 1 vote for no music in the future from me. gonna have that loop in my head for weeks lol.
Glad you enjoyed the series and thanks for the feedback! I've come to realize this myself and I'm taking a different approach to the background music for future videos, haha. 😁
Great video thank you!
You're welcome! I'm glad you found the video helpful! 🙂
Amazing guide even for beginners! I have a problem encountered while following through, so I am using the old input system and set my interaction to be (Input.GetKeyDown(KeyCode.E)), everything works fine and well however I cannot exit the dialogue as it loops back from the beginning and the player is unable to move.
Really glad to hear you found the video helpful! 🙂Here are my thoughts on what might be happening - but keep in mind it could be something else.
What I imagine is happening here is that when the dialog ends, that same button press used to end the dialog is starting the dialog back up. If that's the case, there are a couple ways you could go about it off the top of my head.
*1 - Manage your Input in a separate class and ensure a button press can only be registered once per frame.*
This is actually really similar to how I have the InputManager class set up in the video. Of course, I'm using Unity's new input system; however, you could do something very similar with Unity's default Input System.
See how the 'RegisterSubmitButtonPressed()' method works in this class for an example - github.com/trevermock/ink-dialogue-system/blob/7-dialogue-audio-implemented/Assets/Scripts/Input/InputManager.cs
The idea here is that you'd use a separate boolean to micro-manage the players input so that the input can't happen twice in the same frame.
*2 - Add a bit of wait time before the dialog closes*
A more quick and dirty fix, which I think will work fine for most games, would be to put a bit of delay between closing the dialog and being able to start a new dialog.
I believe this should be as simple as exiting dialogue in a Coroutine, waiting until the next frame or some small amount of time when dialogue is exited, and then setting dialogueIsPlaying=false only after that time has been waited.
That said, it's been a little while since I've touched the system built in these videos so I'm not sure if there's a bit more to it then that.
I hope that at least helps you get started with fixing that issue! Best of luck!
@@ShapedByRainStudios Thank You! Will try this when I finish up work today
Great tutorial. Thank you
thank you!!! video liked and u got a well deserved sub from me!!!!
I would love to see a video of you teaching us how to make the singleton you use for the player inputs. (:
Thank you for the suggestion! You're not the first to request that, so I'll definitely be keeping that in mind for future videos! 🙂
Hello! This was extremely helpful, I was struggling with ink so I appreciate this video a ton!
I have a question, how would you go around getting a variable from ink to be used in another script in unity? I was trying to read ink's documentation but I was having problems with it. Thanks!
I'm glad you found it helpful! 🙂
I played around with this a bit and found two ways that worked for me.
*First way - Variable State*
You can use the below line (where currentStory is a 'Story' object) to access a variables current state in the story.
_currentStory.variablesState.GetVariableWithName("pokemonName")_
One thing I noticed with this is that the State won't actually change until after the current line has been Continued in the story. So imagine the below Ink file:
_VAR pokemonName = ""_
_First line of text_
_~ pokemonName = "Charmander"_
_Second line of text_
_Third line of text_
In that example, if you try to access the pokemon name before the 'Second line of Text' has been 'Continued', it won't be updated yet. So really, you won't see the change until you're on the 'Third line of text'.
*Second way - Variable Observer*
You basically create a 'listener' function that will fire off whenever a specified variable changes. It'd be ideal to put this in a 'Start' method somewhere; however, if following the example in the video you could put this in the 'EnterDialogueMode' function and it should work just fine.
_// make sure the variable name exists before creating a listener_
_if (currentStory.variablesState.GlobalVariableExistsWithName("pokemonName"))_
_{_
_// create a 'listener' that will fire whenever that variable changes in the story_
_currentStory.ObserveVariable("pokemonName", (string variableName, object newValue) => {_
_// do something once the variable changes_
_Debug.Log(newValue);_
_});_
_}_
Then, you can remove the Observer in the 'ExitDialogueMode' method (or wherever you're doing clean up stuff) with the below line.
_currentStory.RemoveVariableObserver(null, "pokemonName");_
I hope that helps!
ayo where's da popularity at my guy
This video is fantastic! Thank you so much for the clear and concise explanations for everything. I wonder, would you happen to have a method for setting character sprite/portraits to change along with each line of dialogue on the dialogue panel? For example, setting a happy portrait to go along with a happy dialogue and then switching to a more neutral portrait on the next line. I'll need to look into it, but I imagine it would involve setting some tag within the ink file/JSON and parsing it somehow?
Edit: Actually, I just saw you have another video addressing this exact question, I plan to check it out next!!
Thanks so much for the kind words! It sounds like that other video is exactly what you're looking for. I hope you find it just as helpful! 🙂
Nice video
The system detect if the word is too long for jump automatically to the next line before write the characters?
Thank you! 🙂 Yes, words will automatically jump to the next line once the text has reached the end of the TextMeshPro boundary (the yellow border I mention at 13:17 in the video determines this).
Really good video!!!! Thxx
So i need some help here, basically i followed your tutorial but I’m using the old input system of unit, there were no error showing up in the code so I thought it would appear, but when I pressed play and tried interacting with the object nothing showed up.
OMG, thank you!!!! 3 3
This was an awesome video which I will DEFINITELY reference too when making the dialog system for my game. I have one question though. How could we make it so that the options have a short version of our dialog option, but then display a the full length dialog on the speech bubble?
Great video Trever, really clear explanation!
I got one quick design question. I'm trying to change the singleton design to the event driven design. I presume the idea is to trigger the dialogue event in the NPC and send the inkJSON file to the DialoguePanel so that it manages the display of the file.
Would you send the file to all the possible listeners which probably won't use it or would you send the file especifically to the DialoguePanel? The latter makes more sense but I can't figure out how to do it without creating a dependency between the NPC and the Dialogue Panel.
Thanks again for the video!
Hey! Great question and I'm glad you found the video helpful!
The InkJSON file would go to all possible listeners for that *specific type of event* ; however, you would set up the *DialoguePanel* as the *only listener* for that type of event. Your DialoguePanel would now be dependent on that type of event rather than the NPC. It's a bit strange to think about, but it is quite different from being dependent on the NPC like in the Singleton pattern.
I highly recommend checking out this short, but concise video by *Game Dev Guide* on setting up an event driven design pattern. It's an excellent introduction to doing Event Driven Design in Unity. - ruclips.net/video/gx0Lt4tCDE0/видео.html
In that video, you can think of *TriggerArea.cs* as *DialogueTrigger.cs* and *DoorController.cs* as the *DialogueManager or DialoguePanel* scripts (depending on how you have things set up.). Creating the *GameEvents.cs* script is optional; however, it's a great way to organize your events and I would recommend doing that as well.
*In short*
1 - The DialogueTrigger script will *publish* an event with the InkJSON instead of calling EnterDialogueMode().
2 - The DialogueManager/DialoguePanel will *subscribe* to and listen for those types of events. When an event of that type is received, it'll use the InkJSON for that event to display dialogue information accordingly.
3 - Create a GameEvents script to better organize and manage your events.
I hope this helps! 🙂
@@ShapedByRainStudios Thanks for all the info! The Game Dev Guide video was great but my system is working with Scriptable Objects and I found it kinda different to get my way around the problem.
I found a great video of Nathan (Dapper Dino) that solves the problem:
ruclips.net/video/iXNwWpG7EhM/видео.html
Thanks again!
can you please make a video on how you made the your input system please
Great video! Really loved how you explained it all thank you!!
I wanted to ask, could something like this be implemented for a text-adventure game? One where you just click/select choices and that progresses the story, with a still background and some sound effects. I know you mentioned in the intro that more narrative-focused games would benefit from a single ink file. Any help would be appreciated, thank you!
Thank you for the kind words! 🙂 Yeah, this system should work just fine for a text-adventure game like you described.
What it really comes down to is how self-contained you want each section of dialogue to be. If there's a lot of cause/effect between dialogue (a choice you make in one story directly effects other stories) it might be a bit easier to do in a single story for the entire project. That would allow Ink to keep track of the state of everything (which it does automatically) rather than having to keep track of state in C# code between different stories.
I'm actually working on a video right now that will go over how to keep track of variable state between multiple stories which will hopefully be out by next week. So if you go the multiple stories route, be sure to keep an eye out for that!
If you wanted to go the single story route, you can do so with this system by making a few small changes. The idea here is that each Knot is self-contained for that piece of the story. Then, you'd navigate to a specific Knot for each click/select.
*1* - Write your dialogue in a single Ink story. This can be multiple Ink files using INCLUDE statements for organization. As you're writing your story, separate each 'click/select' dialogue into different Knots.
*2* - Initialize the single Ink story in the DialogueManager (Awake or Start method) instead of in the DialogueTrigger scripts.
*3* - In your DialogueTrigger scripts, send a string _knotName_ to the DialogueManager instead of an inkJSON file. The Knot name should correspond with the click/select the DialogueTrigger is attached to.
*4* - In the DialogueManager EnterDialogueMode method, call *currentStory.ChoosePathString(knotName)* which will take you directly to that knot in the story.
Again though, this comes down to preference more than anything else. Do you want to manage multiple small stories or a single large story? They both have their pros and cons. If you're not sure, I'd just start with multiple stories like in this video and then switch over to a single one if you feel the need to. I hope that helps!
@@ShapedByRainStudios Thank you so so much for this, I really appreciate it! Looking forward to that video! I'll start working on it with what you suggested. Thank you once again!
Hi, I’m not sure if you answer this in another video, but how do you switch between regular dialogue and choice dialogue using the inkJSON?
Like what if there is a file that has regular dialogue, then it asks you a question that you have a few options to choose between? How do you write code that checks for that in order to switch between the UI?
Hi this is such a good set of videos. have you got an outline of what would need to be altered to adapt it for a 3d space please?
Hey there! I'm glad you've found the videos helpful! 🙂 Off the top of my head, the only difference between 2D and 3D for these tutorials should be how the DialogueTrigger class detects the player.
In 2D, we used OnTriggerEnter2D/OnTriggerExit2D to detect if the player is in range (around 9:53 in the video).
In 3D, you'll instead use the corresponding 3D methods OnTriggerEnter/OnTriggerExit. More details on the Enter method can be seen here (should be easy to find the Exit method docs through Google if needed) - docs.unity3d.com/ScriptReference/Collider.OnTriggerEnter.html
Hopefully that helps and best of luck!
Thank you so much!
Hi! I know that this is two years old and the tutorials have been very helpful but I'm running into this issue where when one of the choices is the end of the dialogue and should close but its coming up with a blank before closing? It's like trying to load dialogue that doesn't exist before closing.
eg: [No Comment] -> END
This comes up as just a blank before closing instead of just closing the dialogue. Is there a fix for this? Thanks!
Hey! Really glad you've found these tutorials to be helpful! :)
I imagine you're hitting a similar case to what happens when an external function is used at the end of dialog. See the timestamp "8:58 External Functions at the end of the dialogue" in this video - ruclips.net/video/dwxu4Q-GJU0/видео.html
I believe that will solve the issue you're running into. I hope that helps and best of luck!
@@ShapedByRainStudios it worked! I just had to put it into the choice function for it to work properly but thank you!
thank you for a nice tutorial. one question though: is it possible to use input.getkeydown(button) to trigger the whole dialogue instead of using the new input system? will it work that way aswell?
edit: I just saw you answered this in another comment. thanks!
You're welcome! 🙂
Yeah, like you saw mentioned in that other comment, the old input system should work just fine.
@@ShapedByRainStudios btw, in that case, in the choices part, we can skip the event system reference in script and just use the button event in each button to reference the number of choice when button is pressed?
I think you'll still need to reference the Event System in the DialogueManager script for that first selected choice. And yeah, you should be able to assign onClick functions for the buttons just like in the video.
With all of that said, I haven't had time to try this myself with the older input system, so there could be some other hurdles or oddities I'm not thinking of. If you end up having trouble, let me know and I'll set aside some time to dig into it a bit more! 🙂
Thanks for this! great tutorial that helped me get very far and have a clear understanding!
I do have a question that I hope you can help me with (or someone else here?): In a specific moment I would want to have an input field instead of a choice. My idea was to pass the information typed in the field as a global variable in Ink, and depending on the value, the story will continue one way or another.
I managed to get the UI appear/hide and get the information in Unity but for some reason I do not manage to get the variable pushed to the story. Any idea how I could get this done?
Hello there, I have a problem with this, after you made your choices appear, that’s where I’m currently stuck at,
The problem:
The choices aren’t appearing correctly, and it’s only one that appears without the actual text as well, I have checked and compared the code and I can say for sure that it’s the same as the GitHub code, at the current stage of course,
Another thing I did was use a different ink file set up they ways yours was set up in the video. Unfortunately that didn’t work either.
There is also an error message that pops up:
NullReferenceException: Object reference not set to an instance of an object
The area where this error leads to is in the Dialogue Manager script in the DisplayChoices() function inside the Foreach loop where I think we are trying to set the choicesText[index].text = choice.text;
I would appreciate it if someone could tell me where I’m going wrong
Hi.Your video is so amazing!
Thank you! I'm glad you found it useful! 🙂
Great video! I am having an issue that when using your input manager script, when I try and enter dialogue a second time with the same NPC, it will not register my initial input to start a conversation (I have a multi-path dialogue system that was working without the input manager system you're using, but I couldn't figure out how to "select" the buttons appropriately without using your method). Not sure if that's an issue you've encountered, might be something on my end I messed up with the Input Event System, but if you have any recommendations that would be greatly appreciated :)
Hi Trever! Thanks for teach us a working and easy to manage dialogue system. This work wonderfully on pc by using sumbit and arrow button. But I wonder, is there is a way to make the button can be clicked using mouse cursor?
Hey there and thanks so much for the kind words! There's definitely a way to make the button clickable by a mouse cursor, but it can depend on what Input System you're using. I personally haven't done a lot of 'mouse click' input myself, so my best recommendation is learning a bit more about whichever Input System you're using and how it works for mouse clicks. I hope that helps and best of luck to you!
Hey there Trever!
The tutorial is great so far, but my game doesn't seem to be registering that the Interact button is pressed (I set it to E). I've gotten all the way to 19:00 and set up all the scripts as well as the player interaction system and still can't seem to get it to work. The box collider detector works, it's just that the canvas and panel aren't popping up when interacting.
I know this could be a variety of issues, but I was just looking for a bit of help to at least find out where this is coming from!
I've also determined (using Debug.Log) that it is my input manager script that is not receiving a player interaction trigger
Fixed!
@@la-clique How did you fix it?
Great tutorial!
How do we have choices impact the gameplay and not just the dialogue? (ie. play with the chosen Pokemon).
I'm glad you found it helpful! I might do a future video covering this, but until then - here's a couple ways you could go about it.
You can feed variable state to/from the Ink story using *story.variablesState.GetVariableWithName("pokemon");* and *story.variablesState.SetGlobal("pokemon", pokemon);* . The second parameter in SetGlobal ('pokemon') is a _Ink.Runtime.Object_ type which would be used to store and access the value on the C# side.
I have a detailed explanation on how to initially set this up on Discord under the _Unity_ channel if you want to check that out - discord.gg/99gcnaHFf9
*OR*
Alternatively , you could also use _Ink Tags_ to pass metadata to your C# code. I cover setting that up in this video if you haven't seen it - ruclips.net/video/tVrxeUIEV9E/видео.html
I hope that helps! 🙂
@@ShapedByRainStudios Thank you!
I know the video is old but maybe somoene can still help me! Whenever The Dialogue Ends (in the Ink file i say -> End) in the game it still displays one more empty panel (without text or buttons). Then the Player needs to Click again to close it. Thats really weird and i have no idea where this issue could come from.
Hey there! 🙂Here's some troubleshooting steps though that we can use to narrow the issue down in the code.
1 - Put some Debug.Log() statements in and around the ContinueStory() method. Ensure it's getting called exactly how you'd expect it to when you continue the dialogue.
2 - When calling currentStory.continue() method, is there a last line that's coming out as blank? This might help you determine if it's something to do with your Ink file; however, with what you mentioned already, I think this seems unlikely.
3 - Put some Debug.Log() statements in your ExitDialogueMode() method. Is this getting called before or after that empty panel shows up? That might help you narrow down if it's something with your ExitDialogueMode() method or not. Since this is happening at the end of the dialogue, it's possible something is going wrong here.
4 - It could also be worth checking your code against the Github project to see if anything seems off. The code can be found here for this tutorial - github.com/trevermock/ink-dialogue-system/tree/2-choices-implemented/Assets/Scripts/Dialogue
I hope that helps a bit! If you're still stumped on this after going through the above steps, then let me know the results of anything you found and we can try to go from there.
@@ShapedByRainStudios Thank you alot!!! i didnt even expect such a good awnser to my Question.
It worked until I tried to confirm a choice. For some reason my buttons only work if you click on them, no way to confirm a choice with the keyboard, and yet I can navigate through choices. How can I make that you can press a button with the keyboard?
Hey there! Assuming you have the code set up to register button presses, usually issues like this are due to something in the Event System not being configured correctly.
The first thing I would do is check your Event System button mappings to ensure your Submit button is correctly mapped. This will look a bit different depending on if you're using Unity's new Input System (like I am in the video) or Unity's old/default Input System. For reference, see around 13:50 in the video where I switch the component to be compatible with the new input system. I know of a couple others who have had issues with it not defaulting the submit button correctly in the Event System, so there's a good chance that's it.
If those mappings look correct, the next troubleshooting step I recommend is to double check your Input System button mappings. For Unity's new Input System, this will be in the Input Actions Asset. For Unity's old/default Input System, these will be under Edit -> Project Settings -> Input Manager (top left menu of Unity).
In addition to the above - a good troubleshooting step would be to try and print out some logging in a script when your submit button is pressed. That'll help you figure out if it's an Input issue (which is what it sounds like) OR potentially an issue specifically with your choice buttons. If it's the latter, you'll want to make sure your OnClick function for each Choice button is correctly hooked up to the MakeChoice() function.
Hopefully that helps and best of luck! 🙂
Is there any tutorial video for the input manager? kinda stuck on it
great video anyway
I don't have a video specifically on the Input Manager used, but there is an excellent video by Samyam I've been recommending which goes over Unity's new Input System in detail that might help. It can be found here - ruclips.net/video/m5WsmlEOFiA/видео.html
Or if you don't want to deal with Unity's new Input System at all, everything in this tutorial should work with Unity's old (default) input system if you replace those calls appropriately. There are some responses I've made to other comments with more details on how to go about this if that route interests you.
Appreciate the kind words and best of luck! 🙂
Thank you so much!! this video is really helpful. How can I make the choice buttons show up when I press submit button once again after seeing the line?
Great video, I have a problem where the player presses the movement keys and talks to the NPC at the same time, the character continues moving.
i'm having a problem with "using Ink.Runtime", apparently unity doesn't recognize Ink as namespace
solved by moving STORY script in scripts folder
@@francescoruggeri933 I'm glad you figured it out and thank you for sharing your solution as well! 🙂
Hi Trevor. Thank you for this amazing tutorial. I was able to add a Typewritting effect to the Dialogue System, but when typing a word using bold or color the Rich Text appear briefly on the dialogue box.
Also, when the word is being written on the edge of the dialogue box and it runs out of space, the entire word disappears and appears on the next line. I saw you managed to avoid this 2 issues in your game (that looks fantastic by the way). Could you please give me a little guide on how to achieve it?
A tutorial on how to do this would also be great as a follow-up to this one. Thank you very much!
You're welcome! 🙂
For your first issue with the Rich Text appearing in the dialogue box, you'll need to account for that when adding letters for the typewritter effect. The below Coroutine is close to what I'm using in my game and should do the trick.
Note that if you're using '' symbols as part of your dialogue text that aren't intended to be tags, then you'll have to handle this differently.
private IEnumerator DisplayLine(string line)
{
bool isAddingRichTextTag = false;
foreach (char letter in line.ToCharArray())
{
if (letter == '')
{
isAddingRichTextTag = false;
}
}
else
{
dialogueTextDisplay.text += letter;
yield return new WaitForSeconds(typingSpeed);
}
}
}
In that Coroutine, once we hit a Rich Text Tag, it'll put out the whole tag without waiting, and then go back to doing each letter. When it puts out the whole tag like that, it won't appear in the TextMeshPro text and the following text will be colored. Of course, this will do the same for the end of the tag as well.
As for your other issue with text going to the next line - I believe the text in my game also does that. The clips in this video happened to be cases where the words line up with the dialogue frames length.
If you really wanted to, you could come up with an algorithm to detect when a words width will exceed the current frame and then insert a newline character in those cases so the word shows up on the next line - but that's definitely more than I'd be able to get into in a RUclips comment.
I hope all that helps!
@@ShapedByRainStudios Thank you SO MUCH for your quick and awesome response. Where we can see updates about your game?
By the way. The Coroutine worked perfectly fine. Thanks!
@@rubpty No problem! 😁 I post updates roughly 2-3 times a week on both Twitter and Instagram! Both are @trevermock (links in description of the video).
Hi! First of all this is an awesome tutorial, thank you very much for doing this.
I used this tutorial in a visual novel type setup where the dialogue is started with a simple raycast to mouseclick and it worked perfectly but I can't get multiple dialogues to work on separate NPCs, it just starts the same one. I assume the problem is with how the script picks the textfile, would you have a suggestion of where I should start troubleshooting? 😄
I'm glad you found the tutorial helpful! 🙂
Hmm. I'd start by looking at the _EnterDialogueMode_ method in the _DialogueManager_ . Maybe put some log statements in there to make sure it's getting called like you think it is.
You could also play around with setting the currentStory to null in the _ExitDialogueMode_ method. That'll make sure the 'older' currentStory isn't still set when new dialogue is triggered and might help you narrow down if this is an issue with the _DialogueManager_ or an issue with how you're triggering it.
If the _DialogueManager_ code seems correct, it's possible that the raycast is hitting both objects at once - but of course, the _DialogueManager_ will only handle one of them. I imagine this would result in the issue that you described. In that case, I'd put some logging in the _DialogueTrigger_ script to see if both are getting called at the same time when you click.
I hope that helps!
@@ShapedByRainStudios Thank you Sir, this was extremely helpul! The problem was that in my raycast I basically just ran the script if the raycast was tagged interactable so I ended up running every instance of that script in every NPC.
If anyone else is having similar problem with their implementation I fixed this issue by putting "hit.collider.gameObject.GetComponent().GetRaycast();" if an interactable object was hit and added a new function named GetRaycast in the DialogueTrigger script where I ran "DialogueManager.GetInstance().EnterDialogueMode(inkJSON);" to run the function only in the raycast object. I'm not sure if this is the best, cleanest way to go about it but it worked and I learned something today 😂
18:07 Assets\Scripts\Dialogs\DialogueManager.cs(48,13): error CS0103: The name 'InputManager' does not exist in the current context. What is this (((
Hey there! The InputManager is a custom Singleton class created to make interacting with Unity's new Input Manager a bit more convenient for this tutorial. You have a couple of options. I would recommend the second option if you don't know much about Unity's new input system.
*Option 1 - Unity's new Input System (like I'm using in the video)*
It's mentioned very briefly at 4:54 in the video. You'll need to set up a InputManager gameobject just like I show there with a (1) InputManager script and (2) Player Input component.
You can get the InputManager script I'm using here - github.com/trevermock/ink-dialogue-system/blob/end-of-video/Assets/Scripts/Input/InputManager.cs
You'll also need Unity's new InputSystem installed and configured for this to work. If you're not familiar with Unity's new Input System, here's an excellent video by Samyam that goes over setting it up - ruclips.net/video/yRI44aYLDQs/видео.html
*Option 2 - Unity's old (default) Input System*
If you're using Unity's default input system and/or don't want to bother with the above, you can simply replace any line where I call the InputManager with a line like the one below (the below example shows pressing the 'i' button).
if (Input.GetKeyDown(KeyCode.I))
A list of keycodes to get different input can be found here - docs.unity3d.com/ScriptReference/KeyCode.html
I hope that all helps! 🙂
Hello! Oh, I just didn't know about the new control system. I was also trying to adapt the script for 3D control. I ended up replacing everything with button activation, but it looks like I broke something... The dialogue wouldn't end until I left the cube collider space. Then I saw your message! That helped a lot. Now I'll just write the controls for the new system and hopefully everything will be fine)
Thanks for your great video. It really helps me a lot about how to designing the system, and I am going to experiment with UI toolkit.
By the way, I have a question: at 27:26, to select the first choice, you said "event system requires it to be cleared first and the have the selected object be set". But in my own project, I try to directly set the first choice selected without select to null first, and it works just fine, so there is no need for coroutine in my case. So can you tell me why you said that?
Note: my Unity version: 2022.2(Beta)
Thanks again😊
Hey there and thank you for the kind words! Really glad you got use out of these videos! 🙂
As for that part at 27:26, if the issue isn't happening for you I wouldn't worry about it. It's happened to some and not to others, but I think it just comes down to a Unity version difference.
TL;DR - if you don't see any issues you can ignore that part of the video.
Hope that helps clear that up!
Hello really thank you for the tutorial . i was wondering what you said in 03:45 , is there an example , for example , putting all props description under 1 ink file (since having separate ink file for just one-three liner dialogue seems could get messy real fast if theres ton of objects in the scene)
Hey there! I don't have a concrete example anywhere, but I know a few others that have gone that route with only a couple modifications to this system. Here's one way you could go about it.
With the below approach, you'd keep all of your dialogue in a single Ink file and use Ink Knot's to organize that file depending on the dialogue you want to happen for each dialogue trigger.
1 - Write all of your dialogue in a single Ink file organized into _'Knots'_ that should correspond to each dialogue trigger you want to use.
2 - In your DialogueManager script, you can load the entire Ink Story there rather than having it come from the DialogueTrigger script.
3 - In your DialogueTrigger script, instead of passing along an entire Ink Story to the DialogueManager EnterDialogueMode(..) method, pass along a string instead which represents the *knot name* for that specific triggers' dialogue.
4 - In your DialogueManager *_EnterDialogueMode(string knotName)_* method, call *_currentStory.ChoosePathString(knotName);_* to start your story from that specific knot.
You can see more info about the _ChoosePathString(..)_ method in these docs (scroll to the "Jumping to a Particular Scene" section) - github.com/inkle/ink/blob/master/Documentation/RunningYourInk.md
I hope that helps a bit! 🙂
I implemented this in my game. I like the Ink system, but I feel like having a singleton DialogueManager is a bit of an anti-pattern. I've been trying to come up with a better way using dependency injection, in keeping with your design of having reusable components.
Make sure besides having a RigidBody for the Player also the function ...OnTriggerEnter2D(Collider2D... is written with "2D" instead of "2d". It's a small mistake in the reference script i guess.
Does anyone know why the JSON file wont convert to text? I triple checked I have all the code correct and in unity. It logs the inkJSON.text but it does not show up in the DiolageText.
Hey there! Hmm, it might be a bit hard to figure out without seeing your project/code. I know you said you triple checked, but make sure you also check against the project code on Github if you haven't already. - github.com/trevermock/ink-dialogue-system/tree/2-choices-implemented/Assets/Scripts/Dialogue
Here are some things that come to mind that you could try/quadruple check.
1. In the top left menu bar in Unity, you can go to 'Assets -> Rebuild Ink Library'. Make sure it builds without any errors to ensure that Ink is installed properly.
2. When you log the inkJSON text, are you doing it with _currentStory.Continue()_ ? If so, the dialogue line is getting removed when you do the log and then the story is empty when you actually try to set the dialogue text. Be sure to put _currentStory.Continue()_ into a variable and then log/use the variable.
3. Totally a shot in the dark, but have you closed and reopened Unity? Someone else was having some issues with Ink and they mentioned that things were working correctly after restarting Unity. Worth a try!
I hope that helps! 🙂
This is a very helpfull tutorial, thank you very much! I would like to use the scroolwheel to select the buttons instead of W and A. Would you mind explaining how to achieve this?
I'm glad you found the tutorial helpful, thanks for the kind words! 🙂That should be possible, although I haven't tried this myself. The solution will likely depend on which Input System you're using. Here's a couple links I found that _might_ help get you started.
If you're using Unity's new Input system like I am in these tutorials, this seemed like a pretty good video to get you started using a scroll wheel - ruclips.net/video/2kUaS-55atA/видео.html .
If you're using Unity's old (default) Input System, upon first searching this it looks like a lot of the ways people are doing it is through code. With that said, I imagine that there's an easier way to do it where the Event System handles it, but without playing around with it myself I'm not sure how. Here's a link to someone who wrote a script that might act as a good starting point if you want to go the code route - answers.unity.com/questions/340772/how-to-use-the-mouse-wheel-to-switch-blocks.html . The 'blocks' being referred to could be switched out to select the choice buttons by code instead. The important bit from that link is how they're getting the scroll wheel axis information. You can use that information to write your own logic to select the buttons.
I hope that helps a bit and best of luck getting that working! Again - please take the above recommendations with a grain of salt as I personally haven't worked with scroll wheel controls before.
@@ShapedByRainStudios Thank you very much for your answer, I greatly eppreciate that :) With your help I was able to implement the feature I wanted. Here is the code snippet I added in the Update Method:
if(currentStory.currentChoices.Count > 0)
{
if(Input.mouseScrollDelta.y != 0)
{
currentSelectedChoice -= (int) Input.mouseScrollDelta.y;
currentSelectedChoice = (currentSelectedChoice < 0) ? 0 : (currentSelectedChoice > currentStory.currentChoices.Count - 1) ? currentStory.currentChoices.Count - 1 : currentSelectedChoice;
EventSystem.current.SetSelectedGameObject(choices[currentSelectedChoice].gameObject);
}
}
@@BSXPanther Awesome, I'm glad you figured it out and thank you for sharing! 🙂
hi there! this is a really useful tutorial, thanks so much! i'm a super beginner and i encountered a problem i can't figure out - i'm at about 19:00 in the video, but when i test out getting the dialogue to show up, it pulls the dialogue panel up as intended, shows the first line of text, but then when you press continue it speeds through all my lines of text really fast and then immediately closes. do you have any tips for this, or have any idea what went wrong? :0 thanks again! (and sorry if this is a dumb question, i'm very new to unity! :) )
Hey there! This could be due to a lot of different things, but here are the first things I would try.
1 - How are you taking in input? Are you using Unity's default input system? If so, are you using Input.GetKeyDown(..) OR Input.GetKey(..)? Input.GetKeyDown() will only be true for a moment when the key is first pressed; however, Input.GetKey() will be true for as long as the key is held down. The latter would result in it blowing through the dialogue lines like you're seeing and is a really common mistake for beginners.
2 - Put some logging at the top of your ContinueStory() method - like Debug.Log("ContinueStory called") - so you can see every time it's getting called. It should only get called once every button press you do. I imagine it's getting called more for some reason though. From there, you can put more Debug.Log(..) statements around the code to try and figure out where things are going wrong.
3 - You can double check your DialogueManager code against the file on Github. This sounds like it's either something in your Update method or ContinueStory method, so I would start with double checking those. Here's the file at the end of this video - github.com/trevermock/ink-dialogue-system/blob/2-choices-implemented/Assets/Scripts/Dialogue/DialogueManager.cs
I hope that helps! If you try those things and don't feel like it's getting you anywhere, feel free to comment back and we can try digging deeper. 🙂
@@ShapedByRainStudios omg thank you so so much, i was using "GetKey" instead of "GetKeyDown" just like you said lol! that was a super easy fix, thanks for getting back so quick, i appreciate the help! :D
@@hazia awesome! Lucky guess, haha! Glad I could help! 🙂
I have a problem, hope you can help me with this
For example when we choose the answer Charmander and it's not the correct answer so how can we go back and choose another answer for the question?
Hey! You can do that by modifying the Ink file for the dialogue. Replace _pokemon .ink_ with the below contents and it should do what you described, where Squirtle is the correct answer.
Check out this video as well if you're interested in learning more about how the syntax works (if you haven't seen it already) - ruclips.net/video/KSRpcftVyKg/видео.html
--- *pokemon .ink file contents below* ---
-> main
=== main ===
Which pokemon do you choose?
+ [Charmander]
-> incorrect("Charmander")
+ [Bulbasaur]
-> incorrect("Bulbasaur")
+ [Squirtle]
-> correct("Squirtle")
=== incorrect(pokemon) ===
You chose {pokemon}, but that wasn't correct. Try again.
-> main
=== correct(pokemon) ===
You chose {pokemon}! That was correct!
-> END
Thanks for the tutorial, its a complicated (for newbies like me at least), but clean way to show dialogues with NPCs.
I only have a problem where the logic works perfectly, but the visual feedback of the choices when selected doesnt work at all. I tried with a lot of configurations over the button components but none of them show me when i select the option.😱
I'm glad you found it helpful! 🙂
That sounds like it could be that the 'Selected Color' needs to be changed (22:12 in the video for reference). Double check the alpha value of that color as well, which should be 100. Sometimes those default to an alpha value of 0.
If that doesn't work, you could also play around with the other color values for the button if you haven't already. Especially the alpha values.
Based on your comment though, it sounds like you might have already tried what I mentioned above. In that case, it could be worth downloading this project from Github, loading it up in Unity, and seeing if the issue still occurs. That'll at least help you narrow it down and also give you something to compare against. github.com/trevermock/ink-dialogue-system/tree/2-choices-implemented
Best of luck and I hope that helps a bit!
@@ShapedByRainStudios wow, thank you so much! what a fast response! heading to try it in unity
FIXED! IDK what happened, but i re opened unity now and seems to be working with the exact same setup as earlier. Anyways, thank you a lot for the explanation! (you gained a sub)
Haha, right on! Sometimes that does the trick! 😅 Appreciate the sub!
when I transfer from one scene to another scene my dialogue is not working it provides an error called gameobject has been destroyed, what should I do?
Great tutorial! I was wondering, is there any to make a typewriter effect with this setup?
Hey there, just checked out this video pretty recently and am a big fan of it. Followed it all the way through and it works pretty well. I have encountered one issue though at the end if you do see this. Basically the issue comes from the choice selection. It works so far where you can select and choose the pokemon, but after choosing a Pokemon the final text does not get displayed and the dialogue interaction ends early. How do I fix this?
Great video! But i had a problem. When I'd have multiple choices, I'd have to first click the choice with a mouse button and then I could proceed with my submit button later on. Is there any way to fix this? Can I make the OnClick() method be triggered by assigned button? I am not using the new input system.
have you found the solution to this?
Is it a good thing to write a storytellingManager class that holds all the dialogues init and all the "states" that has been switched in the game, for instance if you have succeed with quest , and already talked with X and Y and picked up item B etc and also handles all the Cutscenes etc ? should these dialogue be dialoguemanager then also or just normal classobjects with MonoBehaviour ?
Hey! I think there are lots of ways you could go about what you're describing. I think a StorytellingManager class is fine, but I would lean towards a normal class object that's controlled by the DialogueManager rather than a MonoBehaviour if you're just trying to keep state. Of course, it completely depends on your use case.
I would do something similar to what I have in this video that goes over variable data persistence (which it looks like you've seen and I'll reply to you there in just a moment as well🙂) - ruclips.net/video/fA79neqH21s/видео.html
I also just put out this video which covers using story.ToJson() and story.LoadJson() methods for a really simple save system which you might find as a useful reference for keeping story state. Skip ahead to the Save/Load timestamp - ruclips.net/video/HP1EYVwAhRg/видео.html&t
I hope that helps!
@@ShapedByRainStudios great answer. Thanks
I learnt a lot from you video. Thank you very much! But if I want to click on "VisualCue", instead of using keyboard, what should I do?
Hello, how can you do multilanguage using ink, to have dialogues in English, Spanish and French?
Hey there! 🙂To my knowledge, Ink currently doesn't have direct support for localization. The last I checked, they recommend having separate Ink files for each language (which is definitely a big downside if you have a lot of dialogue).
There are some other creative solutions people have done out there, but I'm personally not as knowledgeable on them. You'll find some threads and short articles on the subject if you search '_Ink localization_' on Google that might give you some ideas.
I hope that helps!
@@ShapedByRainStudios thank you
amazing thank you
thank you.
this video has been a great help to me so far, I just have one question. I am near the end of the video, where you have just shown that you can now click on a choice, the problem is, I can't click or even highlight any choice, I am using both unity input systems, but have tailored this part of my project to the new one, if thats any help. I have an action in my control panel and code inside my input script for a mouse click, but I dont mind using the arrow keys like you have. i've also put everything into the inspector, like under the event system, and in the inputmanager inspector too. sorry if this didnt make much sense
Hey there, I'm glad the video has been helpful and I believe I understand. 🙂 Working with both Input Systems at once can definitely be a bit tough. It sounds like the issue is maybe related to having a 'first selected choice' in the event system as mentioned at around 26:46 in the video. That said, the Event System behaves differently depending on which input system you're using - which might be where you're running into an issue.
It's really hard to say what could be going on. I would start by troubleshooting the 'first selected choice' coroutine code around that part of the video, putting in some Debug.Log() statements to ensure it's being called. With any luck, that might give you a lead as to what's happening (or not happening).
If all else fails, I would recommend sticking with one input system over the other unless you have a good reason to need to use both. Others have gotten this Dialogue System working with Unity's old (default) input system with a few small modifications. If you want to go that route and are having trouble - let me know and I can try to give more specific guidance to do that.
Best of luck! It definitely seems like a tricky issue!
@@ShapedByRainStudios interesting, I do feel like it might be to do with having both input systems, however it does work for the interact and submit button, just not the choices. I tried debugging the coroutine for firstselectedchoice, and it seems to be working, it comes up when i open up the text box. how would I go about only using the old unity input system? no worries if its too much to explain, but thank you anyway:)
@@ShapedByRainStudios it seems to be working now, i deleted the event system and readded without clicking the button that changes it to the new input system and it works, really not sure how but im glad its fixed! I appreciate your help and thanks for the tutorial:)
@@conners2955 Oh interesting. I'm glad you got it figured out! 🙂