Visible Bullet Tracers and Lasers Clarification

I know this question is probably very redundant, but please hear me out.

So I’m working on space adventure game with heavy combat elements with intentions of expanding it with role playing elements as I go. I’m a graphic designer with strong knowledge on programming with Javascript from my time spent in web design and I have been learning the ropes of Unity. Introductions said and done, here is my question:

I’m trying to understand some of the pros and cons, along with the finer details of methods used for lasers, bullets, and so on.

  1. The first method I see most commonly
    is using a particle system with
    raycast. I have yet to spend a lot
    of time using raycast, but from what
    I understand, it detects a collision
    with an object and if the fire
    button is pressed, it applies damage
    to the object colliding with the
    raycast. My main problem with this
    is that the damage is instant and
    you can’t dodge the projectiles, not
    to mention running into the
    particles themselves does nothing.

  2. The second method is to use a
    particle system with a particle
    collider, but with this you can’t
    detect where the particle is
    colliding for generating impact
    effects (they impact in the center
    of the object they’re colliding
    with, not the point of collision).
    I also noticed that the reference
    manual says that particle collision
    uses a lot of overhead, but the
    particle system only uses one draw
    call(?).

  3. The one I see second most commonly is an object with a trail renderer. My question is what kind of object do you tie it to? An invisible mesh? An empty game object? Does it have a rigid body? My main problems I’ve seen with this is draw calls and objects skipping past collisions. On the plus side however, speeds could be easily adjusted and effects (sparks, explosions) would be easy upon destruction and lights could be added.

  4. The last one I’ve seen is a line renderer which seems to use similar methods to method #3.

So finally, here is what I am looking for specifically:

  • Lasers/bullets that have a tracer and are clearly visible.
  • Adjustable speeds and can be dodged (if slow enough).
  • Have an impact effect of some kind on point of impact (sparks, explosion, etc).
  • Can be given some kind of small, randomized angle to make them slightly imperfect (if I choose).
  • A lot of these projectiles will be on screen (huge capitol ship battles, turrets, etc)
  • A PLUS: If it’s not too heavy on overhead, emits light.

Any help will be GREATLY appreciated. I’m building it for computer, so I’m not trying to cram this onto an iPhone, though I’d still like to try and keep it optimized.

Well, this is a bit of a huge question. I’ll try to address it point by point!

Assuming you have a single script which you set up in the inspector for different kinds of projectiles (despite how horrendously unrealistic slow lasers are, but that doesn’t matter), your script needs to have the following-

  • Starting Velocity (determined by the direction of the gun * bullet speed, modified by a random value)
  • Impact particles (just a one-shot particle effect, instantiated on impact)
  • Renderer (including a material)
  • Accurate collision detection (as in, better than what rigidbody physics can provide for you)

Now, it’s kind of a 2-stage thing, since both the gun and the projectile play their own parts in this. You should be able to set up the gun so that it can shoot any kind of projectile which meets certain criteria, and set up the projectile so that it meets some common interface or standard. Exactly how you do this is up to you- you have quite a few different options.

The gun needs to know a few things-

  • What direction it is facing (easiest to just use the Transform for that)
  • How accurate it is (a number between 0 and 1, where 0 is shooting in a random direction and 1 is always shooting straight ahead)
  • How fast the projectile is moving when it is spawned

Given this information, I would then do something like this to acutally do the shot-

void ShootBullet()
{
    Vector3 shootDirection = Vector3.Slerp(Random.insideUnitSphere, transform.forward, accuracy);
    Vector3 shootVector = shootDirection * shotPower;
    GameObject bullet = (GameObject)Instantiate(bulletPrefab, transform.position, transform.rotation);
    bullet.SendMessage("SetVelocity", shootVector);
}

This will instantiate a prefab, and then send a message to the newly-created object telling it what direction to move in. Now, this message can be implemented any way you like- so you could have a rigidbody-controlled projectile, in which you would just set its velocity to the shootVector, or you could be using a transform.Translate-controlled one, which case you would do something different.

Now, the collision detection thing is another thing you need to look out for- to avoid the ‘bullet through paper’ problem, you need to do more than just rely on Rigidbody physics to manage everything for you. The way I do this, is using Physics.Linecast between the object’s previous location, and its current location.

void CheckCollisions()
{
    RaycastHit hit;
    if(Physics.Linecast(previousPosition, transform.position, out hit))
    {
        // we hit something, get information back out of it
        //   now we can apply force, deal damage, spawn particle effects etc.
    }
    previousPosition = transform.position;
}

As for the optimisation problem, I wouldn’t recommend adding lights to lots and lots of projectiles, but you can do that on key ones to draw the eye to them. Depending on the shader, you can do self-illuminated glowing textures, or particles- but in the end it really just comes down to testing. See how many bullets you can manage!