Unity3D: Armor & Weapon Attachment to Character Model

For this week's blog post, I'm going to get a bit more technical than we usually do in these blog posts.  This is very Unity3D specific, so if that's not your bag then you've been warned.


Problem

The characters in Shibe Warz can have any combination of armor, boots, helmets, and one weapon/spell in each hand, so how do we attach those models to the character and have them animate when the character does?

Solution

I'll start with the helmet and weapon models, because the method for those is very generic and can be useful in other games.  I've uploaded the entire .cs file here if you want to look at it before/while you read.

1. Create prefabs of the models to be used.

This is pretty straightforward, drag in all the assets you need and make the weapon and armor prefabs.

2. Create a script to assemble the finished model

I named my script "UnitBuilder.cs", and it has public GameObject objects for each model that we just made a prefab for.  In Shibe Warz we have cloth, leather, and plate armor, as well as a bunch of weapons, so the top of my script looks like so:

...etc. The prefabs made earlier can now be dragged into this script, so they are easily changeable later on.  Note the "baseModel" object, which is the prefab of the completely naked unit, which we will be building on top of.

3. Instantiate the unit's naked model

This is pretty straightforward. Notice that I'm using Network.Instantiate here because Shibe Warz is multiplayer over a network. If it's a single player game, you'd just use Instantiate.

4. Attach the helmet

This is where things get a little tricky.  The premise behind having models "attach" to the character is to make them children of the original model, because a child's position and rotation, once initially set, are locked in with respect to the parent. So let's say you make two cubes, A and B.  You make A the parent and B the child.  You shrink B and put it inside of A.  Now when you move A, B will move with it, retaining its position inside of A at all times.

So, what we're going to do is make the helmet a child of the unitGameObject created above.  But we have to be careful here, because the unit's model will be animating, and as such the head will be moving around a lot.  So what we really want to do is make the helmet a child of the unit's head, that way no matter how much it moves around, the helmet will move with it.  How do we do that? Well, first we have to find the head in the model hierarchy. This is how it looks in the unity hierarchy view:

So now that we know where the head is, we can find it in code and place the helmet there.  Beware, the following is hard-coded, which is never good.  But it was getting late, so I was just trying to get things working.  Please refer to my previous blog post, where I talk about how messy your code will likely get while developing a game.

One thing you may recognize is the use of the helmPosition object.  I discovered that I couldn't simply put the helmet at position (0,0,0) because then it wouldn't be fit on the head properly, so I had to mess with it a little bit to make it look good.  Once it looked good, I simple copied the x, y, z values and stored them as private variables in this class.

And voila! The helmet is now instantiated, placed on the head, and made to stay there by setting transform.parent = charHead.

5. Attach the Weapons

This is almost identical to attaching the helmet, the only difference is instead of attaching it to the unit's head, you attach it to their hand.  For the sake of brevity I'm omitting the code, but I've uploaded the entire file here if you would like to see how the sausage was made.

6. Attach the armor and boots

I saved this part for last, because I'm not really proud of how it was done, and I know in my heart of hearts there's a better way to do it, but it works, and if it ain't broke don't fix it, right?

When Anthony created the armor, he was generous enough to attach it all to the same skeleton as the base unit model, and animate it in the exact same way.  This made my job extremely easy, as all I had to do was instantiate the armor at the exact same spot as the unit, and any time an animation is run I just animate both the unit's model and the armor's model.  The same was done for the boots.


So! This was pretty much the entire process of building a dynamic model from scratch.  I hope this can be useful to someone, and if anyone has any questions or wants to say, "Hey that was a stupid way to do that, you should do it this way..." and then provide some awesome way to do it, feel free to leave a comment here or hit us up on twitter, @verusgames.  After all, the purpose of this post is to help people in the future with the same problem!

-Nick

What I've Learned

As the new year quickly approaches, so does the one year mark for when I started actually getting into gamedev.  I started in January with a basic RPG tutorial in XNA, and here I am now, 4.5 projects later, and I would like to reflect on some of the most important things I've learned over the past year (about gamedev, that is).  I'm a big fan of lists, so let's get this thing started right.

1. Your code will get ugly

