How clone prefab as a new object ? not as (clone)(clone)...(clone)

hello everyone, I am trying to do the sand pile algorithm, where I have a resource, which increases in state over time, when it reaches its maximum state, it must create the same resource around it, with its initial states so that it can be repeat the cycle, expecting them to increase their states over time and spawn new neighbors.

The problem is that when generating the neighbors, they are created by referring to the cloned object, and they create their neighbors immediately, without waiting for their states to increase over time.

initially it waits for time fine, but when creating the first neighbors, it immediately fills the entire map, since new objects immediately create their neighbors without waiting.

Basically, I need help to know, how to create these instances, as new objects, or at least with their initial states. So that they wait and do not create their neighbors immediately, and do not fill the map immediately

how could i solve it? Or what alternative could I do?

Thanks for the help

here link to see screenshots in forum:
https://forum.unity.com/threads/how-clone-prefab-as-a-new-object-not-as-clone-clone-clone.1344206/

Code :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ResourceLifeCycle : MonoBehaviour
{
    private Utils utils = new Utils();

    private int state = 0; // Current state
    public int maxState = 4; // Max state

    public int groundLimit = 10; // Ground Limit


    public float timeRemaining = 10; // Current timer
    private float timerConstant = 0; // timer Limit


    public GameObject resource; // GameObject to create - is itself


    // Start is called before the first frame update
    void Start()
    {
        timerConstant = timeRemaining;
        state = 1;
    }

    // Update is called once per frame
    void Update()
    {
        Timer();
    }

    private void Timer()
    {
        // Timer
        if (timeRemaining > 0)
        {
            timeRemaining -= Time.deltaTime;
        }
        else
        {
            if(state < maxState){
                state = state +1;
            }else{
                // Generate new resource
                Generator();
            }
            // Restart Timer
            timeRemaining = timerConstant;
        }
    }


    private void Generator()
    {
        // foward
        Vector3 cord = transform.position + ( Vector3.forward );
        if(cord.z < groundLimit){// check ground limit
            if(utils.isObjectHere(cord)==false){// check if exist object in new position
                Instantiate(resource, cord, Quaternion.identity); // create new resouce in new position
            }
        }
        // foward left
        cord = transform.position + ( Vector3.forward + Vector3.left );
        if((cord.z < groundLimit) || (cord.x > -groundLimit) ){// check ground limit
            if(utils.isObjectHere(cord)==false){// check if exist object in new position
                Instantiate(resource, cord, Quaternion.identity); // create new resouce in new position
            }
        }

        // foward right
        cord = transform.position + ( Vector3.forward + Vector3.right );
        if((cord.z < groundLimit) || (cord.x < groundLimit) ){// check ground limit
            if(utils.isObjectHere(cord)==false){// check if exist object in new position
                Instantiate(resource, cord, Quaternion.identity); // create new resouce in new position
            }
        }
        // right
        cord = transform.position + ( Vector3.right );
        if(cord.x < groundLimit ){// check ground limit
            if(utils.isObjectHere(cord)==false){// check if exist object in new position
                Instantiate(resource, cord, Quaternion.identity); // create new resouce in new position
            }
        }
        // left
        cord = transform.position + ( Vector3.left );
        if(cord.x > -groundLimit ){// check ground limit
            if(utils.isObjectHere(cord)==false){// check if exist object in new position
                Instantiate(resource, cord, Quaternion.identity); // create new resouce in new position
            }
        }
        // back
        cord = transform.position + ( Vector3.back );
        if(cord.z > -groundLimit ){// check ground limit
            if(utils.isObjectHere(cord)==false){// check if exist object in new position
                Instantiate(resource, cord, Quaternion.identity); // create new resouce in new position
            }
        }
        // back left
        cord = transform.position + ( Vector3.back + Vector3.left );
        if((cord.z > -groundLimit ) || (cord.x > -groundLimit )){// check ground limit
            if(utils.isObjectHere(cord)==false){// check if exist object in new position
                Instantiate(resource, cord, Quaternion.identity); // create new resouce in new position
            }
        }
        // back right
        cord = transform.position + ( Vector3.back + Vector3.right );
        if((cord.z > -groundLimit) || (cord.x < groundLimit) ){// check ground limit
            if(utils.isObjectHere(cord)==false){// check if exist object in new position
                Instantiate(resource, cord, Quaternion.identity); // create new resouce in new position
            }
        }

    }
}

Hello.

You can have a little more control of what is happening inside the scrpt. Using IEnumerators (Corutines). Here is an example:

void Start()
{
Basic things....
StartCorutine(FirstFunction());
}

IEnumerator FirstFunction()
{
Things...
yield return null;
More thinge...
StartCorutine(SecondFunction());
}

IEnumerator SecondFunction()
{
yield return null;
Instantiate function (Replicate itself)
}

This way, you are sure what things are executed in a specypic order, and give time to process (because each yield return null will wait 1 frame to continue) And can also do a exponential increase (if each element instabntiate 2 more elements)

Rememeber, IEnumeratots are used as void function, but needs to be called like this StartCorutine(functionName()); and the funciton must have a return inside (in all of its branches if have multiple if or switch)

Bye!!