Friday, February 24, 2012

sound advice

        Hey gimme a break, i went to bed at like 1 last night and i've been in a bit of crunch this week.  I keep saying that one of these days I'm going to start a job during a project that's NOT in crunch, but you know, it's a fun crunch.  Had the first dog-n-pony with the execs and I gotta say our team is working on some cool shit.  We got to postpone our demo for a week, which is good because I've only been in the code for about a week and a half, and the scope of our demo is pretty impressive.  I mean, not really, but given the time we've had to put it together...

Photobucket
It seemed like a manageable project at the time..!

        So I'm still working on the Kinect camera tutorial, I'm actually going to go in and tighten up the implementation, along with the graphics on level 3, so I'll have a bit of a better presentation.  It's a bit sad that I didn't have more time to really come up with some cool camera control, was hoping to do a little more than just build a mouse driver type thing, but you know, it's a good starting point.  I feel like the implementation I came up with is pretty solid, it's a good hybrid of a few different paradigms that make good sense.  Anyway, hopefully that's a fairly tantalizing preview.  I'll go over the basics of how to setup the zigFu/OpenNI stuff too so you can further hack away on Kinect.  If you haven't messed around with it yet, you should, I'm surprised it took me this long to get into it.


Thompson Eye Phone and Sogo-7s optional...

        Alright, so to some possibly meatier content, although I may be the only person who's run into this issue.  If that's the case, you guys are all jerks for not posting solutions!!  One of the things we've been beating our heads against somewhat for the last couple days is how to manage sound, in particular sound on events, such as collision.  Now, that's a fairly straightforward problem that you could solve in a few different ways, but here are some ways NOT to solve it:
  • The rather naive and seemingly obvious audio.Play() in Update(), it only seems obvious at very first glance
  • Immediately prior to a seemingly obvious Destroy() call.  Again, it only seems obvious at very first glance
        So, the first method we came up with was a bit brute force I'll admit, but if you know me, that probably comes as no surprise.  We setup a GameObject that's basically an audio container, so actually it's a GameObject and a script that exposes a bunch of public AudioClips.  You probably see where I'm going with this, if you guessed AudioSource.PlayOneShot() or AudioSource.PlayClipAtPoint(), pour yourself an expensive single malt shot.  For some reason, this made the audio sound really wonky, and it wasn't a 3d issue or a playing multiple clips issue.  We could have wrapped either one of these to get a bit more control over the AudioSource, but I felt like that was probably overkill.  For a larger project, I could see the benefit of this though, and it's definitely something I'll be exploring more.  I have a ton of questions about this pattern, performance issues mainly.


Brute Force? Heh, more like ME Force, amirite??

        The second method is about as straightforward, but I had some perf concerns again.  It's funny how I'm still in game developer mode and trying to make the transition to blue sky R&D developer mode.  Performance? Hah, we care not for your framerates and memory budgets!!  Or something...But yeah, basically we ended up attaching multiple AudioSources to the prefab and managing it in script.  The code was pretty simple, something to this effect:


        Obviously this is super naive and you'd want to do a bunch of other checks, but you get the idea, it's sketch code, whadyawant? I'm not very sanguine on this method largely due to the multiple AudioSources on each prefab, again, perf concerns. I may just be paranoid still...

        The solution we ended up going with is not ideal but serves as a bit of a springboard for a pattern I might have used if i had been thinking about it.  For each collision behavior, we exposed an AudioClip for that behavior, then switched out the object's AudioClip in the OnCollisionEnter() based on the name of the colliding object, i.e. We have an object in the world and based on the projectile's name, we swap out the AudioClip and play the AudioSource.  Again, i don't feel like this is super ideal because then we have assets all over the place, but it definitely made life easier for me because I could just concentrate on a behavior at a time. So we're looking at something like this:


        Again, super-naive, there are better ways to do the specifics, but you get the idea.  This seems to be working for now, so i'm going to just STFG and keep in mind what I've learned.

