Previously On IT Ninja . . .
When we last left off I had started a whole new game. It was just the basics, a player you control, a world you can walk through, and ways to transition scenes. It’s a great beginning, but pretty boring if there’s nothing to do. That’s where building a questing and dialogue system in Unity comes into play.
And Now On IT Ninja . . . .
The first thing I did was start playing around with a UI. It’s something pretty simple so far, as is everything in this game. My idea is to get a working prototype for everything I want to do, then add more of those things, and make them prettier. So, I created a canvas, threw on some UI elements and sprites that I want to use and then moved on to creating stuff to put in there.
Quests, Questing, and Quest Objects
So, the beginning of my dive into questing was a YouTube video tutorial. From there I’ve made a deep dive into all sorts of concepts in Unity. One major thing the video did for me was to open my eyes to MonoBehaviour. I ran into an issue with my Save Game script when it came to saving GameObjects previously, and this video allowed me to realize I can create my own objects that are serializable and don’t inherit from MonoBehaviour so they can be included in my savegame data!
Next, I needed a way to store a bunch of quest objects of the same type in a single variable for saving. So I needed an array, right? All my previous coding experience said that’s what I needed. But I was wrong, arrays in Unity work a bit differently than I’m used to. Then I found lists. Bye bye arrays, prolly never touch one of them again.
So now I’ve got a new Quest object, which I can “give” the player, and save and load between sessions. Amazing! But now I actually need some kind of quest giver. My head kept spinning around creating a database or JSON file or something to store all kinds of stuff in. But then I remembered, I’m trying to keep it simple for now. So I just dropped a new script on a sprite, copied a bit over from my travel anchors and BAM!
Back to the UI
So far so good. I’ve got this thing I walk over to. I press a button and this quest is now assigned to the player. There’s all sorts of data in the Quest object, so I need a way to let the player view that. I also need some dialog for accepting the quest. So back to the UI we go. So that’s two different functionalities I need. I need a UI element for viewing/accepting the quest and a UI element for viewing active and completed quests.
I spent a good long while thinking about how to do this. Again, overthinking things, but time its not a bad thing. I moved my game pause stuff over to the UI manager for a number of reasons. The main being they share controls and actions. But then I had to think long and hard about how the systems involved in the UI, the pause screen, dialogs, other UI elements, interact with each other.
I could simply use the escape key to pause the game, and open a dialog over everything, but I’d like to use that key for exiting windows, conversations, or other dialogs too. So I will just create boolean variables tracking the state of those UI elements, and depending on the states different things will happen when the escape key is pressed.
Back to the Beginning
Wow, now as I dive deeper and watch these tutorials I’m noticing that I’ve made a critical mistake in my scripting. The fact that I’ve caught it now is good, it’ll allow me to go back through and correct the mistake early on. Basically, I’ve hard coded a bunch of stuff that changes the active state of game objects. I should just have set those as public variables instead. This will take some time to correct. . .
Surprisingly, it didn’t take as long as I expected. I only had to modify a couple prefabs and that took care of the issue. Going forward I will do my best to just associate game objects via public variables instead of trying to find the thing in the scene. Once I got that all down I just dove right back into the questing dialogs.
Doing It Wrong
So, I’m basically doing this whole game development blog things wrong, I think. Part of why I say that is because I did a whole bunch of work and can’t really say a lot about the process. There was a ton of trial and error, but in the end I got it working. I had to tweak my existing code as well as write (and re-write) new code. But I can’t for the life of me remember the details, just that it works.
Should I be more technical? Should I just give a better overview about what I’ve done? Mix and match depending on reasons? You know what, I’m not doing anything wrong, this is my game/blog/site/post so I can do it whatever way I want.
So, I got it working, mostly. It’s some pretty complex stuff, and I had to do a lot of brain bending to figure out the logic behind it. All of these systems I was playing with interact. I’m talking three or four different prefabs, each with at least script and multiple sub-components (which may have its own scripts), that can be instanced any number of times across multiple scenes.
I have a feeling that I may eventually come back to this and completely redo it. I may be missing some best practices, or be too much of a novice to do all of this eloquently but for now it works. All the functionality I described (more coming later). You’ve got a Dialog UI element (so far only used for questing, but will eventually be used for character dialogue), a pause UI element, and a third UI element.
Each of the UI elements can be closed with the escape key. If none are active, hitting escape does the pause thing. You hit tab, the third UI element opens or closes. You interact with a quest giver, the Dialog UI opens with quest information in it, and you can choose to accept or decline the quest. If you accept the quest, it gets added to a list and you can’t get the quest again. If you decline, you can just interact again.
I have functionality built into the Dialog UI element to allow me to use that for actual NPC dialogue and such but I have yet to build a system to use it. I guess that means it’s time to talk about it. Let’s just give you a general idea of my dialogue UI. There’s a sprite, two texts, and six buttons. So far, the sprite is static because I don’t feel like figuring out how to change that on the fly properly. One text is a subject, opener, title, whatever. The other is the description.
So, for quests, the title of the quest appears in the top text, and the description appears in the bottom. Two buttons are active, one to accept, one to decline. So, for dialogue between characters, I should put the other character’s name in the title text field and then what they have to say in the description text field. Then a number of the other four buttons will be active and have your possible responses. Is four possible responses good enough? Yeah, for now it is.
So the next step is to create an NPC prefab. Create an NPC script. Create a NPCDialogue class. Dialogue can get tricky I think, especially if it’s nested. No, I have to remember to keep it simple! I really keep forgetting that. Just need to make something that does what I want and later I can come back and improve it. I think I’ll add one more button to the UI too, a simple “Continue” button.
I gotta feel like I’m making progress on this game, so we’ll add a simple way to complete the first quest I added to the game. I’ve created a new prefab that will do all the tracking of quest objectives. So far I’ve made it so any quest that asks the player to go to a certain scene will complete when that scene loads! It took a bit of research on lists to get it working right. But now the player is rewarded with experience and money when the quest is completed.
In doing this I’ve begun creating a function that will deal with completing quests. I just feed it a quest, and it will do everything. Right now, it adds currency to and exp to the player and marks the quest complete, but eventually it will also give players items, maybe throw up a dialog or something. Starting simple to progress.
Next Time On IT Ninja . . .
So I’ve got a barely working quest system. It’s not pretty (nothing in this game is pretty) but it does the job. Well, it does one job, literally a single quest so far. But it has the beginnings of a very robust questing system. I’ve got the bones, now I need to add the muscle. But before I can add all that muscle I need to add even more systems to the game.