0
\$\begingroup\$

Each Prefab is built with canvas and two panels childs of the canvas. I'm scaling the two panels. The automatic mode part is working fine.

The problem is with the G key. When I press once on G it's scaling both panels up to maxSize then when pressing on G once again it's scaling the panels back down to minSize.

But when I press on G quick in the middle while it's scaling them it should turn the scaling side in the middle. For example if I press G and both panels start scaling to maxSize if in the middle I press on G again it should scale them both to minSize without getting first to the maxSize. But in this case one of panels is keep scaling to maxSize a bit and then move back to minSize.

But they both should turn side in the middle at once. It seems like one of them have a lag he turn sides a bit after the first one.

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

public class Scaling : MonoBehaviour
{
    public GameObject Prefab;
    public int numberOf = 1;
    public float duration = 1f;
    public Vector3 minSize;
    public Vector3 maxSize;
    public bool scaleUp = false;
    public Coroutine scaleCoroutine;
    public bool automatic = false;
    public bool coroutineIsRunning = false;

    private List<GameObject> parts = new List<GameObject>();

    private void Start()
    {
        for (int i = 0; i < numberOf; i++)
        {
            GameObject objecttest = Instantiate(Prefab);
            foreach (Transform child in objecttest.transform)
            {
                parts.Add(child.gameObject);
            }
        }
    }

    private void Update()
    {
        if (automatic)
        {
            if (!coroutineIsRunning)
            {
                Scale();
            }
        }
        else
        {
            if (Input.GetKeyDown(KeyCode.G))
            {
                Scale();
            }
        }
    }

    private void Scale()
    {
        scaleUp = !scaleUp;

        if (scaleCoroutine != null)
            StopCoroutine(scaleCoroutine);

        for (int i = 0; i < parts.Count; i++)
        {
            if (scaleUp)
            {
                scaleCoroutine = StartCoroutine(ScaleOverTime(parts[i], maxSize, duration));
            }
            else
            {
                scaleCoroutine = StartCoroutine(ScaleOverTime(parts[i], minSize, duration));
            }
        }
    }

    private IEnumerator ScaleOverTime(GameObject targetObj, Vector3 toScale, float duration)
    {
        float counter = 0;
        Vector3 startScaleSize = targetObj.transform.localScale;

        coroutineIsRunning = true;

        while (counter < duration)
        {
            counter += Time.deltaTime;
            targetObj.transform.localScale = Vector3.Lerp(startScaleSize, toScale, counter / duration);

            if (counter > duration)
                coroutineIsRunning = false;

            yield return null;
        }
    }
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

In your scale method, you loop through all objects and start a coroutine for each. You save the coroutine object to cancel it later, but you are overwriting the last one started with each iteration through the loop. So when you start the next time, you are only canceling one of the coroutines that you started.

Either keep track of each coroutine separately in an array, or just use StopAllCoroutines().

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .