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!
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:) 🌼
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!
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.
@@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! 🙂
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.
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!
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(); }
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 😆
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.
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!
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!
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)
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 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!
hi there! despite copying everything to a T, i can't seem to be able to set up my player input component the same way as yours at 5:09 the only function it's letting me add is MonoScript > string name, and i don't know how to get the inputmanager.xPressed in there.
Hey there! Ensure you're dragging in the InputManager *_gameobject_* and NOT the script from your assets directory. This isn't clear in the tutorial since it looks like the script is what's been dragged in. It's actually the InputManager gameobject the script is attached to. If that doesn't seem to be it though, let me know and we can dig a bit deeper. I hope that helps! 🙂
Hello! if anyone understands this code, please tell me why at this point: 18:15 when I moved the "DialogueManager" script to the appropriate place, I do not have such tabs as "Dialogue UI", "Dialogue Panel", "Dialogue Text" in the script settings?
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! 😁
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!
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!
Okay second comment with another issue at around 28:40. When I try to choose an option, nothing happens. I only have two choices set, but choosing the first one(choice 0) does nothing, whereas choosing the second one(choice 1) gives an error message that says choice out of range.
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 I've followed the video through arround 19:33, for some reason, the first line is always instantly skipped. Do you have any thoughts on what might be the possible reasons?
If I make the DialogueManager update to fixed update, I can see the first line, but it gives me difficult time(multiple clicks) to go from 2nd to 3rd line.
Now for somereason I can't click the options, is it because your code was designed to select choices by movement input, and I was trying to make a mouse click interaction?
@@PengiiiiGameDev Thanks for replaying, did you mean the question by savageontoast7215? Seems like button problem wasn't resolved. And I solved my double click problem. For myself, I made a separated PlayerScript that use Update to check for "Input.GetButtonDown("Say")" where Say is an customized input category for left-click or space I added in Unity Project setting-Input Manager. What I did to get around the double click is to make Playerscript call the "Trigger" as Enumulater and just wait for 0.1 second. This seperates the Input in player and the input in DiaglogueManager. I don't know if it will hunt me in the long run. For the button non-respawnse. For me I was working after I disabled the main Camera, from Online out of 50 replies someone suggested it's the raycasting being blocked by canvase or buttons. For me it was the Main Camera. Not sure if this is suitable for anyone. btw my game is a Unity3D project
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!
I need help. My dialogue ui isn't showing up anymore. When I reached 26:24 and switched my Ink scripts from Test to Choices Ink Script thats when the dialogue box doesn't show up for the npc that i assigned the Choices Ink script to. But when I assign the test script the dialogue box shows up. Do you think you can help me?
Hey there! This could be a few different things that I can think of. Here's what comes to mind that you can double check. 1 - Does the new Ink file have an error at all? There could be a typo in your Ink file, which could prevent it from displaying. Hopefully your editor would catch this, but you can play with what's in that Ink file to try and narrow it down. 2 - If the Ink file seems fine, it sounds like maybe something is off with the choices. I would compare your DialogueManager script against the one I have posted on Github to see if there's anything you might of missed. - github.com/trevermock/ink-dialogue-system/blob/2-choices-implemented/Assets/Scripts/Dialogue/DialogueManager.cs 3 - If the DialogueManager Script looks good, it might be something not hooked up correctly in your editor. This would likely give you an error. If you're getting a specific error, that could help narrow it down quite a bit. I hope that helps! 🙂
@@ShapedByRainStudios Thank You! I looked through both mine and your dialogue manager script and added in currentStory.currentChoices.Count == 0 && and the ContinueStory(); in Make Choice and it fixed my problem! I'm so glad this was able to work, thank you so much.
@@ShapedByRainStudios Ah I ran into another problem now. I decided to add dialogue to other objects in my scene other than my npcs, such as a sign. However, it replays the text once it is finished and I'm stuck in a loop. It doesn't do this with my npcs, whether they had choices or not. I went back in the video and rewrote the (playerInRange && !DialogueManager.GetInstance().dialogueIsPlaying) line in DialogueTrigger but it didn't help.
@@AW05Backup Hmm. It's hard to tell without seeing your code, but if it's replaying the text once it's finished then a couple things come to mind. It could be the actual Ink file. If you play through the Ink file in the Inky Editor, does it loop like that as well? If not, the other thing that comes to mind is that maybe the time waited in ExitDialogueMode() isn't enough (around 21:00 in the video), and so when you hit the 'submit' button to end the dialogue it also triggers again. That assumes that your submit button is the same as the button you're using to trigger the dialogue. You could try increasing that time slightly to see if that has something to do with it.
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
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'm a beginner programmer who's making a very simple game as a joke for a friend. I've followed the tutorial up to 20:38, but when I test it doesn't close the dialogue(it doesn't do the else ExitDialogueMode() ) after the final line. the error message makes me think it's trying to continue the Story again, even though there isn't another line of text. How do I fix this?
Hey! figured it out :) I'm not using a player controller, rather the player moves forward by itself whenever a Boolean i made called "encounter" is set to false. the "encounter" would get set to true when the player reached a trigger after a set amount of time, to which it would stop moving and also start the text dialogue. i fixed the problem by making sure encounter got set back to false in the else statement that had ExitDialogueMode()
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).
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! 🙂
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?
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.
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
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!
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?
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. 😁
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!
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!
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!
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!
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?
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?
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!!
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); } }
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!
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.
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 :)
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
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! 🙂
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:)
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 currently have an older version of Unity and don't have access to that Player Input component, would it be possible for me to use this tutorial without it?
Hey there! 🙂 Yes, Unity's default Input system will work for everything done in this video. For the few sections that have Input specific code, you can replace it with calls to 'Input.GetKeyDown' and it should work the same - docs.unity3d.com/ScriptReference/Input.GetKeyDown.html Anywhere I use a method like 'RegisterKeyPressed()' though, you _may_ need to account for race conditions when using Unity's default Input System by keeping track of the Input.GetKeyDown call in a boolean and micro-managing it a bit. I hope that helps and best of luck!
@@ShapedByRainStudios I've gotten it to partially work using your suggestion, however I've been stuck on trying to display lines other than the first line. Using Input.GetKeyDown, I'm initially able to start the dialogue and show the first line, but whenever I press the KeyCode I have assigned to switch lines, it won't transition. I've tried mapping other keys and that doesn't seem to work either.
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.
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! 🙂
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.
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!
Do you have a good suggestion for how to handle performing some sort of action when selecting a choice? Is it possible to run a script when a choice is made (or perform a func etc)?
I managed to implement that with a custom system, not with Ink. Key was to have a Dialogue Manager with an Action-property, for example. If you click on a selection on the UI, it triggers the static Action of the DialogueManager with the parameters 1-4 (for each selection). NPC-scripts or scripts that trigger the dialogue automatically subscribe/desubscribe during the process and react upon the selection.
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!
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 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
This is an incredible tutorial. Helped me immensly - thank you so much!
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.
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.
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 was littarly a month ago. Consistant tutorials of every topic in game dev!👍👍😀
Appreciate it! 🙂
Wait woah, I was looking for a tutorial as in depth as this a while back! Thanks!
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 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! 🙂
Not only is an useful feature, also I learn how to improve my Unity programming. Thanks a lot!
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! 🙂
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.
Hey, this tutorials saved my project, super recommended!
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?
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! 🙂
Didn't know about InK. Thanks!
Another awesome video dude! ill be doing the portraits one next!
Really glad to hear! I hope you find that one helpful as well! 🙂
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();
}
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 😆
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! 🙂
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.
Amazingly simple way to add dialogue with choices, thank you very much!
No problem! Glad you found it helpful! 🙂
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!
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! 🙂
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! 🙂
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! 🙂
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! 🙂
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!
Really like your input manager design!
Glad to hear! It's definitely convenient! 🙂
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)
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! 🙂
OMG! I love you thaks for your tutorial!
This is amazing ! Thank you so much for the video!
You're welcome and thank you for the kind words! 🙂
yo bro, really thankya. Big respect
Amazing tutorial!
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!
hi there! despite copying everything to a T, i can't seem to be able to set up my player input component the same way as yours at 5:09
the only function it's letting me add is MonoScript > string name, and i don't know how to get the inputmanager.xPressed in there.
Hey there! Ensure you're dragging in the InputManager *_gameobject_* and NOT the script from your assets directory. This isn't clear in the tutorial since it looks like the script is what's been dragged in. It's actually the InputManager gameobject the script is attached to.
If that doesn't seem to be it though, let me know and we can dig a bit deeper. I hope that helps! 🙂
@@ShapedByRainStudios ah, that was it! thank you for the awesome tutorial, you earned yourself a new sub :)
At 11:46 where i am able to go into the trigger when ever i go into the collider i just get stopped and cant go further
Hello!
if anyone understands this code, please tell me why at this point: 18:15
when I moved the "DialogueManager" script to the appropriate place, I do not have such tabs as "Dialogue UI", "Dialogue Panel", "Dialogue Text" in the script settings?
Fuck!
I just missed one letter in this line "[SerializeField] private TextMeshProUGUI dialogueText;" XXDDDDD
@@ot1genbeats88 That'd do it! Haha, I'm glad you figured it out! 🙂
@@ShapedByRainStudios Thanks for your video. Very helpful.
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! 😁
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!
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
Thanks dude this really helped me a lot I did the steps that's you did thanks man!
Thank you! This helped me a lot!
No problem! I'm really glad to hear! 🙂
Okay second comment with another issue at around 28:40. When I try to choose an option, nothing happens. I only have two choices set, but choosing the first one(choice 0) does nothing, whereas choosing the second one(choice 1) gives an error message that says choice out of range.
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
Hi I've followed the video through arround 19:33, for some reason, the first line is always instantly skipped. Do you have any thoughts on what might be the possible reasons?
If I make the DialogueManager update to fixed update, I can see the first line, but it gives me difficult time(multiple clicks) to go from 2nd to 3rd line.
I fixed it by make the EnterDialogueMode Coroutine with 0.1 second.
Now for somereason I can't click the options, is it because your code was designed to select choices by movement input, and I was trying to make a mouse click interaction?
@@unluckyyooo6598 one of the top comments explains how to make the button interactable, try that
@@PengiiiiGameDev Thanks for replaying, did you mean the question by savageontoast7215? Seems like button problem wasn't resolved. And I solved my double click problem. For myself, I made a separated PlayerScript that use Update to check for "Input.GetButtonDown("Say")" where Say is an customized input category for left-click or space I added in Unity Project setting-Input Manager. What I did to get around the double click is to make Playerscript call the "Trigger" as Enumulater and just wait for 0.1 second. This seperates the Input in player and the input in DiaglogueManager. I don't know if it will hunt me in the long run. For the button non-respawnse. For me I was working after I disabled the main Camera, from Online out of 50 replies someone suggested it's the raycasting being blocked by canvase or buttons. For me it was the Main Camera. Not sure if this is suitable for anyone. btw my game is a Unity3D project
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!
Well explained! Thank you!
I need help. My dialogue ui isn't showing up anymore. When I reached 26:24 and switched my Ink scripts from Test to Choices Ink Script thats when the dialogue box doesn't show up for the npc that i assigned the Choices Ink script to. But when I assign the test script the dialogue box shows up. Do you think you can help me?
Hey there! This could be a few different things that I can think of. Here's what comes to mind that you can double check.
1 - Does the new Ink file have an error at all? There could be a typo in your Ink file, which could prevent it from displaying. Hopefully your editor would catch this, but you can play with what's in that Ink file to try and narrow it down.
2 - If the Ink file seems fine, it sounds like maybe something is off with the choices. I would compare your DialogueManager script against the one I have posted on Github to see if there's anything you might of missed. - github.com/trevermock/ink-dialogue-system/blob/2-choices-implemented/Assets/Scripts/Dialogue/DialogueManager.cs
3 - If the DialogueManager Script looks good, it might be something not hooked up correctly in your editor. This would likely give you an error. If you're getting a specific error, that could help narrow it down quite a bit.
I hope that helps! 🙂
@@ShapedByRainStudios Thank You! I looked through both mine and your dialogue manager script and added in
currentStory.currentChoices.Count == 0 && and the ContinueStory(); in Make Choice and it fixed my problem! I'm so glad this was able to work, thank you so much.
@@ShapedByRainStudios Ah I ran into another problem now. I decided to add dialogue to other objects in my scene other than my npcs, such as a sign. However, it replays the text once it is finished and I'm stuck in a loop. It doesn't do this with my npcs, whether they had choices or not. I went back in the video and rewrote the
(playerInRange && !DialogueManager.GetInstance().dialogueIsPlaying)
line in DialogueTrigger but it didn't help.
@@AW05Backup Hmm. It's hard to tell without seeing your code, but if it's replaying the text once it's finished then a couple things come to mind.
It could be the actual Ink file. If you play through the Ink file in the Inky Editor, does it loop like that as well?
If not, the other thing that comes to mind is that maybe the time waited in ExitDialogueMode() isn't enough (around 21:00 in the video), and so when you hit the 'submit' button to end the dialogue it also triggers again. That assumes that your submit button is the same as the button you're using to trigger the dialogue. You could try increasing that time slightly to see if that has something to do with it.
you are my favorite person ever
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! 🙂
Really good video!!!! Thxx
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!
Great video thank you!
You're welcome! I'm glad you found the video helpful! 🙂
OMG, thank you!!!! 3 3
Hi, I'm a beginner programmer who's making a very simple game as a joke for a friend. I've followed the tutorial up to 20:38, but when I test it doesn't close the dialogue(it doesn't do the else ExitDialogueMode() ) after the final line. the error message makes me think it's trying to continue the Story again, even though there isn't another line of text. How do I fix this?
Hey! figured it out :)
I'm not using a player controller, rather the player moves forward by itself whenever a Boolean i made called "encounter" is set to false. the "encounter" would get set to true when the player reached a trigger after a set amount of time, to which it would stop moving and also start the text dialogue. i fixed the problem by making sure encounter got set back to false in the else statement that had ExitDialogueMode()
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).
can you please make a video on how you made the your input system please
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! 🙂
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?
Great tutorial. Thank you
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.
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
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
Hi.Your video is so amazing!
Thank you! I'm glad you found it useful! 🙂
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?
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. 😁
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!
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!
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! 🙂
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!
for some reason, pass 28:46, I'm still unable to make a choice, it still just ends the dialogue
Thank you so much!
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!
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.
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?
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! 🙂
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! 🙂
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
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?
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 :)
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 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!
thank you!!! video liked and u got a well deserved sub from me!!!!
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! 🙂
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 currently have an older version of Unity and don't have access to that Player Input component, would it be possible for me to use this tutorial without it?
Hey there! 🙂 Yes, Unity's default Input system will work for everything done in this video. For the few sections that have Input specific code, you can replace it with calls to 'Input.GetKeyDown' and it should work the same - docs.unity3d.com/ScriptReference/Input.GetKeyDown.html
Anywhere I use a method like 'RegisterKeyPressed()' though, you _may_ need to account for race conditions when using Unity's default Input System by keeping track of the Input.GetKeyDown call in a boolean and micro-managing it a bit.
I hope that helps and best of luck!
@@ShapedByRainStudios I've gotten it to partially work using your suggestion, however I've been stuck on trying to display lines other than the first line. Using Input.GetKeyDown, I'm initially able to start the dialogue and show the first line, but whenever I press the KeyCode I have assigned to switch lines, it won't transition. I've tried mapping other keys and that doesn't seem to work either.
Never mind, I have found the problem, silly me.
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.
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! 🙂
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.
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!
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
@@Digwoddiri I'm glad you figured it out and thank you for sharing your solution as well! 🙂
Great tutorial! I was wondering, is there any to make a typewriter effect with this setup?
Do you have a good suggestion for how to handle performing some sort of action when selecting a choice? Is it possible to run a script when a choice is made (or perform a func etc)?
I managed to implement that with a custom system, not with Ink. Key was to have a Dialogue Manager with an Action-property, for example. If you click on a selection on the UI, it triggers the static Action of the DialogueManager with the parameters 1-4 (for each selection). NPC-scripts or scripts that trigger the dialogue automatically subscribe/desubscribe during the process and react upon the selection.