Search Unity

Bug Layer of Prefab changes after Runtime cuz of script

Discussion in 'Scripting' started by Philipp_Goettler, May 25, 2023.

  1. Philipp_Goettler

    Philipp_Goettler

    Joined:
    Dec 11, 2021
    Posts:
    28
    Hey, i got a Prefab, that has the layer "Buildings" and one child "Player". When my enemy Instantiates the Prefab, it should change the childs layer "Player" to "Enemy". This also works. But when i then stop playing, the layers stay on "Enemy". This is the code:

    Code (CSharp):
    1. public override void CreateBuilding(AI_Controller aiBase)
    2.     {
    3.         if(gotEnoughRessources)
    4.         {
    5.             int randomSpot = Random.Range(0, AI_BuildingSpots.Singleton.LumberjackSpots.Count);
    6.             if (AI_BuildingSpots.Singleton.LumberjackSpots.Count > 0)
    7.             {
    8.                 Instantiate(lumberjackInstantiate,
    9.                     AI_BuildingSpots.Singleton.LumberjackSpots[randomSpot].transform.position, Quaternion.identity);
    10.                 Destroy(AI_BuildingSpots.Singleton.LumberjackSpots[randomSpot]);
    11.                 AI_BuildingSpots.Singleton.LumberjackSpots.Remove(
    12.                     AI_BuildingSpots.Singleton.LumberjackSpots[randomSpot]);
    13.                 ChangeLayerOfChildren(lumberjackInstantiate);
    14.             }
    15.         }
    16.         gotEnoughRessources = false;
    17.     }
    18.  
    19.     void ChangeLayerOfChildren(GameObject go)
    20.     {
    21.         go.layer = 12;
    22.  
    23.         foreach (Transform child in go.transform)
    24.         {
    25.             if(child == null)
    26.                 continue;
    27.             ChangeLayerOfChildren(child.gameObject);
    28.         }
    29.     }
    Also one question is, how does it work, that changes in RunTime change things in the inspector afterwards, i thought every change in the inspector gets reseted.
     
  2. BABIA_GameStudio

    BABIA_GameStudio

    Joined:
    Mar 31, 2020
    Posts:
    497
    That would be because this method call:
    ChangeLayerOfChildren(lumberjackInstantiate);
    is passing in the prefab and not the instantiated instance..

    When you instantiate the gameobject you should be getting a reference to that gameobject:
    GameObject lumberjackInstance = Instantiate(lumberjackInstantiate, AI_BuildingSpots.Singleton.LumberjackSpots[randomSpot].transform.position, Quaternion.identity);


    and then using that one as the parameter for the change layer method:
    ChangeLayerOfChildren(lumberjackInstance);


    I believe that if you change a prefab even at runtime, then this change will persist afterwards.
     
  3. Philipp_Goettler

    Philipp_Goettler

    Joined:
    Dec 11, 2021
    Posts:
    28
    I have tested now yours and also this one:
    Code (CSharp):
    1. GameObject lumberjackInstance = lumberjackInstantiate;
    2.                 Instantiate(lumberjackInstance,
    3.                     AI_BuildingSpots.Singleton.LumberjackSpots[randomSpot].transform.position, Quaternion.identity);
    But it still changes the layer.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    Look closely at your code above:

    line 1 just copies the prefab reference

    line 2 / 3 instantiate and still do nothing with it

    Reread carefully what Babi says above. you must assign lumberjackInstance the value that Instantiate() returns.

    ALSO: name things properly. Don't use
    lumberjackInstantiate
    , that means nothing.

    Instead use perhaps:

    lumberjackPrefab
    <- drag your prefab into here

    lumberjackInstance
    <- assign what Instantiate() returns to this, and ONLY change the layer on this

    This same pattern is used EVERYWHERE in Unity games. Get super familiar with breaking the two things apart: prefab vs instance. Without that brain wiring you're going to bang your toe on this problem again and again.
     
  5. BABIA_GameStudio

    BABIA_GameStudio

    Joined:
    Mar 31, 2020
    Posts:
    497
    Then you obviously made a mistake when typing mine in, and yours (as Kurt pointed out) is just doing what you were originally doing as you are still not referencing the instantiated instance and are just applying the layer change to the prefab.