Now that I'd settled on a game concept and I had some 3D character models to work with, I had to figure out how to actually bring them to life. There were some aspects of this that I already knew how to do, like giving the character the ability to interact with the world and talk to other characters. My biggest area of concern was figuring out how to animate my wizard, which is one of the things I'll cover here today. If you already have a good understanding about how to set up an animated character in Unity, some of this material will be a review for you -- but it was a pain to figure this out for the first time and if I can spare someone that annoyance, I'd be happy to do so.
I've worked with Unity for a long time, but I've admittedly got a few areas that I don't have a lot of knowledge about -- one of these areas is animating 3D characters. I've used the animation system for several things in the past like animating camera movement or animating 2D sprites, but as far as preparing 3D models, rigging, skinning -- all of that stuff was a big blind spot for me. I thought that this project might be a good chance for me to force myself to learn some of these concepts, or at least figure out how to get some good animations in my game without having to dive too deeply into these topics.
For the purposes of this article, I'll be referencing the specific models I'm working with -- but an analogous process can be used for your own 3D models, with everything just having a different name.
My first step was to actually get my characters into the scene by importing the Synty Studios models I discussed in my last article. If you've already bought some models, you can open up the asset store within the Unity editor, and then download and import the models.
Once the models have imported, you can navigate down into the newly imported folder until you find the prefabs folder. In my case, here you can see all of the different characters and all of the various props and weapons that come with the pack. I sifted through a few of the characters until I found the one I thought might be a good candidate for the game's protagonist -- I decided on the wizard. I grabbed the prefab and brought it into my scene.
Okay! And now with my wizard in the scene, let's run it and see how he looks!
Ah! Well.
I guess I need a floor.
Next, I went ahead and imported some of the environments I got from Meshtint Studio to give my wizard somewhere to stand.
So this is all well and good -- now I've got this great looking wizard, but there are actually no animations for him in the Synty pack. I was hoping to have some of this functionality built-in to the prefab, but no such luck -- this was the step I was really unsure about. Thankfully, Synty has done a great job of setting up their characters to work with Unity's default character movement and animation assets.
At this point I imported the default package "Characters" -- this gives me access to some of Unity's basic character controller scripts.
I first add the "Third Person Character" to my wizard -- this automatically added the script of the same name, along with a capsule collider and a rigidbody component -- these are important to help our character deal with collisions.
Up next, we need a way to actually have our character respond to player input so we can move him around. Unity has a great built-in script for that too -- let's go ahead and attach a "Third Person User Control".
Now, if we go ahead and run the scene, we have the ability to move our player with the keyboard!
Well....sort of:
Our wizard isn't exactly doing what we'd like -- we want him to be able to run around, but he's just kind of spinning in place.
Let's keep trekking ahead and hook up some animations -- maybe that will help us out. For this, we go up to our wizard's Animator component -- we can see that by default, he doesn't have an Animator Controller assigned. Let's go ahead and attach Unity's ThirdPersonAnimatorController.
Now when we run, we see our wizard look like he's permanently in jump mode:
The last step here is we need to tweak a few things -- if you look in the scene view, the collider that gets attached to our wizard doesn't match the shape of his body. You can manually edit the size of the collider -- or you can use a little trick. You'll notice that the wizard object in the hierarchy is actually a parent object with a bunch of different character objects as children. If you drill down into the transform and find the actual wizard object, you can attach a capsule collider and it will automatically be the right size. Then you can copy that component back to the parent transform where all the rest of our scripts are, delete the old capsule collider, and voila! A perfectly sized collider for our wizard.
Even though we now have our correct, wizard-sized capsule collider, we will still see the same problem -- there's one more thing we need to fix. The last step is to adjust the ground check distance in the Third Person Character -- by default this is set to 0.1, which doesn't seem to be the right distance for our character to tell where the ground is. This needs to be increased to some larger value -- I chose 1.0. Now, running again, here is what we see:
Okay! Well that wasn't so complicated after all! Unity's built-in character controller is certainly limited in some ways, but for the purposes of Curious Castle, getting the movement and animations to work smoothly with these new models was relatively quick and easy.
I think this process would have been a much bigger pain if Synty Studios had not already done a great job of rigging these models and setting them up as humanoids. Sometimes you will find 3D models that have not beed rigged, and this straightforward animation workflow would not be possible -- instead, you'd need to actually do the rigging yourself by setting up a bone structure and then assigning each part of the 3D mesh to the bone it should follow. I'm sure there are well-established ways to go about doing this, but it's definitely something you'd need to spend some time figuring out. So if you are ever downloading or buying character art and you see that the objects are rigged -- that's a big relief!
I was so excited to have this sorted out -- I now have a wizard that can run around with smooth animations to match! Thank you Synty Studios for setting up awesome characters, and thank you Unity for having an easy basic character animation setup!
Implementing a Dialog System
One of the next things I worked on was a key system required for this game -- some sort of text box/dialog system. I created a basic UI element parented to the main camera in the scene to house the actual text. I used a nice little piece of code I have come back to time and time again when writing text boxes -- some functionality to show one character at a time and play a little sound effect every so often, so it sounds like the character is mumbling along with the text being shown. Kind of like in the game Animal Crossing. It's a little verbose to post here, but please reach out if you're interested and I would be happy to share that code with you.
I decided it would be nice to add a little picture of who was talking next to the text box -- so I set up a separate area of the scene with characters standing in front of a uniform background. Then I set up a second camera as a close-up to their face, and put a render texture on a little quad which I arranged next to the text box -- now the close-up picture will show on that quad, right next to what that character is saying.
I then added a unique ID for each character to my text processor, so that when it loaded the text onto the screen, I also supplied the ID so it would know which character's face to show.
I think the final result looks pretty good!
Now that I had a system in place to show text on the screen, I wrote some code for our protagonist wizard to interact with the objects in his world. Anything that he could interact with I put in its own layer -- that helped me make sure to only check collisions against things I've explicitly targeted as something the player can interact with. Each object in the "Clickable" layer also has a script attached to it which contains the text information that should display after it's been clicked. That way, I can easily change this in the inspector on a per-object basis.
After that, I modified the character controller to perform a sphere cast upon a certain keyboard press by the player, and used this as a way for the player to be able to check all kinds of different objects for clues or talk to other characters in the game. You can do something like this:
I manually set the clickPoint GameObject to be in front of the wizard, and then I make this call to check for any overlaps in a sphere with radius 0.6. This call can be paired to some player input, such as pressing enter -- and after this executes, you now you have an array containing all the objects in the TempCast layer that were caught in the OverlapSphere. If you want, you can also now calculate which one is closer or make some other decision about which one you want to perform an action on in the case of multiple colliders appearing in this results array -- for simplicity I just take the first one listed.
After getting this code in place, I spent a long time setting up many different objects throughout the castle that could be "checkable" by the player -- when the player presses the enter key in front of the object, a little text blurb appears on screen. Maybe you walk up to a barrel and press enter -- now, the game will say "Checking inside the barrel! But nothing was there...". Of course, if you check in the right places, you might find some interesting clues.
After setting up most of the castle's objects and putting all the important clues in all the right places, the core mystery of the game is pretty close to being solvable. I actually need some way to register if the player has correctly solved the puzzle -- I think I might implement this in the form of a branching conversation tree when you talk to the king. Maybe he will present the player with all the possible options, and I will code some UI for the player to choose one option among several. The player can then select which answers they think are correct, and I will perform a check to see if they give all the right answers. If the player gets them all correct, they win! Otherwise...game over.
I also spent a couple of hours putting together a title screen for the game -- kind of unnecessary, but I think having a title screen where the player has to "press start to play" adds a nice layer of polish and professionalism to the game. It makes it feel more like a real game. I think the title screen I came up with is pretty cool looking, so I won't spoil it here -- you can see it once the game is ready on Sunday!
So that's where I'm at now! I'm feeling well on track to finish the game in time. I've got the layout mostly in place and all of the clues are hidden throughout the castle. There are a ton of details to keep track of and already in my casual playthroughs I've found lots of bugs -- so I'll be busy making sure all of these little things are fixed before the deadline on Sunday!
Looking forward to the home stretch of getting this game ready for everyone to play! You will hear from me on Sunday in my Curious Castle recap!
--Kyle
looking better all the time bugman, still well above my pay grade. keep up the great work. love you and miss you.