Getting an error when PhotonNetwork.Destroy-ing

Options
Hey, so I keep getting this error, or atleast one very similar.
Can't execute received Destroy request for view ID=2127 as GO can't be found. From player/actorNr: 2 GO to destroy=  originating Player=Guest4721
UnityEngine.Debug:LogError(Object)
NetworkingPeer:OnEvent(EventData) (at Assets/Photon Unity Networking/Plugins/PhotonNetwork/NetworkingPeer.cs:1707)
ExitGames.Client.Photon.PeerBase:DeserializeMessageAndCallback(Byte[])
ExitGames.Client.Photon.EnetPeer:DispatchIncomingCommands()
ExitGames.Client.Photon.PhotonPeer:DispatchIncomingCommands()
PhotonHandler:Update() (at Assets/Photon Unity Networking/Plugins/PhotonNetwork/PhotonHandler.cs:76)
Note: The View ID, is a bullet. The Guest4721 is a player.


This error happens, when a player Shoots a bullet, at an enemy/another player, and sometimes just a wall.

The thing is, sometimes it appears, sometimes it doesn't. And the error only appears for the client who received the bullet. Sorry I'm terrible at explaining. But if one
player shoots a bullet, and it gets destroyed, the other players receive the error.

Here's my projectile script, I've done enough debugging, and I believe the error leads to the bullet script, whenever it is destroyed..
public int damage;
	public GameObject bloodObj;
	public float bloodSpeed;
	
	public AudioClip[] sounds;
	
	void OnCollisionEnter(Collision other) 
	{
		var randomX = Random.Range (-360, 360);
		var randomY = Random.Range (-360, 360);
		var randomZ = Random.Range (-360, 360);
		var randomDir = new Vector3 (randomX, randomY, randomZ);

		foreach (ContactPoint contact in other.contacts) 
		{
			if (other.gameObject.tag == "Player" || other.gameObject.tag == "DeadPlayer" || other.gameObject.tag == "NPC")
			{
				GameObject blood = Instantiate(bloodObj, transform.position, Quaternion.identity) as GameObject;
				blood = Instantiate(bloodObj, transform.position, Quaternion.identity) as GameObject;
				blood = Instantiate(bloodObj, transform.position, Quaternion.identity) as GameObject;
				blood.rigidbody.velocity = randomDir * bloodSpeed * Time.deltaTime;
				blood.audio.clip = sounds[Random.Range(0,sounds.Length)];
				blood.audio.Play();
			}
		}

		if (other.gameObject.tag == "Player" || other.gameObject.tag == "NPC")
		{
			if(photonView.isMine)
			{
				other.gameObject.GetComponent<PhotonView>().RPC ("TakeDamage", PhotonTargets.All, damage);
				PhotonNetwork.Destroy (gameObject);
			}
		}

		else
		{
			if(photonView.isMine)
			{
				PhotonNetwork.Destroy (gameObject);
			}
		}
	}
}

I'll try to keep debugging, but this is insane..
Its hard to fix, because it's not really telling me what is wrong.

