How can I reference an instantiated Scene Object?

This script instantiates objects in the scene and assigns each instantiated object c a value (ballValue). Then each instantiated object c is added to a list (Container), so that I can grab each object c with Container[i]. My problem is that I want every player to have the same list. However the list is only created for the master client. I look for a way to make a reference to the instantiated object c. What I want in pseudocode:
if (ismasterclient)
    c= InstantiateSceneObject...;
else 
    //c=reference to the already instantiated object;
How can I do that? And if it can not be done like that is there another solution to get my Container List synchronized?
Please help me, I'm stuck there for 2 weeks :(

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class Spawner : Photon.MonoBehaviour, IPunObservable

{

    public GameObject[] MyObjects;
    List<GameObject> Container = new List<GameObject>();


    void OnCreatedRoom()
    {
        initializeObjects();
    }
    
    // Update is called once per frame
    void Update()
    {
        
        if (Input.GetMouseButtonDown(0))
        {
            Debug.Log("Container.count="+Container.Count);
        }
    }

    public void initializeObjects()
    {
        for (int i = 0; i < MyObjects.Length; i++)
        {
            //GetComponent<PhotonView>().RPC("Spawn", PhotonTargets.All,i);
            Spawn(i);
        }
    }


    public void Spawn(int i)
    {
        float Min = -5f, Max = 5f;
        string name;
        GameObject c;
        Vector3 newPos = new Vector3(Random.Range(Min, Max), Random.Range(8f,12f), Random.Range(Min, Max));
        name = MyObjects[i].name;
        c = PhotonNetwork.InstantiateSceneObject(name, transform.parent.localPosition + newPos, Quaternion.identity, 0,null);
        c.GetComponent<BallScript>().ballValue = i;
        //Add instantiated object to a list
        Container.Add(c);
    }
}
and in my Ball Script there is this corresponding method:

public int ballValue
    {   
        get { return _ballValue; }
        set
        {
            _ballValue = value;
            if (photonView.isMine)
                GetComponent<PhotonView>().RPC("RPC_SetBallValue", PhotonTargets.Others, _ballValue);
        }
    }
    [PunRPC]
    void RPC_SetBallValue(int aBallValue)
    {
        _ballValue = aBallValue;
    }

Comments

  • anyone :open_mouth: ?
  • Hi @WTler,

    if the list is accessible (public) you can implemented OnPhotonInstantiate(PhotonMessageInfo info) callback and attach it to the prefab. It is called when the game object gets instantiated through PhotonNetwork.Instantiate(SceneObject) call. In this callback you can do something like reference.GetList().Add(this.gameObject);. Hint: you need to remove the object from the list if it gets destroyed, so you need to implement OnDestroy callback as well.

    Another option is Manual Instantiation which you might want to try out if the other approach isn't working for you. This is described on the bottom of this page.
  • @Christian_Simon Thank you for your answer! OnPhotonInstantiate is probably exactly what I was looking for. But when I try to add my prefab (which has my BallScript attached) to my Container List by calling
    void OnPhotonInstantiate(PhotonMessageInfo info)
        {    
            GetComponent<Spawner>().Container.Add(this.gameObject);  
        }
    , I get a NullReferenceException. What am I doing wrong?
  • OnPhotonInstantiate(PhotonMessageInfo info) should be added to the game object which gets instantiated. I guess you currently have this on the object which contains the list which is wrong as far as I would say. If you however have attached OnPhotonInstantiate(PhotonMessageInfo info) to the game object that gets instantiated, you need to replace GetComponent call with another function call. I guess something with FindObjectOfType would work in your case.
  • I had added OnPhotonInstantiate(PhotonMessageInfo info) to the Ball Script already. The Ball Script is added to all prefabs. The List and and the Photon.InstantiateSceneObject call is in my Spawner Script. And thank you a lot, FindObjectOfType works fine, I'm happy now. :smile:
    void OnPhotonInstantiate(PhotonMessageInfo info)
        {
            FindObjectOfType<Spawner>().Container.Add(this.gameObject);
            ballValue = FindObjectOfType<Spawner>().Container.Count
        }