I’ll start with a disclaimer this time, because anybody who knows me knows that I will absolutely go on long, rage-filled rants about this subject if given even half a chance. I guess here’s my half a chance, but I’ll dial back the rage.
What’s Hit Detection?
Put simply, detecting whether a volume intersects another volume to produce a ‘hit’. I realise that’s very dry, so imagine you’re in a game, and you try to hit an enemy with a sword. Hit Detection is what’s running when the game is trying to calculate whether that sword swing should count as a hit or a miss (putting aside good old dice rolls, anyway). Should be simple, right? Riiiight? (You’ll have to imagine the knowing eyebrow wiggle, nobody needs to see that at any time).
Boffers?
Yes okay, I’m very much making stuff up when I use the word Boffer.
Well, sort of.
Boffer is a mostly American LARP term, meaning those big padded swords that you actually use to hit each other when you’re pretending to be knights and goblins or whatever. They can end up looking quite silly in their hugeness. I couldn’t find a good stock image, and I didn’t really want to make someone’s hard work sound laughable. So imagine those things in Gladiators that they use to hit each other. Something like this:

It’s big, it’s foam, it bears a passing resemblance to a sword, you can hit people with it. The problem I have is not any of those, it’s when you try and transpose the same logic onto a video game.
What do foam swords have to do with video games?
Everything, and ideally, nothing. One of the most common things I see when I see people making sword-based combat games is admittedly, a complete no-brainer. It’s basically the first thing you’d think of. It mostly works, mostly.
Just stick a capsule collision volume to the sword (to act as invisible foam to your boffer), and let the animation do the work. Brilliant, right?

Et voila! A hitty thing! Just detect when the capsule touches something, there’s your hit. Why are you complaining so much Pix?
Your hitty thing has a few minor drawbacks, and I mean minor drawbacks in a very British way. But it’s hard to explain without a little explanation about frames.
Frames
In theory, you should never have to worry about frame pacing, right? We live in a world where computers are (more or less) powerful enough to do whatever we want. In practice, <insert unhinged cackling here>.
Think of a game as like an interactive flipbook animation. It ‘flicks’ through each page of the flipbook at a given rate (framerate), and that produces the motion on screen. Where games diverge from movies, flipbooks, zoetropes and the like is for each page (or frame), the game is making decisions about what should be shown next.
In an ideal world, these frames are shown at regular intervals, but say, for example, your paper flipbook costs a lot of money to turn to the next page. If somebody doesn’t have that much money, they may skip a few pages to save a bit of cash. To keep everything nicely lined up, we can lengthen the time it takes to get from frame to frame to make sure the timings still work and we don’t just have the subject of our flipbook teleport around.
So applying this to a video game:
Your game has a framerate, it could be 30fps, it could be 60fps, it could be anywhere between 4fps and 120fps. You can’t even safely assume that the time between frames is the same every time, unless you’ve locked the framerate (which is its own can of worms, tl;dr players *really* don’t like it).
Why does that matter though? Because it determines the locations your sword is physically in when it calculates the hit. You don’t (typically, I’ll get to it later) sweep the entire path of the sword, you just receive whatever locations the animation produces frame by frame.
Imagine your character is swinging your sword, the framerate is normal (we’ll assume a solid 60fps to make it easier). Just assume every diagram I’ve lovingly MSPainted here is from a top down perspective. What you actually get back out of this is something like this:

Pretend I drew the character’s arm in there if it makes it easier. Hopefully that shows you what the capsule on your sword *thinks* its location is at those given times. This is the approach that a certain very popular series/engine uses to solve the problem of hit detection. Note the gaps between the capsule positions.
Now let’s place an enemy somewhere where you’d think you can hit them:

Starting to see the problem? If that enemy just happens to be in between those frames when you swing the sword, you’ll miss, but it looked like you hit, bad feels are produced all around.
I’m maybe overblowing this a little, if the sword’s path is sufficiently slow and the framerate sufficiently high, it’s rare (but not impossible) that you’ll hit this situation. So if your game is about zombies fighting each other underwater, in slow motion, you can probably disregard everything I’m about to say.
As a side note, there’s something else about this that bothers me. If I place an enemy here:

