Recursion going infinite when calling with SetParent

I couldn’t figure out why it is creating a infinite recursion

Observations:

  1. when I create only ChildA recursion is going good
  2. but When I create ChildB recursion is going infinite
  3. when I do without SetParent both of the cases are working good
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Fractal : MonoBehaviour
{
    int depth = 2;
    
    void Start()
    {
        if (depth <= 1)
        {
            return;
        }
        Fractal childA  = generateChildFractal(Vector3.right);
        childA.transform.SetParent(transform, false);
        Fractal childB = generateChildFractal(Vector3.up);
        childB.transform.SetParent(transform, false);
    }
 
    Fractal generateChildFractal(Vector3 direction)
    {
        Fractal fractal = Instantiate(this);
        fractal.depth = depth - 1;
        fractal.name = "F__" + depth;
        Debug.Log("Generated Child: " + fractal.name + " at Depth: " + fractal.depth);
        fractal.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
        fractal.transform.localPosition = direction;
        return fractal;
    }
}

When you Instantiate “this”, you will be cloning the whole gameobject this script is attached to. That includes any children it might have. Since your childA clones itself, it doesn’t have any children. However since you added childA alteady as child to your main object, when you duplicate your main object again as childB, that childB will also contain the clone of childA.

That’s why you generally should avoid instantiating / cloning objects in the scene. You should always instantiate prefabs.

Note that prefabs can not hold references to itself because during instantiation any local / internal reference will be “patched” to the newly instantiated object. So you either need an inbetween mediator to access the prefab (for example a scriptable object that has a public field that holds the prefab and the prefab only references the scriptable object asset). Or you could pass down the original prefab after you instantiated your clone from the prefab. Something like

Fractal child = Instantiate(prefab);
child.prefab = prefab;
// [ ... ]

ps: If you really want to clone the object itself, you should at least also make your depth variable serializable and have the Start method actually decrease it’s own depth once right at the beginning. When you clone yourself the clone would also clone / copy the current depth value and in turn would reduce it in its own Start method once it’s his turn. However this would be much more complex and hard to reason what the final hierachry would look like. Prefabs are the way to go.

thanks @Bunny83
I changed setParent for childA after initializing the childB now it is working properly