How can a Client destroy a SceneObject?

Players must create objects and manipulate objects created by other players. Right now, I make sure that every game object created is a SceneObject. Since clients can't create scene objects, I use an RPC to have the Master Client create all objects as scene objects.

An important aspect of the game is the ability for players to destroy objects. The master client can destroy objects but clients cannot. I've been trying to destroy an object using OnTriggerEnter(). I'm trying to send the collider data via RPC but I get errors:
Exception: Write failed. Custom type not found: UnityEngine.CapsuleCollider

This is how I'm attempting to destroy the network objects:
private void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Tree")
        {
            treeLocation = other.transform;
            //PhotonNetwork.Destroy(other.gameObject); //Does not destroy object if not MasterClient
            if (PhotonNetwork.IsMasterClient)
            {
                ReplaceTreeWithStump(other);
            }
            else
            {
                this.photonView.RPC("RPC_ForceMasterClientReplaceTreeWithStump", RpcTarget.MasterClient, other);
            }
        }
    }

    void ReplaceTreeWithStump(Collider other)
    {
        PhotonNetwork.Destroy(other.gameObject);
        PhotonNetwork.InstantiateSceneObject("Stump", treeLocation.position, treeLocation.rotation);
    }

    [PunRPC]
    void RPC_ForceMasterClientReplaceTreeWithStump(Collider other)
    {
        ReplaceTreeWithStump(other);
    }

If I try to include the Collider 'other' as a parameter in the photonView.RPC, it won't work. If I use the above example without the extra parameter (Don't try to destroy anything), it will instantiate the object.

Is it possible to send a collider as a parameter this way? Is there a better way to destroy objects that clients don't own?

Comments

  • You can not send Colliders. Colliders are just one component of a game object. The PhotonView component on an object gives you a way to identify game objects via the network. We sometimes call objects with a PhotonView on it "networked game object".

    Even better:
    When you call RPC on some networked object, this reference to said object is implicit! The RPC will execute on that object's scripts. So the RPC method called will be on the correct networked object and you don't need to pass anything else.
  • Techno_Babel
    edited August 2020
    Thank you. I am now using the ViewID of the object to destroy it.
    else
                {
                    int viewID =  other.GetComponent<PhotonView>().ViewID;
                    Debug.Log("ViewID of tree: " + viewID);
                    this.photonView.RPC("RPC_ForceMasterClientReplaceTreeWithStump", RpcTarget.MasterClient, viewID);
                }
    
    [PunRPC]
        void RPC_ForceMasterClientReplaceTreeWithStump(int viewID)
        {
            PhotonNetwork.Destroy(PhotonView.Find(viewID).gameObject);
            PhotonNetwork.InstantiateSceneObject("Stump", treeLocation.position, treeLocation.rotation);
        }