Prevent a game object collide against specific colliders.

I have two “turrets”, which can turn around and spawn missiles in any given direction (360 arc of fire). Around this, I have four box colliders (north, south, east, west) to detect hits from other turrets.

My problem is that, as the spawner for the missiles are inside the turrets, when I fire a missile, the missile spawns and collides with the colliders instead of just passing through.

I tried using InstanceID’s to detect when the collision is against the turret that spawned the missile (using a System.GUID created when the turret is instantiated that is also passed to the missile on creation).
I do something like this:

public OnCollisionEnter(Collision col) {
  /* Collision detection stuffs, so I can grab the collider, identify it
     and initialize the "turret" variable.*/
  if(turret.InstanceID.ToString().CompareTo (_owner) != 0)
    /* Do missile stuff */
  else
    return;
 }

The thing is that the collision is detected and the “return” statement executed, but the missile “gets dumb”, collides against it and ricochets inside the turret (Colliding against the other colliders of the turret) losing speed.

Both turrets are copies of the same prefab/game object instantiated at runtime.
The missiles are instantiated when the player press fire via the “instantiate” function using a linked GameObject in the turret GameObject and then a custom initialization function called “init” in which I put all the data the missile needs to hurt other players and move around (and the “owner” GUID).
Basically:

GameObject rocket = (GameObject)Instantiate((Object)missile, position, rotation);
rocket.GetComponent<Missile>().init(/*parameters such as speed and damage*/);

I can’t (afaik) use layers, as both turrets comes from the same prefab. Right now, I don’t know if I can assign a layer on runtime to a specific gameObject (and if this is an “elegant” way to handle it).

I can’t switch off the colliders for a frame, then switch on them again, as there is a chance that other missile were just passing through in that moment.

I can’t move the colliders, nor the empty gameObjects I’m using as a point to spawn the missiles.

Am I missing something? There’s anything “elegant” I can do to avoid this issue?
Thanks.

Yes there is :slight_smile:

SOLUTION:

Physics.IgnoreCollision

For example, in void Awake() or void Start() of your projectile (and if the instantiated projectile is a child of the barrel that is firing it, which is the default case) then you could use something like this:

Physics.IgnoreCollision(transform.parent.GetComponent<Collider>(), GetComponent<Collider>());

Alternatively (and still in void Awake() or void Start()) you could get the collider of the barrel and use something like this:

var colliderToIgnore = GameObject.Find("Player/Turret/Barrel").GetComponent<Collider>(); // traversing hierarchy like a tree
Physics.IgnoreCollision(colliderToIgnore, GetComponent<Collider>());

REMARKS:

  1. GameObject.Find is expensive, but in Awake/Start is fine as you might already know.
  2. You need to read the cautions and limitations of dealing with Physics.IgnoreCollision; please read the docs.