Monday, November 26, 2012

Weapon animations are (basically) in!



After much tedious pixel painting of blocky arms and hands over guitars, I now have characters who can walk, run, jump and idle while holding their instruments.

Some problems I dealt with during this "minor" task:
  • Forgetting how I set up the run animation. This was an embarrassingly big one, I had the guitar sprite animating properly during the walk cycle, but when the player started to run it got all funky and out of sync. I was in the dumps over this for hours; was there a timing problem when using multiple anims with RagePixel? Was I calling the run anim in a different way than the walk? Was there some holdup causing my Update function to skip a tick when accessing certain other functions? I came to believe I might have finally hit a wall, and was contemplating the ugly option of starting all my drawings over, making the character sprite big enough to hold a weapon, and just adding "with weapon" versions of all current anims to my original sprite sheet.

    Thankfully, my memory came to my rescue: last week, when I was setting up the player run animations, I decided to change the framerate for run to be slightly faster than walk so it would look more natural, because the sprite was moving faster. I then promptly forgot I had done so. Once I remembered this I was able to simply adjust the framerate of the weapon animation and everything locked into place. This is the best argument I could muster for working in a team of at least two: you never know when you're going to have a show-stopping "senior moment" that can cost you a day, but that would be solvable by anyone else who knows your code base and isn't wearing tunnel vision goggles.
  • Calling on types instead of instances. In Unity C#, when you want to get reference to a script that lives on a GameObject, you declare it with the name of the script file as the type, which is something you created yourself, so in my case, rather than something like
    public MonoBehavior playerControlScript;
    where MonoBehavior is the generic type for all scripts and playerControlScript is my script name, you instead have to use
    public playerControlScript playerScript;
    or some such, where the "type" is the name you made up previously for the script, and the variable name is a new made up name for the container that holds a reference to that script, within the current script that you're writing. Easy enough to work out, but if you're new to it it can get really confusing because my default assumption is that anything where I made up the name is a thing I can use for reference rather than an immutable static type. Therefore I would write something like this:
    if (playerControlScript.jumpActive)
    and then freak out when Unity told me "An object reference is required to access non-static member", and run around with my head on fire for far too long until realizing the simple solution is instead to write:
    if (playerScript.jumpActive)
    because I was trying to use a type instead of an instance without realizing it. Hopefully I'm over that one now.
  • Realizing way too late that for more realism I should have placed the instruments behind the player's entire body when they are facing the other direction, this way it appears that the players flip their instruments from shoulder to shoulder as they turn. This is actually less of an "oops" and more of a "well, if I were willing to double the number of animation frames and completely change the way I do directional facing, yeah that would be pretty rad". This is one of those moments when you realize you have to put a lid on a feature somewhere, or else you will continue to refine and improve it forever at the expense of the rest of the game. Something tells me there will be a lot of those moments coming up. 

No comments:

Post a Comment