looks-good-to-me-ship-it

        I think, in retro, I would have gone with some method that was a hybrid of all of these, maybe have an audio manager type script attached to the prefab that exposed all the AudioClips i wanted to play then have each collision behavior poke into the audio manager.  I like the idea of keeping collision behaviors as separate script just because i hate looking at big scripts that manage everything.  That could just be me, honestly, I ain't to guud at readin teh codez, not bein a real programmer and all...

        Thoughts?  I'd love to hear from anyone else about how you tackle this sort of thing.  At some point i want to go back into library/SDK developer mode and start wrapping up a bunch of functionality like this for future Unity projects...

Saturday, February 18, 2012

skipping the obligatory intro post, let's dive right in

        So i've been getting my hands dirty with Unity again in a pretty big way.  Seriously, now that i've left the games industry, i'm actually making...well game-ish type things again, and somewhat having fun in the process.  Oh who am i kidding, this is probably the most fun I've had in the last 5 years or so.  Can't put too fine a point on what I'm doing at the new gig, but suffice it to say I'm doing some interaction design stuff that draws heavily on my experience in game development.  It's fun.

        But I'm not here to tantalize or be faux subversive in a rather clumsily veiled attempt to get people to ask me for more information.  Rather, I think i'm going to use this space to share random tips I come across during my game-ish interaction prototype development experience.  Probably some Unity randomness, tons of Maya randomness, and who knows, maybe some of that Python stuff i seem to love so much.

        Alright then, as the title states, let's dive right in.  One of the really interesting things I came across in the Unity reference manual:

"The most convenient way for animators to work is to have a single model containing all animations."

        Hmm...my 10+ years supporting animators in various degrees tells me otherwise, so of course I setup my character with individual animation files.  No referencing or anything pretty like that, this is a pretty quick n dirty project, so no infrastructure or pipe really.  We'll make that up next project, but that's for another post.  Anyway...

        If you're familiar with Unity, you may be aware that when you import an animation, it comes in as a Read-Only asset.  In short, it means you can't add animation events or otherwise edit the animation in Unity.  After a few hours, well ok, maybe only one, I found the accepted workaround, which is to duplicate the animation clip and thereby creating a new animation clip that's writeable.  I quickly found out that many of the explanations i found online where contingent on creating animation the Unity approved way, i.e. one long animation file.  That gives you an asset with a bunch of animation clips as children, like so:


         With this layout, it's pretty easy to break the Read-Only state, you simply select the clip and Edit > Duplicate or Ctrl+D and you're good to go.  The toolflow issues arise when you want to make an animation clip Read-Only and the animation is stored in a separate file.  In that case, you get an asset that looks something like this:


        In this case, you have actually have a bunch of individual assets that Unity collates into a single-ish asset.  The question now is how do you duplicate one of these to break the Read-Only state?  Well, selecting the actual asset and duplicating doesn't do it, it just creates another Read-Only animation entry.  We can attempt to duplicate the entry in the Inspector:


       ...But that just gives us the same end result:(  So what's a bear to do??  Good question, the secret actually lies in the animation asset's hierarchy.  If we expand one of the animation assets, we get all sorts of fun things:


        If we look down near the end of the animation asset's children, we find what we seek, the actual animation clip itself.  THAT'S what we want to duplicate, so we select that and Edit > Duplicate or Ctrl+D.  Now we have a discreet instance of the animation clip:


        Now we just have to drag this instance into the appropriate slot in the character's Animation block in the Inspector, and we're good to go:


        Now we can add Animation Events to our heart's content.  Keep in mind we lose all this data when we reimport, so it's probably a good idea to come up with some sort of automated process for this.  Good case for some sort of metadata system...Maybe we'll talk about that at some point, I do need to learn Unity Editor Scripting, but honestly, I have no idea when I'm going to get back to building big systems again.  So anyway, that's what I got for now, like i said, it's a pretty specific case, but I imagine i can't be the only person who's ever run into this.  Hopefully this helps.

        Hope someone found this useful, next up, some thoughts on SoftKinetic and the iisu SDK...Stay Tuned!