Cannot Call Destroy(GameObject go); on the gameobject

Options
Hey,

I've been stuck for a couple of hours with this problem and with no other threads that can help me, I decided to post a thread.

I'm spawning an gameobject (a health pick up) from a spawner by using:
[code2=csharp]public class SpawnerHP : Photon.MonoBehaviour{

public bool spawn = false;


// Use this for initialization

void Start () {
if(PhotonNetwork.isMasterClient){
PhotonNetwork.InstantiateSceneObject("HP", gameObject.transform.position, gameObject.transform.rotation, 0, null);
}
}

// Update is called once per frame

void Update () {

if(spawn){
StartCoroutine(WaitAndPrint(15.0F));
spawn = false;
}
}


IEnumerator WaitAndPrint(float waitTime) {
yield return new WaitForSeconds(waitTime);
if(PhotonNetwork.isMasterClient){
PhotonNetwork.InstantiateSceneObject("HP", gameObject.transform.position, gameObject.transform.rotation, 0, null);


}
}

}[/code2]

On the health pick up gameobject I'm using:
[code2=csharp]public class deleteHP : Photon.MonoBehaviour {
SpawnerHP SHP;
// Use this for initialization

void Start () {
SHP = GameObject.FindWithTag("Spawner").GetComponent<SpawnerHP>();

}

// Update is called once per frame
void Update () {

}

void deleteHPP(){


}

void OnTriggerEnter(Collider other){
if(other.gameObject.tag == "Player"){
SHP.spawn = true;

PhotonNetwork.Destroy(this.gameObject);
}
}
}[/code2]

The problem I'm having is that other players when walking over the health up can't pick it up. It gives the error of Cannot call Destroy(GameObject go); on the gameobject "HP(Clone)" as we don't control it (Owner: ).

However if the person who created the server (masterclient) walks over it, they pick it up and the gameobject is deleted for everyone.

My question is how do I make it so that I spawn "HP" on the masterclient but everyone can pick it up and destroy it?

Just to clarify the spawner works, if the masterclient picks up the health, a new health pick up is dropped 15seconds later.

Any help would be greatly appreciated!

Thanks,

Comments

  • Tobias
    Options
    Only the owner of a GO has control over it. The Master Client has control when the owner is gone, if I recall correctly.
    You can use InstantiateSceneObject() to directly assign a GameObject to the scene and not some player in particular.

    But: In your case for pickups, I would not create "proper" game objects. Instead you could use room properties instead.
    My proposed idea is this: Per level, you need a list of pickup items (type and position). The list is the same on all clients, so you can refer to any item in the list with the index number.
    Per pickup you can have a room property or one room property with all the pickups in a list.
    When a player picks up an item, it can set the item's room property to false. As in "picked up" or "unavailable". Every client gets this property change and can remove the item from the map temporarily. The master should track when this happens and re-set the property after the time you set (15 seconds).
    In this scenario, it's important that the Master Client might drop out of the game anytime, so each client must be prepared to drop new pickups after the time. Also: More than just one client might pick up the item if they do it at about the same time.
  • Hi Tobias,

    Thanks for the reply.

    When the pick ups are spawned, the PhotonView says the owner is scene, and not a player.

    Your idea could be really tiresome in my case as I want to spawn in a high number of objects in the scene. Keeping track of all the properties could be really confusing.

    Is there not a way to spawn an actual gameobject without an owner? If not, is it possible to change the ownership of the item to the player who is picking it up?

    Cheers,
  • Tobias
    Options
    When coding, tiresome is relative. Yes, keeping track of a lot of objects means some effort but you don't have to do it manually, right?
    In the end, creating a GameObject and destroying it also means we keep track of it. In this case, the PUN code and Unity's scene. And the server, which is buffering each and every Instantiate and gets rid of it by Destroy.
    The work has to be done but when using properties, you wouldn't need Instantiate AND Destroy and both again to spawn something new.

    How about this: Send an RPC "I picked this and that up". You can update the client's values (without needing ownership) and every client can activate a coroutine to disable and hide the pickup for the 15 seconds.
    If someone new joins, the Master Client checks all suspended pickups and sends the list to the new player (on demand).

    You never have to switch ownership. You only let others know: The following item is gone for the next 15 sec.
  • Destroy(GameObject.FindWithTag("Spawner"));
  • if(GameObject.Find("Player(Clone)")!=null){
    Destroy(GameObject.FindWithTag("Spawner"));