Assign exposed vars before instantianting prefab?

I have a prefab (a few GameObjects with my scripts). Some of these scripts have exposed variables. In their Start() method I’m initialising some other variables based on the exposed ones. The problem is - when I try to instantiate such a prefab the Start() method gets called before I get a chance to assign the exposed variables.

What should I do?

You can call SetActive(false) on prefab before instantiating it, then instantiate an object and set your vars, and then class SetActive(true) on instantiated object and prefab.
Start and Awake are called only on active objects.

You can set variables in the script on the prefab before you instantiate it. Then the variables will be set correctly in Awake and Start.

So my understanding (just to clarify) is that you have a prefab, which contains some scripts. Those scripts have a load of members that control how the script operates, so you want effectively want to be able to go:

  • create object
  • set the members (lets call them initialisation members)
  • have it ‘start’ and let the script do its thing!

In the simplest case, if you know what the initialisation values are at edit time you would just set these properties in the editor, however you’ve probably hit the scenario where the initialisation members are dependent on run time data? In this case what you’ll need to do is remove the functionality from the start function (so it does very little), then create a new function (lets call it Init) that you call manually which does the bulk of the work. So the order would be:

  • create the object
  • (its start function is automatically called, but does very little)
  • set the members on the script
  • call ‘Init’ on the script

That sound ok?

You can make it a little more robust by having the script raise an error when updating if it hasn’t been initialised, adding the custom parameters as arguments to the init function and even creating your own special static helper functions that internally do the above code. So you might have:

    public static GameObject CreatePlayer(float player_fatness)
    {
        GameObject obj = Instantiate(player_prefab); //the player is created and start is called

        PlayerScript player = obj.GetComponent<PlayerScript>();
        player.fatness = player_fatness;
        player.Init();

        return obj;
    }

or if you passed the parameters into the init function:

    public static GameObject CreatePlayer(float player_fatness)
    {
        GameObject obj = Instantiate(player_prefab); //the player is created and start is called
        obj.GetComponent<PlayerScript>().Init(player_fatness);
        return obj;
    }