When In Doubt, Check UnCodeX

I’ve been working with UDK for over four years now, and it still never ceases to amaze me. The reason is simple: there’s so much code given to us right out of the box, and untold thousands more lines marked “native” that we don’t even see. For those of you who have never spent a weekend digging around in the Development\Src\Engine\ folder, things can get overwhelming pretty fast.

So today I’d like to tell you guys a little story to reinforce a point I’ve made (and lived by) for quite a while: when in doubt, check UnCodeX. If you don’t know what UnCodeX is, stop reading right now and go find out.

All good? Good.

One of the things I’ve done in UDK countless times is make a third-person camera. I did it once just to experiment and learn about the camera class, and since then I’ve done it for who knows how many clients. It’s not particularly hard; there are tutorials galore online and even official documentation about it.

Play around with a third-person camera long enough, though, and you’ll notice something very odd about it: if you try to look at the sky the camera will hit the ground and (because we don’t want the camera going into the ground) start to roll across it. Eventually your camera will be oriented vertically and — lo and behold — you’re staring up your character’s butt. It’s not the most pleasant experience in the world.

Now normally I’d leave such a thing be because:

  1. If a player somehow manages to find himself in a situation where all he can see is butt, it’s his fault and he should get ambushed by the opposing team and die
  2. Most players aren’t dumb enough to try staring at the sky when bullets are flying

But sometimes we just can’t help it.

I recently got contacted by a client who wanted to prevent this at all costs (the reason he gave had little to do with butts, but I digress). “OK, no problem,” I thought. The camera code that handles collision with the ground looks something like this:

if (Trace(HitLoc, HitNorm, out_CamLoc, CamStart, false,
vect(12,12,12)) != none)
{
out_CamLoc = HitLoc;
}

In other words, do a trace vertically downwards and if we hit the ground, place the camera at that point instead. Simple, right? So why not halt camera rotation at this point as well? Cut to three hours later, dozens of failed attempts, and one really tired and confused me. The biggest problem was that, although I could constrain the camera to stop once it hit the ground, I couldn’t get it to start moving again. It was as if someone had dropped a big glob of superglue on the thing and it just stuck as soon as the trace was valid.

However, my real error was in assuming that I could code a working solution myself (i.e., without Epic’s help). So finally I turned to UnCodeX and began slogging through their own camera code. Below is pretty much exactly what I did:

  1. So far I had been working in the Pawn class, and I knew the problem was Controller.Rotation; that is, how to stop the controller from rotating as soon as the camera touched the ground? Knowing that, I searched for PlayerController in UnCodeX.
  2. I did a search for “rotation”. One result that really interested me was LimitViewRotation(), as it had the comment: “Limit the player’s view rotation. (Pitch component).” Aha! Exactly what I wanted to do!
  3. I found that LimitViewRotation() was called by ProcessViewRotation(), which only called it if the PlayerController had no reference to a camera or a pawn. But since we did have a pawn, I knew this line would be called: Pawn.ProcessViewRotation(DeltaTime, out_ViewRotation, DeltaRot);
  4. Jumping back to the Pawn class, I saw this line in its version of ProcessViewRotation(): out_ViewRotation = PlayerController(Controller).LimitViewRotation(out_ViewRotation, ViewPitchMin, ViewPitchMax);
  5. Since ViewPitchMax was not a parameter or local variable, it had to be a global variable in the pawn class. So I experimented, setting ViewPitchMax=2500 in my own pawn’s default properties.
  6. And what do you know? The camera appeared to stop right above the ground.

Of course, it’s just an illusion. We’re not really stopping the camera when it hits the ground, but when its upward pitch is around 13.7 degrees. But in this case the illusion was strong enough to do the job in one line of code.

Moral of the story? UDK is powerful, and more often than not it already has support for what you’re trying to do. The only problem is that said support is usually buried neck-deep in a bunch of code, which is where UnCodeX comes in. Learning how to use it well will save you heaps of time and ultimately make you a better coder.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s