Search Unity

Setting the parent of a transform which resides in a prefab

Discussion in 'Scripting' started by INSHO, Sep 17, 2009.

  1. INSHO

    INSHO

    Joined:
    Sep 17, 2009
    Posts:
    5
    i want to create a level dynamically.

    think of creating a checkerboard, each square is a prefab. then using user controls to rotate the entire board around as one piece. so all the prefabs get placed under an empty group. ( the whole thing is not one prefab because the there are 12 different types of squares, each level could contain any number or combination of the squares, one level could contain 16 copies of square A)

    so..
    //create empty nodes.
    node1 = new GameObject ("node1");
    node2 = new GameObject ("node2");

    //add prefabs as children to nodes
    var squareA : Transform;
    Instantiate(squareA);

    //control nodes with user input.


    no problem here, no issue or warnings but it stops when i run it with the error:

    "Setting the parent of a transform which resides in a prefab is disabled to prevent data corruption.
    UnityEngine.Transform:set_parent(Transform)"

    does this mean i can not create empty nodes at run time then group several prefabs under them?
    am i going about this correctly?
    any idea on other ways around this?

    thanks,
     
  2. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    You have a comment saying "add prefabs as children to nodes", but you don't seem to show the lines of code where you actually set the prefabs' parent variables. This code could be where the problem lies.
     
    twobob likes this.
  3. GargerathSunman

    GargerathSunman

    Joined:
    May 1, 2008
    Posts:
    1,571
    From the error, it looks like you're not instantiating prefabs before you give them their parents. The error basically means that you can't change the parent of a non-instantiated prefab.

    So, Instantiate them, group them under your nodes as needed, and then set their parent to the node.
     
  4. INSHO

    INSHO

    Joined:
    Sep 17, 2009
    Posts:
    5
    right i did leave that line out about the parenting.

    //create empty nodes.
    node1 = new GameObject ("node1");
    node2 = new GameObject ("node2");

    //add prefabs
    var squareA : Transform;
    Instantiate(squareA);

    //do some parenting
    GameObject.Find("node1").transform.parent = GameObject.Find("node2").transform;

    GameObject.Find("node2").transform.parent = GameObject.Find("squareA").transform;


    //control nodes with user input.

    this is how i get the error..
     
  5. Maelstroms

    Maelstroms

    Joined:
    Nov 26, 2009
    Posts:
    11
    I get the same error :

    Code (csharp):
    1.  
    2. l_Object = Instantiate( g_Pawn, l_Position, transform.rotation );
    3. l_Object.transform.parent = transform;
    4.  
    g_Pawn being a prefab linked into a global variable of the script.

    It says "Setting the parent of a transform which resides in a prefab is disabled to prevent data corruption".

    Any ideas ?
     
  6. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    If node1 and node2 are prefabs, then you should instantiate copies of them first. Prefabs aren't strictly present in the scene, so you can't use them as parents for anything else.
     
    samana1407 likes this.
  7. wallfired

    wallfired

    Joined:
    Dec 26, 2009
    Posts:
    21
    Hi, I solved the same problem... First, you should make a Instantiate the Prefab, after that, you should find that instance and asign the parent... Something like this:

    Code (csharp):
    1.  
    2. // This is the parent node
    3. Transform parent = GameObject.Find("Suelo").transform;
    4.  
    5. // This is the prefab
    6. GameObject prefab = (GameObject)Resources.Load("prefab");
    7.  
    8. // Add the instance in the hierarchy
    9. Instantiate(objTiled);
    10.  
    11. // Find the instantiate prefab and asign the parent
    12. GameObject.Find("NAME").transform.parent = parent;
    13.  
    14.  
    I hope this solution help you... (Sorry by my English) :oops:
     
  8. simjeanny88

    simjeanny88

    Joined:
    May 17, 2012
    Posts:
    19
    Hi all! I got the same problem.
    It is my script:

    var balloon_prefab : GameObject;
    function OnTriggerEnter(col : Collider){

    pump_control(col);
    }

    function pump_control(col : Collider){
    if(col.gameObject.tag=="pump" GameObject.Find("ball1").transform.childCount < 1 || col.gameObject.tag=="pump" GameObject.Find("ball2").transform.childCount <1 || col.gameObject.tag=="pump" GameObject.Find("ball3").transform.childCount <1 || col.gameObject.tag=="pump" GameObject.Find("ball4").transform.childCount <1 ){
    GameObject.Find("headpump").transform.animation.Play("snob");
    print(transform.childCount);

    if(GameObject.Find("ball1").transform.childCount <1){
    Instantiate(balloon_prefab,GameObject.Find("ball1").transform.position,Quaternion.identity);
    balloon_prefab.transform.parent=GameObject.Find("ball1").transform;
    }
    if(GameObject.Find("ball2").transform.childCount <1){
    Instantiate(balloon_prefab,GameObject.Find("ball2").transform.position,Quaternion.identity);
    balloon_prefab.transform.parent=GameObject.Find("ball2").transform;
    }
    if(GameObject.Find("ball3").transform.childCount <1){
    Instantiate(balloon_prefab,GameObject.Find("ball3").transform.position,Quaternion.identity);
    balloon_prefab.transform.parent=GameObject.Find("ball3").transform;
    }
    if(GameObject.Find("ball4").transform.childCount <1){
    Instantiate(balloon_prefab,GameObject.Find("ball4").transform.position,Quaternion.identity);
    balloon_prefab.transform.parent=GameObject.Find("ball4").transform;
    }
    yield WaitForSeconds(3);
    GameObject.Find("headpump").transform.animation.Stop();

    }
    else {
    GameObject.Find("headpump").transform.animation.Stop();
    }
    }
     
  9. sdgd

    sdgd

    Joined:
    Jan 15, 2013
    Posts:
    81
    thanks this is the 2. time I found your post that helped me what's wrong
     
  10. snlehton

    snlehton

    Joined:
    Jun 11, 2010
    Posts:
    99
    Remember that Instantiate returns the copied instance (prefab instance, copied gameobject etc). Many of you seem to be using GameObject.Find() to find the instance - this is wrong. If there was already an object with the same name, you might get that old instance instead of your new freshly created copy!

    Code (csharp):
    1.  
    2. public class Spawner
    3. {
    4.     public Transform m_prefab;
    5.  
    6.     public void Start()
    7.     {
    8.         Transform t = Instantiate(m_prefab) as Transform; // instantiate prefab and get its transform
    9.         t.parent = transform; // group the instance under the spawner
    10.         t.localPosition = Vector3.zero; // make it at the exact position of the spawner
    11.         t.localRotation = Quaternion.identity; // same for rotation
    12.         t.gameObject.name = "My Awesome Instance!";
    13.     }
    14. }
    15.  
     
  11. tachen

    tachen

    Joined:
    Jul 2, 2013
    Posts:
    9
    Thanks!