Floatlands has another addition – Projectile system. Until now, only weapon animations were present in the game, without actual bullets, so the shooting experience wasn’t quite genuine. This chapter will go over projectiles that launch from a weapon, how they bounce from other objects and surfaces, and how much effect do penetration angles have.
The projectiles are drawn with a white line. Velocity verlet integrator was used for simulating bullet forces because it produces almost no error and is simple to implement. If you wish to learn about verlet velocity, this is good article to read: Doing gravity right
Projectiles also support bouncing off the surface. If the angle between a bullet and a normal is right enough, the bullet will bounce otherwise it will stop. Random error is added to velocity after bounce too, so that it’s path is less predictable. Shooting bullets into cave gets interesting, because bullets bounce to every imaginable direction.
Lots of games don’t have this feature of Projectile penetration, it’s a very good gameplay element and this is why it was added. It becomes very fun to play, because you can damage an opponent through a wall. Lets look at some examples, so you can get a taste of what this feature can do.
Penetration calculation includes a huge amount of math. Angle between a normal and projectile direction tells you how orthogonal to surface the bullet is. There is more chance that a bullet will penetrate, if it is orthogonal to the surface. Also, each projectile loses »mass« so that its weaker after penetration. It can also happen that a bullet doesn’t penetrate but bounces off instead.
Shooting quad walls:
There is also another raycast from another side of collider, (reverse direction of bullet) so that code can determine how deep penetration will be. The deeper, the less chance that it will penetrate (or not at all).
A little bit of programmers speak:
Every MonoBehavior that will be penetratable needs to implement this IPenetratable interface. Then you can just call GetComponent<IPenetratable>() on collider and if it’s not null, you can go on and calculate penetration from porosity and max depth.
public interface IPenetratable
// [0, 1] - measures emptiness of volume
// (0, +inf)
// max depth
Game also includes dynamic crosshair; it reacts to player velocity. Here you can see the crosshair of shotgun reacting in action.
- Bullet spread – how much spread independent of current state. Shotgun projectiles still spread even if you crouch.
- Weapon spread – how much player movement affects weapon accuracy.
- Recoil kick: How much it moves your crosshair/mouse permanently.
- Recoil kick deviation: Randomized kick ammount (deviation is from statistics).
- Recoil deviation: Temporary displacement of your cursor. This is usually big because it returns to back where you were aiming exponantially fast.