This might not be true for some of the more experience devs out there, but as a recent grad (not even a comp sci one), one of my biggest hurdles getting into gamedev was worrying about how clean and perfect my code was.  Reusability is huge in object-oriented programming, and I was eager to keep everything separated into their own chunks of functionality.  This soon took its toll, however, as I would often get paralyzed trying to do things in the cleanest possible way.  Nowadays, I spend a couple minutes thinking about a good approach, and then I dive right in.  I could sit around coming up with the most efficient code possible, but at the end of the day I need a working game before I need an efficient one.  "You can't edit a blank page," so the saying goes, and the same goes for coding.

2. People see the product, not the work

When you release a game, it's important to remember that nobody sees the amount of work that goes into it, only the final result.  This was a big misstep that we took when releasing Spell Bound.  We had all worked hard on it for 2-3 months, and we focused too much on being rewarded for the hard work, rather than being rewarded for the finished product.  We released it as a paid app (much to the chagrin of Mike) but thanks to the single review we got, we quickly saw the error of our ways, and made it free.  It may have taken 3 months of hardly ever missing a day to work on it, but it was simply not up to par with similar games, which were mostly made by larger studios of more professional developers.  It's important to note, however, that we did receive payment in a way in that we learned a LOT from Spell Bound, and gaining knowledge when you're as novice as we are is often better than gaining money.

3. Don't overplan

Planning is a great thing, especially when you're working in a team of more than one.  However, overplanning can start to be a problem when it gets in the way of getting work done.  Case in point is Shibe Warz, our current project, in which I tried to move more to a production role than a developer one.  I set up all the tasks for everyone, made a gantt chart, set up perforce to (semi-)work with unity, and all the things I could think to do to make everyone else's job easier.  This went great for a while, until I realized that with me in a production role, we were only down to one developer in a team of 5-6, and we were quickly getting behind schedule.  Everything I did production-wise was probably helpful to the rest of the team, but not nearly as helpful to the project as a whole as if I had dedicated all my time to developing.  As the team gets bigger, a producer will definitely be a more beneficial addition than an extra developer, but with as few people as we have we aren't quite there yet.

4. Keep It Simple, Stupid

This is something you read about time and time again, and anyone who has started (and probably given up on) their first game project is already well aware of this, but it's absolutely vital.  Keep your first games simple, plain as that.  Development is hard, game dev is even harder.  Things pop up that will take extra time that you hadn't even thought of before, like the GUI, a tutorial of some kind, options, the list goes on.  It's easy to skip over these small details because we take them for granted, they aren't what make a game fun but they are what make a game polished.  To date, the most polished game I've made has been Lightmaze, a simple puzzle game and definitely the simplest of the games we've made.  We had a month to do it in, I finished all of the gameplay in the first week and spent the rest of the month adding GUI, menus, music, special effects, everything.  Calculated Risk is our second-most polished game, and that is another very simple concept, which again took us a single month.  Spell Bound, which took us 3 whole months, is nowhere near the polish of either of those games, due largely to the fact that it is so much more complex.

5. Don't reinvent the wheel

This may be personal preference, but I see it as simply being resourceful.  There are countless resources out there, many of which are free, that you can be using to build your game.  Gone are the days when you need to build your own engine from scratch, now you can pick up Unity Free and get something semi-professional going in just a few days, with a little help from the asset store.  There is a cost with utilizing all these resources, however, and that price is that you don't actually learn how to make them.  But I don't think that is always a bad thing.  If you are looking to land a job in industry as a programmer, write your own engine from scratch.  Trying to get into the industry as an artist? Learn the ins and outs of modeling and texturing.  But if your primary goal is to make a game that people want to buy/play, then use as many resources as you can to achieve this end.  There's still plenty of learning to be done using this approach, as the resources typically need to be tweaked to all be fit together, which requires at least a basic understanding of how they work.  A perfect example from me personally is on Shibe Warz: I am not a GUI programming and I never want to be, so I picked up DaikonForge GUI on the asset store and it has enabled me to produce a much more professional GUI much quicker than I would have otherwise.  I'm not learning the ins and outs of GUI programming, but that is not my goal.  My goal is to make a fun game that has a nice, clean GUI, and by utilizing outside resources that goal is achieved much quicker, allowing me to focus on other, more important aspects of the game.

That's it from me! This ended up being much longer than I wanted it to be, but it was nice to get all of my thoughts in writing.  Hopefully this will help someone out at some point, as well.  Time for me to get back to what really matters: developing!  Thanks for reading!

-Nick