January 19, 2015

How to design realistic high-speed bullets in Unity

Let's say you have made a target in Unity and now you want to fire a bullet against that target.

You have two options to choose from. The first option is to completely ignore gravity and fire a ray against the target and see if it hits (You can maybe calculate the theoretical time it takes for the bullet to hit the target before you fire the ray). This will work fine if you're not firing at distant targets because gravity will not make a large difference over small distances. But ignoring gravity is pretty lame.

When I first faced this problem I thought I had to calculate the theoretical bullet trajectory curve (after going down to the basement and bring up my old books on mechanics and physics). Then I realized that I should use Unity's built-in physics engine.

But there is always a but. When you fire a high-speed bullet in Unity (using the physics engine) you will notice that it will not always hit the target. The reason is that a game is similar to a movie. A movie consists of a number of images per second, and it is the same with a game. So your bullet will not fly continuously like in the real world, because it will jump between each frame to its next position. It will look like this (each white ball is the bullet's position each frame):

But solving this problem is easy. What you need to do is to fire a ray (1 frame before the last bullet's position) against the last bullet position and see if it hits anything. So this system will be delayed by 1 frame, but no-one will notice that because there are at least 30 of them per second. 

If you want to be even more accurate you can interpolate between these positions and add more bullet positions. I believe the easiest method here is using De Casteljau's algorithm. The result will look like this:

If you want the trajectory curve to be even more smooth you can use De Casteljau's algorithm again and again and again...

Looks interesting? You can test it here.

No comments:

Post a Comment