Using line trace as hit detection - problem between frames.

So I have a hit detection method setup which takes two points on my weapon, draws a line between them, and sees if there is any collision. 99.99% of the time, it works perfectly. But… if I run it on a slow (< 10 fps) machine, I run into problems. Every tick, if they are attacking, I’m checking to see if this line collides with them. Problem is when there’s ~100ms between ticks, it hardly ever draws that collision detection. Therefore when I swing at someone beside me I can see it drawing a trace really early on, and really late, but none that would collide with the player. Is there a way to say okay I’m on to the next frame - how many traces did I miss, go and calculate all those traces? Or a way to detect collision between two lines perhaps (that might not be 100% accurate tho?). I’m open to ideas/suggestions, would prefer for this to be 100% as I can see lots of little scenarios where they could play out poorly for the player.

How accurate do you need your checks to be? You could do an approximation type line-check. Where every frame you’re doing roughly 3-5 traces each in the motion of your swing towards where you’ll be “next frame” or so. That way you have some lean-way that will help keep the feel of a true swing, but also reduce the feeling of being cheated when a swing doens’t connect because of frame rate discrepancy

edit:

also, I remember the game Chivalry having the same exact issue you were having which started off being made in UDK I believe, and they made a blog post about it. I’d recommend googling for it, see what their solution was. Which if I remember, was vaguely what I suggested.

They don’t need to be 100% but, they need to be decently accurate. I want to display blood splats and generate sounds from the hit location. The main issue is registering the hits.

Yeah that’s kind of along the lines of what I was thinking of doing, except I was thinking of actually going backwards. So go back a few frames to see if they hit something, and act accordingly.

I’ll see if I can’t dig up that blog post, as the game I’m making is very similar to Chivalry :slight_smile:

I found the post and the dev mentions:

“Thats correct, since we’re drawing traces from one position to another it doesn’t matter if the player pivots or the animation is fast. The line will be drawn from where the weapon was on the previous tick to where it is on the current tick everytime. This is much more accurate than a single positon per tick method as it eliminates the player pivoting issue.”

So, is he drawing continuous lines from the previous point to his current point? That’s initially what I was thinking of doing, but it seems like it could be a bit wacky if you give it some odd angles.

Angle shouldn’t matter if i understand correctly, as every tick that happens you’re going from where it was to where it is and checking between. If you keep the same relative point of the mesh (say the pointy bit of a sword) and use that as your guide constantly, then you’re always going to be in the path of your sword doing that method.

First: Games won’t run well on slower machines. There is a reason games have “min spec” requirements…
Second: You may want to try to enable sub-stepping for physics. If you make the maximum sub-step size something like 0.04, then you know physics will always run at 25 Hz, even if rendering runs slower.

I ended up implementing the method I mentioned above. I am just lerping between the last known position and the current position every tick. Seems to work well at high FPS, will test tomorrow with low FPS. Seems really accurate and efficient actually!

Well please do let us know! Always fun to see how things progress out.

I played around with quite a few different methods for low FPS, and this seems to be by far the best. Even at 6FPS I’m registering hits fine :slight_smile:

Just to clarify:

I have two sockets on my sword to signify the start and end of the blade. Each tick, I am lerping between the last known position and the current position, doing a hit scan with each increment to see if it hits the player. That’s it really!