Launch a projectile from one object to another

G’day guys, I’ve been trying for some time to devise a script that would enable a turret-like object to instantiate and launch a projectile prefab at a target that enters its collider. I’ve seen people use LookAt() for ‘traditional’ turrets, but my objects can’t afford to ‘look’. In fact, an ambition further down the line is to create multiple ‘fire points’ on each ‘turret’.

Anyway, I’ve tried a few different methods, to no avail. Combining a LookAt() that instantiates a gameobject pointing in the same direction as the turret was my best idea, but I can’t help but feel there must be a clean, efficient way to do this, perhaps by drawing a raycast from the turret to the target, and somehow moving the projectile down this path?

Anybody have any advice as to the best way to do this? I just need to be pointed in the right direction.

Cheers.

You can create a vector turret->target and use it to instantiate and fire your projectile:

var turret: Transform; // drag the turret here
var prefab: Rigidbody; // drag the projectile prefab here
var speed: float = 10; // projectile speed
var dist: float = 2; // spawn point distance from the turret

function OnTriggerEnter(col: Collider){
  // calculate the direction:
  var dir = (col.transform.position - turret.position).normalized;
  // calculate the rotation:
  var rot = Quaternion.FromToRotation(Vector3.forward, dir);
  // create the projectile
  var proj: Rigidbody = Instantiate(prefab, turret.position + dist * dir, rot);
  // make the trigger ignore the projectile:
  Physics.IgnoreCollision(collider, proj.collider);
  proj.velocity = speed * dir;
}

This code must be attached to the trigger volume, and any object entering this trigger will receive a welcome projectile. To avoid collisions with the turret object, the projectile is instantiated at dist distance from the turret.

Notice that in this case the firing code is assigned to the trigger, not to the turret. If you want to keep the actual firing code in the turret, you can use SendMessageUpwards just to tell the turret who’s the target, and let the turret script aim and fire:

// Trigger script:

function OnTriggerEnter(col: Collider){
  // tell the turret script who entered the trigger:
  SendMessageUpwards("TargetFound", col.transform);
}

// Turret script:

var prefab: Rigidbody; // drag the projectile prefab here
var trigger: Collider; // drag the trigger object here
var speed: float = 10; // projectile speed
var dist: float = 2; // spawn point distance from the turret

function TargetFound(target: Transform){
  // calculate the direction:
  var dir = (target.position - transform.position).normalized;
  // calculate the rotation:
  var rot = Quaternion.FromToRotation(Vector3.forward, dir);
  // create the projectile
  var proj: Rigidbody = Instantiate(prefab, transform.position + dist * dir, rot);
  // trigger must ignore projectiles!
  Physics.IgnoreCollision(trigger, proj.collider);
  proj.velocity = speed * dir;
}

This second alternative is more versatile, because you can do smart things like checking the target tag to not shoot turret’s friends, or turn the turret to the target before shooting etc.