Recently I’ve been reworking the way Projectiles operate in my game to make the mechanics of aiming and shooting feel nicer.
In my game I have two kinds of Projectiles: Hitscan and Missiles. Hitscan Projectiles deal damage to a target immediately using Raycasting whereas Missile Projectiles behave like real world projectiles using velocity and all that fun physics stuff. Beyond that I have a number of parameters that can be modified to alter a Projectile’s behavior, for example a grenade would be configured to use gravity, bounce around and explode after a delay and a rocket would be configured to explode immediately upon impact.
With that out of the way, the issue I actually want to look at is one I’ve encountered with the accuracy of Missile Projectiles. The starting weapon of my game is a simple blaster weapon with infinite ammo that fires small missile projectiles that deal very little damage but they fire with 100% accuracy. This weapon isn’t exactly going to be your go to weapon for the entire game but it’s intended to be there as your last resort if you run out of ammo for all of your other weapons so it at least needs to be reliable, hence the 100% accuracy. The problem is that using Physics to detect collisions gives me sub-optimal, inaccurate results.
The aim model that I’m using first projects a Sphere Cast (basically a thick Raycast) using the current Projectile radius from the main camera until a valid point is hit in world space. From there the contact point is adjusted to give us the actual point that the Projectile needs to fire towards to hit its mark accounting for its radius. Once this is performed the Projectile is then spawned in, given its origin point along with the direction to the target and then it’s fired.
Now the problem…
As we can see here the projectile isn’t hitting its target point, it seems to be overshooting it which is problematic and it looks a bit shit. Now let’s take a quick look at that in slow motion by setting the game’s timescale to 0.1 which will automatically lower the fixed delta time from 0.02 to 0.002 (we’re now essentially just running the game at 10% speed).
Wait a second! Why is it hitting the right spot now? Well technically it isn’t, but it’s a hell of a lot closer to where it needs to be so let’s try it again but back at regular timescale with the fixed delta time set at 0.002 again.
Basically the same results but this is neither a reliable or a viable fix, we’re just running 500 physics cycles per second instead of the default 50, not good.
At this stage I began digging for solutions online but couldn’t find anything beyond changing the fixed delta time which as I’ve already mentioned is not an acceptable solution. The closest thing I found to a fix online was an old community script that prevents fast moving objects from clipping through colliders using Raycasting to catch objects as they clip into something then correcting them. So naturally I tried adapting this to work in my scenario but it didn’t really fix anything. I know at this stage that I’m logically going to have to do something using Raycasting to resolve the problem, I’m too stubborn to just live with my Projectiles being a bit inaccurate.
So, what if I just stripped out the collision stuff and just use the Raycasting? (I later switched to Sphere Casting)
Well I think the results speak for themselves, I feel like this is going to come back to bite me in the bum at some point but at least it’s working as intended.
In retrospect I could have tried using triggers instead of collision which might have improve the accuracy but it doesn’t stop the projectile from overshooting and getting stuck inside of things, and since I already have the Raycasting to check for clipping it just doesn’t make sense to me to have both.
Anyway if you know of a more performant solution or optimizations that’ll get me the same results, or just have questions feel free to leave a comment or shoot me a message.