-2

How can I create and scale up 100 cubes over time one by one with using Vector3.Lerp function. I need to be dependent on the duration variable. I need an efficient way.

derHugo
  • 83,094
  • 9
  • 75
  • 115
Elif
  • 141
  • 13

1 Answers1

0

Though your question is pretty vague:

Use a Coroutine like e.g.

// Adjust these in the Inspector
[SerilaizeField] private Vector3 targetScale = Vector3.one;
[SerilaizeField] private Vector3 startScale = Vector3.zero;
[SerilaizeField] private float durationPerCube = 1f;
[SerilaizeField] private Transform[] cubes;

private IEnumerator ScaleUpRoutine()
{
    if(cubes.Length == 0) yield break;

    foreach(var cube in cubes)
    {
        var timePassed = 0f;
        while(timePassed < durationPerCube)
        {
            var factor = timePassed / duration;
            // optional easing-in and -out
            //factor = Mathf.SmoothStep(0, 1, factor);

            cube.localScale = Vector3.Lerp(startScale, targetScale, factor);

            timePassed += Time.deltaTime;
            yield return null;
        }

        // just to be sure set a hard value
        cube.localScale = targetScale;
    }
}

You start it whenever you want via StartCoroutine e.g.

private void Start()
{
    StartCoroutine(ScaleUpRoutine);
}

If you rather wanted it based on overall duration you could do

// Adjust this in the Inspector
[SerilaizeField] private float overallDuration = 2f;

private IEnumerator ScaleUpRoutine()
{
    if(cubes.Length == 0) yield break;

    var durationPerCube = overallDuration / cubes.Length;

    ...

Keep in mind though that yield return null; currently waits for at least one frame per cube so if your overallDuration is very small (< 100 frames) it might not be accurate. In this case you might want to add a StopWatch in order to only yield return a frame after a certain real-time threshold like

...

private IEnumerator ScaleUpRoutine()
{
    if(cubes.Length == 0) yield break;

    var stopWatch = new StopWatch();
    stopWatch.Restart();

    ...

    while(timePassed < durationPerCube)
    {
        var factor = timePassed / duration;
        // optional easing-in and -out
        //factor = Mathf.SmoothStep(0, 1, factor);

        cube.localScale = Vector3.Lerp(startScale, targetScale, factor);

        timePassed += Time.deltaTime;
        if(stopWatch.ElapsedMilliseconds >= maxMillisecondPerFrame)
        {
            yield return null;
            stopWatch.Restart();
        }
    }

   ...

For the creating part: You shouldn't.

Depending on your needs I would either

  • Use a hidden object that already holds 100 cubes in the scene. Only display it when needed
  • Extend the same idea a bit further and use pooling instead
derHugo
  • 83,094
  • 9
  • 75
  • 115
  • Thank you for your answer, but my main question is how can I create 100 cubes an efficient way in the scene? – Elif Jun 03 '20 at 13:15
  • @Elif well ... that is a completely different Question to be honest ^^ ... quick answer: You shouldn't. Use [pooling](https://learn.unity.com/tutorial/object-pooling) instead – derHugo Jun 03 '20 at 13:17