Comments

  • AwesomeX
    Options
    Quick update, it doesn't seem to be related to my AI at all.

    As I did a test, and just shooting another player, many, many times, with no damage, the same error came up.

    So it is indeed related to the projectile script.
  • AwesomeX
    Options
    Anyone know what's causing this?
  • Tobias
    Options
    You should not really use PhotonViews for bullets. They are too fast to sync their speed. They don't change their direction or velocity enough to be interesting for updates.
    You can tell the other users everything interesting about a bullet in the moment you fire it.

    It seems the bullet gets destroyed somehow, before the network-destroy reaches some clients.
    The viewID 2xyz belongs to player 2. If player 2 doesn't have this viewID anymore, then it destroyed it before. This might be difficult to track down to find out when this GO got destroyed by who.
  • AwesomeX
    Options
    Thanks for the reply mate.

    And I understand its not recommended to network instantiate bullets.

    But for now, I'm just trying to fix that bloody error.

    I've commented out
    other.gameObject.GetComponent<PhotonView>().RPC ("TakeDamage", PhotonTargets.All, damage);
    

    As I thought, maybe the clients weren't getting the RPC because it destroys it so fast.
    But even with that gone, I still get the error. So its gotta be the
    PhotonNetwork.Destroy(gameObject);
    
    line of code.

    I've also tried disabling one of the PhotonNetwork.Destroys. But still nothing.

    Is there anything else I could post, that would help?
  • AwesomeX
    Options
    I've got a bit of good news. I removed the 2nd PhotonNetwork.Destroy, as it seemed to be reading that line sometimes first, before reading the top one. Which was giving an error.

    It now looks like this
    using UnityEngine;
    using System.Collections;
    
    public class ProjectileScript : Photon.MonoBehaviour {
    
    	public int damage;
    	public GameObject bloodObj;
    	public float bloodSpeed;
    	
    	public AudioClip[] sounds;
    	
    	void OnCollisionEnter(Collision other) 
    	{
    		var randomX = Random.Range (-360, 360);
    		var randomY = Random.Range (-360, 360);
    		var randomZ = Random.Range (-360, 360);
    		var randomDir = new Vector3 (randomX, randomY, randomZ);
    
    		foreach (ContactPoint contact in other.contacts) 
    		{
    			if (other.gameObject.tag == "Player" || other.gameObject.tag == "DeadPlayer" || other.gameObject.tag == "NPC")
    			{
    				GameObject blood = Instantiate(bloodObj, transform.position, Quaternion.identity) as GameObject;
    				blood = Instantiate(bloodObj, transform.position, Quaternion.identity) as GameObject;
    				blood = Instantiate(bloodObj, transform.position, Quaternion.identity) as GameObject;
    				blood.rigidbody.velocity = randomDir * bloodSpeed * Time.deltaTime;
    				blood.audio.clip = sounds[Random.Range(0,sounds.Length)];
    				blood.audio.Play();
    			}
    		}
    
    		if (other.gameObject.tag == "Player" || other.gameObject.tag == "NPC")
    		{
    			if(photonView.isMine)
    			{
    				other.gameObject.GetComponent<PhotonView>().RPC ("TakeDamage", PhotonTargets.All, damage);
    				PhotonNetwork.Destroy(gameObject);
    			}
    		}
    
    		if(other.gameObject.tag == "World" || other.gameObject.tag == "Floor" || other.gameObject.tag == "DeadPlayer" || other.gameObject.tag == "Explosives")
    		{
    			if(photonView.isMine)
    			{
    				PhotonNetwork.Destroy(gameObject);
    			}
    		}
    	}
    }
    

    It cleared up a bunch of the errors, and they are much, much less likely. However, I still get them sometimes. Still not sure why.
  • AwesomeX
    Options
    I'm starting to lose my mind over trying to fix this..

    My latest projectile script.
    using UnityEngine;
    using System.Collections;
    
    public class ProjectileScript : Photon.MonoBehaviour {
    	
    	public int damage;
    	public GameObject bloodObj;
    	public float bloodSpeed;
    	
    	public AudioClip[] sounds;
    	
    	void OnCollisionEnter(Collision other)
    	{
    		if(photonView.isMine)
    		{
    			if(other.gameObject.tag == "Player" || other.gameObject.tag == "NPC")
    			{
    				other.gameObject.GetComponent<PhotonView>().RPC ("TakeDamage", PhotonTargets.All, damage);
    				photonView.RPC ("Bleed", PhotonTargets.All, null);
    				PhotonNetwork.Destroy(gameObject);
    			}
    
    			else
    			{
    				PhotonNetwork.Destroy(gameObject);
    			}
    		}
    	}
    
    	[RPC]
    	void Bleed ()
    	{
    		var randomX = Random.Range (-360, 360);
    		var randomY = Random.Range (-360, 360);
    		var randomZ = Random.Range (-360, 360);
    		var randomDir = new Vector3 (randomX, randomY, randomZ);
    		
    		GameObject blood = Instantiate(bloodObj, transform.position, Quaternion.identity) as GameObject;
    		blood = Instantiate(bloodObj, transform.position, Quaternion.identity) as GameObject;
    		blood = Instantiate(bloodObj, transform.position, Quaternion.identity) as GameObject;
    		blood.rigidbody.velocity = randomDir * bloodSpeed * Time.deltaTime;
    		blood.audio.clip = sounds[Random.Range(0,sounds.Length)];
    		blood.audio.Play();	
    	}
    }
    

    If I take out
    else
    	{
    	PhotonNetwork.Destroy(gameObject);
    	}
    

    No errors, but then I have bullets flying around in different directions, if they hit a wall or something.

    But with that added, I get that damn error.

    I really don't know what to do..
  • AwesomeX
    Options
    Still need help with this.. :/

    It stopped development on my game.
  • vadim
    Options
    Hi,
    First of all make sure that you are not calling PhotonNetwork.Destroy() twice for same object.
    Little bit of debugging code will help to find out.
    One assumption may be that collision for fast-moving objects triggers handler twice.
  • Tobias
    Options
    If any player can decide to destroy a GameObject, then multiple Destroy's will happen.
    Before you call PhotonNetwork.Destroy for a GameObject, you can find out if it's a networked object with a PhotonView and if it's "yours". Or check if the bullet is "yours". So either (!) the shooting player OR the owner of a hit GameObject will destroy something. The bullet itself is probably best destroyed by the shooting player only.

    Problem is: When the shooting player decides it's time to destroy the bullet, then on the other clients, the bullet might be through the object or somewhere else!
    That is why we asked you to refactor your game and NOT make bullets network instantiated.
    We asked you to change your design as it's more or less impossible to do this way. Not to add unnecessary effort on your side.

    Check out this tutorial videos:
    http://forum.unity3d.com/threads/241158 ... ial-Series
  • steamcore
    Options
    I know this is a very old thread but what I found out on my game that gives the same error is that a Destroy command is probably occuring before an RPC was received or a stream update. So whatever method is calling for the destroy, you need to first make sure no RPCs are still lining up.