Search code examples
c#unity-game-enginesceneprefab

Where to initialize a private variable in Unity C# that requires access to scene hierarchy


I have a "Manager" type class called PlayerManager and I'd like to initialize an object for it in a different class/object using FindObjectOfType(). My understanding is that this searches the current scene hierarchy to find an object that has this specific script.

I use this line of code on a prefab that gets generated in the scene instead of being there from the beginning. The variable is private. Sometimes the object cannot be found because I am using this line on Start() function so I am assuming that the "FindObjectOfType" line is called before it can actually search for the object, therefore finding nothing there.

I thought of using this on Update() instead and check if the object is null first so it doesn't loop. I don't know if this is a good practice but it doesn't "feel right".

What would be the ideal way of doing this if I don't want to use a public or [SerializeField] Variable?


Solution

  • As you know, using FindType codes is not optimal at all, and using this code in Update is even worse. In this case, you must specify the Manager in the Spawner object (for example, gun...) and after instantiate, refer the created game object to the manager.


    Although you haven't posted any code in your question. But I will show you an example how to avoid Find. As you can see, put a determining spawn object event in the manager.

    public class Manager : MonoBehaviour
    {
        private Bullet spawned; // for example type of Bullet
        public void SetSpawnedObject(Bullet _spawned)
        {
            spawned = _spawned;
        }
    }
    

    Right after the instantiate is done, you should run your event. This event can be anything.

    public class Spawner : MonoBehaviour
    {
        [SerializeField] private Manager _manager;
        public Bullet bullet;
        
        public void Spawn()
        {
            var _newBullet = Instantiate(bullet);
            _manager.SetSpawnedObject(_newBullet); // set new Bullet to manager after instantiating..
        }
    }