How can a Client destroy a SceneObject?

The whole answer can be found below.

Please note: The Photon forum is closed permanently. After many dedicated years of service we have made the decision to retire our forum and switch to read-only: we've saved the best to last! And we offer you support through these channels:

Try Our
Documentation

Please check if you can find an answer in our extensive documentation on PUN.

Join Us
on Discord

Meet and talk to our staff and the entire Photon-Community via Discord.

Read More on
Stack Overflow

Find more information on Stack Overflow (for Circle members only).

Write Us
an E-Mail

Feel free to send your question directly to our developers.

How can a Client destroy a SceneObject?

Techno_Babel
2020-08-01 23:24:34

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

Tobias
2020-08-04 08:12:11

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
2020-08-07 11:28:37

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);  
    }
Back to top