Play button does not initialize variables of gameObjects which are parameters of a component?

I do not know if it is a bug or feature:

  • Scene A has GameObject B with attached Component C.
  • Component C has a parameter GameObject D.
  • GameObject D is supplied as a Prefab.
  • GameObject D has a Component E.
  • Component C now calls an Init-Function in Component E.

    public void Init() {
    Debug.Log("Init:");
    if (!initDone) {
        Debug.Log("Init: *** Initializing ***");
        initDone = true;
    }           
    
    

    }

  • The variable init is defined as this:

    private bool initDone = false;

When I hit the Play-Button the first time, I see:

Init: 
Init: *** Initializing ***

After pressing the Stop-Button and the Play-Button of the Unity-Editor again, I see only

 Init: 

So it seems to me that there is no new object created or the initialization is not done again. What is the explanation? Am I missing a Unity concept at this point?

Are you calling the Init() function on the prefab, or on a clone instantiated from the prefab? (If the former, I'd guess you're modifying the prefab itself, which is why the initialization only occurs once.)

Edit: Response to comment below:

So if a Prefab is assigned as a parameter no new GameObject is created, but the Prefab itself is assigned ... I would not have expected that behaviour intuitively.

Why would a new game object be created? The 'GameObject' field is a reference, so when you assign the prefab to it, you're just assigning a reference to that prefab. (Maybe it's the difference between reference and value semantics that's throwing you off, which is why you were expecting a copy of the object to be made.)

Workaround would be: Create an GameObject from the Prefab in the scene and submit that GameObject as a parameter?

Well, it's not a workaround, since what you're seeing is the correct (expected) behavior. But, the usual way to do this is:

  • Assign a prefab to a script field (e.g. a GameObject reference, just like you're doing)
  • Use the Instantiate() function to clone new game objects from the prefab as needed

So no, you wouldn't drag the prefab into the scene and then assign the resulting game object to the script field, if that's what you're asking. Rather, you'd drag the prefab onto the script field, and then clone new game objects from that reference.