- Home /
UNET: How to ignore collisions
Ok so I am instantiating a prefab, which works fine on both the host and all clients. Now my issue is as soon as I add a BoxCollider2D the instantiated prefab will right away collide with the player.
In order to solve that I use Physics2D.IgnoreCollision
- however this only works on the host, not on any other clients since it's a Command.
My code is as followed:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class player_projectile : NetworkBehaviour
{
public GameObject projectile;
public float ProjectileSpeed = 5f;
GameObject square;
[Client]
void Update()
{
if (Input.GetMouseButtonDown(0))
{
GetComponent<AudioSource>().Play ();
Vector2 direction = (Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.z +10)) - transform.position).normalized;
CmdShootProjectile(direction, ProjectileSpeed);
}
}
[Command]
void CmdShootProjectile(Vector2 direction, float speed)
{
square = Instantiate(projectile, transform.position, transform.rotation) as GameObject;
NetworkServer.Spawn(square);
Physics2D.IgnoreCollision(gameObject.GetComponent<BoxCollider2D>(), square.GetComponent<BoxCollider2D>());
square.GetComponent<Rigidbody2D>().velocity = direction * speed;
Destroy(square, 2);
}
}
As you can see I have Physics2D.IgnoreCollision
under CmdShootProjectile
but this only makes it work for the host. How can I also make it work for every other client connected so they don't collide with their own projectile?
Answer by Erdroy · Sep 12, 2015 at 03:28 PM
You should try to attach a script to the projectile, and IgnoreCollision on Start or FixedUpdate.
I thought about doing that and I could reference the player object in the inspector but I don't want the collision to be ignored on other players just the local player.
So ok, I came up with this:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class topkek : NetworkBehaviour
{
public Transform localPlayer;
void Awake ()
{
if(isLocalPlayer)
{
Physics2D.IgnoreCollision(gameObject.GetComponent<BoxCollider2D>(), localPlayer.GetComponent<BoxCollider2D>());
}
}
}
But it doesn't work at all, collision isn't ignored. How would I go on about doing this?
Hmm...
// in topkek : NetworkBehaviour
// A small 'proxy' function to call RpcSetNonCollidable
public void SetNonCollidable(Transform ownerTransform)
{
RpcSetNonCollidable(ownerTransform);
}
[ClientRPC]
private void RpcSetNonCollidable(Transform ownerTransform)
{
Physics2D.IgnoreCollision(GetComponent<BoxCollider2D>(), ownerTransform.gameObject.GetComponent<BoxCollider2D>()); // Ignore the collision
}
// and in player_projectile / CmdShootProjectile
square.gameObject.GetComponent<topkek>().SetNonCollidable(transform);
You should make an custom player-id system(ushort synced with SyncVar in eg. PlayerIdentity) to use ins$$anonymous$$d of "Transform ownerTransform". Then
var players = FindObjectsOfType();
foreach (var player in players)
if(player.playerId == ownerId)
{
// Then here ignore the collision here with: player.transform.
break;
}
That throws me the error:
UNetWeaver error: Rpc function [topkek:RpcSetNonCollidable] parameter [ownerTransform] is of the type [Transform] which is a Component. You cannot pass a Compent to a Rpc call. Try passing data from within the component.
And I actually already tried that, like so:
[Command]
void CmdShootProjectile(Vector2 direction, float speed)
{
square = Instantiate(projectile, transform.position, transform.rotation) as GameObject;
NetworkServer.Spawn(square);
RpcSetSquareNonCollidable();
square.GetComponent<Rigidbody2D>().velocity = direction * speed;
Destroy(square, 2);
}
[ClientRpc]
void RpcSetSquareNonCollidable()
{
Physics2D.IgnoreCollision(GetComponent<BoxCollider2D>(), square.GetComponent<BoxCollider2D>());
}
but I get an error on the client:
NullReferenceException: Object reference not set to an instance of an object player_projectile.RpcSetSquareNonCollidable () (at Assets/scripts/player_projectile.cs:53)
I also tried it with a proxy function like in your example, but it seems no matter what the code only gets executed on the host because of [Command]
I will make something with unique player ID's but I really want to figure this out first. I feel like this should just work, it can't be that hard :/
Your answer
