I’m not too busy moving house to keep poking at No Excuses. Obviously once I got movement working, I had to begin working on the most important, primal interaction of them all: GUNS.
Shoot That Poison Arrow
The best thing about Unity is that, much like World Editor before it, you can spend very little time with it and still produce tangible results. A half-hour here, an hour there, these increments are usually quite enough to produce something. Something imperfect, sure, and certainly something inefficient and wonky — but something that is enough to spur you on.
I figured that the most basic projectile in the RDZ Industries arsenal, the cannon shell, would be easiest. Strap a ribbon emitter to a rigidbody, give it velocity and let the physics engine do its thing. Register the first impact and then… boom.
Of course that would be too easy. Y’see, the cannon shell actually needs to travel pretty fast to be convincing. We’re not going into hitscan territory just yet (I fully intend to introduce laser guns to the setting later), but we are wanting a shell to cross the screen in barely a quarter of a second.
It seems simple enough, until you think it through. Crossing the screen in under a quarter of a second means crossing the screen in four or five frames — that means crossing the screen in four or five discrete increments. That’s not really a speeding bullet anymore, that’s teleportation.
I mean, sure, it all looks fine when you let it play. The ribbon trails behind perfectly, filling the gap where the shell didn’t really travel, fading gently at the end to give the perfect illusion of the shell having hurtled continuously through all that air.
Then you discover that teleportation… Well, the cannon shell never actually hits anything. It can’t, not really. Nine times out of ten, it’s teleported past any obstacle in the world and disappeared off into infinity.
There is supposed to be a built-in solution to this, one that does what I ended up doing manually, but when I tried that it just didn’t make any difference. “Continuous Discrete” interpolation, they call it — instead of only checking collisions where the object has ended up, check all collisions along the path it’s about to take.
No deal, though. My cannon shell just kept on flying through walls. Grumble.
So I did it myself.
Register the projectile’s position in each frame, checking it against the position from the last frame. Do a raycast from its previous position to its current position, find out if it should actually have collided with anything — if it did, then remove all velocity and DIE.
3 thoughts on “Blog 597: The Story of a Projectile”
Raycasting/Tubecasting is pretty much standard for projectiles in Unity, I’m just not sure if performance-wise it scales well.
And for some reason non-convex mesh colliders are horrid at collision detection.
Well, I’m hoping to make up for any performace woes with late-90s graphics. We’ll see how it goes…
Cool model and game play. 😀