Network - Projectile, Prevent Collision with Parent

Hello,

I’m working on a multiplayer network game. Pretty simple concept, just kill any other player you see.

Right now, I’m working on a throwing knife, although I’m sure the concept can be applied to any projectile, but my problem is that the knifes collider colliders with my character/player on initiation.

Few things crossed my mind to prevent this:

  1. I could give the knife a ‘Projectile’ tag and go into my Unity Physics Settings and prevent collision with ‘Projectile’ and ‘Player’. The simple problem with this, is that all the ‘networked’ players also have the tag ‘Player’, and thus would ignore their collider too.

  2. I’m currently using a system where by the throwing knife collider starts off as a trigger, and then after about 0.1 second, turns the trigger collider off, so its a normal collider on. This works, because by the time the collider is active, its well out of reach by the user, this just doesn’t seem very … genuine?

  3. I tried messed around with the ‘Physics.IgnoreCollision’ but I was having no luck!

Because this is a network game, I would normally use Instantiate.Network, so I’m not sure if the Physics.IgnoreCollision applies?

Anyway, here is my code that throws the knife:

function Update(){
     if(Input.GetButtonDown("Action")){
          if(networkView.isMine){
               networkView.RPC("ThrowKnife", RPCMode.All, shooterID.viewID, levelDamage[level]);
	}
     }
}

@RPC
function ThrowKnife(shooterID : NetworkViewID, damage : float){
	
	child.animation.Play("KnifeSwing_Throw");
	
	PlayAudio(0, knifeSwing);
	
	yield WaitForSeconds(0.1);
			
	levelObjects[level].active = false;
		
	var knife : Rigidbody;
	knife = Instantiate(throwingKnife, levelObjects[level].transform.position, player.transform.rotation); //Network.
	
	yield WaitForSeconds(3);
	
	levelObjects[level].active = true;
	throwing = false;
}

So, actually right now I’m just using a normal Instantiate, and not a Network one. But I would like to know if it is possible with a Network one too?

Any ideas?

EDIT —

My characters (well all the characters in the game) do not use a normal collider, they are using a Character Controller.

Thanks

Interesting. I would try giving the knife an “owner” reference (could just be a GameObject) that ThrowKnife sets manually when the knife is created. That way, in your OnTriggerEnter or OnCharacterControllerHit, you can compare the character that got hit with the knife to the knife’s owner.

Physics.IgnoreCollision() is the “right” way to do it. Keep in mind that, unlike what you have now, Network.Instantiate should not be called in an RPC because it is itself an RPC and spawns the object on all clients. So if you’re using Network.Instantiate, you will probably want an RPC immediately following the spawning of the projectile to tell all the clients to uncollide it from the player. So something like:

//Assuming this is in the player class.
void ThrowKnife() {

    GameObject knife = 
     (GameObject)(Network.Instantiate(knifeFab,herp,derp,NETWORK_INSTANTIATES));

    NetworkView.RPC("RemoteDoThrowKnife",
        RPCMode.OthersBuffered,knife.networkView.viewID);

    //don't forget to call the function on yourself, because Unity
    //won't call RPC's on the RPC source even if you use RPCMode.All!
    RemoteDoThrowKnife(knife.networkView.viewID);
}

//then later,
[RPC]
void RemoteDoThrowKnife(NetworkViewID knifeID) {  

    //tell clients to play animations, etc

    //uncollide the objects
    Rigidbody knifePhysics = NetworkView.Find(knifeID).gameObject.rigidbody;
    Physics.IgnoreCollision(this.rigidbody,knifePhysics,true);
}