Then you’ve hit him, but the sword didn’t even touch him. Imagine you’ve got an attack that has a massive backswing. You’ve hit the guy behind you for no reason whatsoever, and now he’s standing there looking a bit bloody and confused. But so are you, you weren’t expecting to hit him.
But Boffers aren’t completely unsalvageable, even though most of the attempted fixes just make the problem worse.
You could attempt to plug the holes by making the capsule wider, then you have full coverage over your entire swing, nobody in front of you gets missed. But this just exaggerates the problem of hitting enemies you didn’t expect to hit.
Not that then.
Maybe you could try lerping (linear interpolation) the location to cover those inter-frame gaps. In effect, a lerp in this case means to slide the capsule from the location in the first frame to the location in the second frame. I’ll just call it a lerp from now on because it’s shorter. In my first set of diagrams, that would work okay. I’d go so far as to say that’s acceptable so long as you don’t push your luck. So let’s push our luck.
Let’s discard our lovely stable framerate for a second, and say we’ve produced this:

What happens if we lerp the capsule between these two locations? It doesn’t follow that arc, certainly, not without a certain degree of mangling. Given the shortest path in the rotation, at some point you’re going to end up with that capsule pointing out of the character’s butt. There’s a somewhat infamous example (although I don’t think it lerps) where a certain demon can hit you with his butt but only at a very specific point in his animation. His butt is certainly not where his weapon looks to be to the player, so it feels unfair (even if it is quite funny to those of us who have debug tools).
So not lerping then, unless we can really be disciplined about what our animations are doing, and what our framerate is (ha).
A more recent solution that I’ve run across is one I like a lot more, but it has one major downside. Instead of relying on what the game produces in any given situation, you sample where the capsule *should* be using the animation as authored. If you sample at a fixed framerate, you can ensure full coverage.

In principle, I don’t mind this. In practice, trying to work out what that fixed interval to sample at should be is a bit of a nightmare, because it depends on target framerate, what the animation is doing and how large your collision capsule is.
It has one major flaw though, in my mind. Consider the player who is playing on a PC with all the power of a potato. Given the gap between frame 1 and frame 2 will be larger, as the framerate will be lower, you end up doing *more* work per frame as you need to check more of your sampled locations to cover the gap. I’m not sure I like making the less powerful machines do more work, it seems counterintuitive at best.
So what’s the answer?
In short, there isn’t one. Yeah, I know. Sorry.
In a bit more detail, there is one if you’re willing to make sacrifices. In essence you sacrifice a little bit of realism for the sake of gameplay feel and gameplay reliability.
In other words, Fake It.
Typically (but not always), there is no reason to go full realism on hit detection. You can get quite far by just making it up.
This is a really stupid diagram but, by discarding what the animation is doing, and what the weapon is doing, you can just describe a simple 3D shape (volume) for a given number of frames to make up your overlap check:

I tend to use these pizza slice things, but you could do spheres, cylinders, cubes (yes, even capsules, just don’t sweep them).
The downside of this is that you don’t get the impression of sword movement, you can’t do a lovely side to side sweep and see each enemy get hit in turn. It’s good enough for most things, and doesn’t have the problem of gaps or wrong hits. But it is boring.
So maybe we can inject just a little bit of the animation data to make this something a bit more special.
Sample the location of the weapon every frame, it doesn’t need to be pre-sampled, and then build your volume out of that. This produces full coverage, even if it’s still technically faked, but you still get your sweeping hit:

Here, the first enemy will receive a hit on frame 1 (he was hit at some point between 0 and 1), and the second enemy will receive a hit on frame 4 (he was hit at some point between frame 3 and frame 4).
Sure there’s limitations to this too, but there’s probably a followup to this post where I address that and ways to improve it.
But the takeaway is, just because a Boffer is the first idea, it doesn’t make it the only idea.
Leave a Reply