Ownership and destroying objects

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.

Ownership and destroying objects

timsk
2012-04-26 13:38:10

Hi everyone,

Still getting to grips with Photon, getting there. I've hit another problem, been working on it all afternoon and haven't managed to figure it out yet.

My problem is with destroying objects and the ownership on them. I know that you cannot destroy objects that do not belong to you, but even with that knowledge I can't seem to do this. I've broken it down as simple as possible and have a cube (tagged "bullet") that can hit a skeleton or zombie enemy.

I have tried 2 different approaches to this (one for the zombie, another for the skeleton). I have also tried the following 2 code samples using PhotonNetwork.Instantiate() and PhotonNetwork.InstantiateSceneObject(), both give the same result.

Heres my skeleton code:

    void OnTriggerEnter(Collider hit)
	{
		if (hit.gameObject.tag == "Bullet")
		{
			SkeletonKilled();
		}
	}

	void SkeletonKilled()
	{
		Debug.Log("We killed a skeleton!");
		PhotonNetwork.Destroy(this.gameObject);
	}

Heres the zombie attempt(trying to check ownership):

	void OnTriggerEnter(Collider hit)
	{
		if (hit.gameObject.tag == "Bullet")
		{
			ZombieKilled(this.gameObject);
		}
	}
	
	void ZombieKilled(GameObject zombie)
	{
		Debug.Log("We killed a zombie!");
		if(PhotonNetwork.isMasterClient)
			PhotonNetwork.Destroy(zombie);
		else if(!PhotonNetwork.isMasterClient)
			 NetworkManager.networkManagerPV.RPC("DestroyObject",PhotonTargets.MasterClient,zombie);
	}

NetworkManager:
	[RPC]
	void DestroyObject(GameObject objectToDestroy)
	{
		PhotonNetwork.Destroy(objectToDestroy);
	}

I get the following errors when I hit them with a "bullet": Skeleton: "Cannot call Destroy(GameObject go); on the gameobject "Skeleton(Clone)" as we don't control it"

Zombie: "SystemException: cannot serialize()" (seems like it's only being destroyed locally?)

The errors come from the player that isn't hosting the server. The server (or masterclient) gets no errors and destroys enemies perfectly.

I don't understand, if the masterclient is the only one that can destroy other players objects. Why, when I send an RPC to the masterclient to destroy the object, does it only destroy it locally? And if that is the case, why doesn't Destroy() automatically do this for me? If I'm calling destroy, I want the object destroyed :).

Hope someone can help. Thanks.

Comments

timsk
2012-04-27 12:45:14

Do I need to provide more information, or is my post being ignored?

Just thought I'de add that my setup works fine using unitys Network.Destroy(). This is starting to feel more like a bug than a flaw in my code.

Edit: Also like to add that all enemies are spawned by the masterclient:

if(PhotonNetwork.isMasterClient)
//spawn code here

Tobias
2012-04-27 15:57:21

You are not ignored but it sometimes takes a while to give (free!) support to everyone.

You don't have to send the master an RPC to let it destroy something. The master gets all the same updates and should also decide if a zombie is destroyed or not. Destroying the zombie works only if it got a PhotonView on it. As it's instantiated with PhotonNetwork.Instantiate, the Destroy should also sync automatically.

Please make sure you use PUN 1.12 from the asset store. If that's not working either, we have to take a look.

timsk
2012-04-27 17:00:46

Sorry, was getting a bit frustrated that I couldn't get it working.

I re-downloaded and re-imported PUN from the asset store (to make sure I'm up to date) but it hasn't helped.

Heres my setup (explained simply): 2 people in a server, Players can fire a cube (network instantiated). Player avatars are network instantiated on the press of "start game". the masterClient spawns all enemies masterClient can shoot his own cubes to kill enemies if anyone else shoots the enemies, I get the errors explained in my first post.

If this is a bug, I hope this helps you replicate :). I'll keep tweaking in the meantime, let me know if you find anything.

Thank you.

timsk
2012-05-03 13:42:28

Well, my trial is over. I can't see a point in subscribing if this issue can't be fixed. An update would be appreciated.

Going back to your comment earlier, if I am a paying customer can I expect support? Or is this not something you guarantee?

Leepo
2012-05-04 09:46:46

The fix is very easy: just make sure only the masterClient is in control of destroying network objects. So have your trigger code only execute for the masterclient (the PhotonNetwork.Destroy is automatically networked).

 void OnTriggerEnter(Collider hit)
   {
if(PhotonNetwork.isMasterClient){
      if (hit.gameObject.tag == "Bullet")
      {
         PhotonNetwork.Destroy(this.gameObject);
      }
}
   }

Tobias
2012-05-04 09:54:39

The subscription for the Photon Cloud is for the service, not for support. We try to provide as much as possible for free. If you needed true company-grade support you should get into touch with us. Mail to: [email protected].

You can save a subscription by hosting Photon yourself. There is a free license for up to 100 concurrent users and the "Loadbalancing" application is compatible with anything you could do with the Photon Cloud. However, you will need to setup your server, Photon and everything yourself.

timsk
2012-05-04 15:46:07

I've started the subscription for now.

Thanks for your help, that has solved the issue. Back to work now I guess!

I would definitly be interested in more support, I'll pop an email over.

Back to top