scale and rotate a cube automatic the cube is never scaling and rotating to the end. how to fix ?

the scaling and rotating both are working.

if the automatic flag bool is false and i press the G key each time i can see that the cube is scaling and rotating to the end for example if it’s rotating down then the cube scale to the minSize 0.1,0.1,0.1 and rotation 0,180 or -180,0 same for maxSize.

the problem is when the automatic flag. bool variable is set to true.
then the cube is scaling down/up nonstop and i can see that the cube whether scaling down or up is never finish the scaling and rotating to each direction. near the end it’s starting scaling and rotating back to the other direction.

why when it’s automatically scaling and rotating it’s not reach exactly to the end each cycle?

using System.Collections;
using Unity.VisualScripting;
using UnityEngine;

public class Scaling : MonoBehaviour
{
    public GameObject objectToScale;
    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 void Start()
    {

    }

    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);
        }

        scaleCoroutine = StartCoroutine(ScaleOverTime(objectToScale, scaleUp ? maxSize : minSize, duration, scaleUp));
    }

    int c = 0;
    private IEnumerator ScaleOverTime(GameObject targetObj, Vector3 toScale, float duration, bool isScalingUp)
    {
        float counter = 0;
        Vector3 startScaleSize = targetObj.transform.localScale;
        Quaternion startRotation = targetObj.transform.rotation;

        // Generate a random angle (0 or 1)
        int randomAngle = Random.Range(0, 2);
        // Set the rotation angle based on the random value
        float t = (randomAngle == 0) ? 180f : -180f;

        // Choose the end rotation based on the scaling direction and apply randomization for both up and down scaling
        Quaternion endRotation = isScalingUp ? Quaternion.Euler(0, 0, 0) : Quaternion.Euler(0, t, 0);

        coroutineIsRunning = true;

        while (counter <= duration)
        {
            counter += Time.deltaTime;
            float lerpFactor = Mathf.Clamp01(counter / duration); // Ensure lerp factor is clamped.

            targetObj.transform.localScale = Vector3.Lerp(startScaleSize, toScale, lerpFactor);
            targetObj.transform.rotation = Quaternion.Lerp(startRotation, endRotation, lerpFactor);

            // Just before the loop finishes, ensure we reach the exact final values
            if (counter >= duration - Time.deltaTime)
            {
                targetObj.transform.localScale = toScale;
                targetObj.transform.rotation = endRotation;
            }

            yield return null;
        }

        coroutineIsRunning = false;

        // Signal end of animation for pause, etc.
        c++;
        Debug.Log("Finished! " + c);
        if (c == 2)
        {
            //Time.timeScale = 0; // Consider using a pause method that doesn't affect Time.timeScale for more complex games
        }
    }
}

I suspect it’s reaching the end of a cycle but your method of verifying is a little wonky. Perhaps you’re just looking at the transform numbers in the inspector?. The lines from 79 to 83 aren’t necessary.

And this might be an easier method for doing your scaling:

using UnityEngine;
public class Scaling : MonoBehaviour
{
    public Transform objectToScale;
    float direction=1;
    public bool automatic = false;

    void Update()
    {
        if ((automatic || Input.GetKeyDown(KeyCode.G)) && Vector3.Distance(objectToScale.localScale,new Vector3(2,2,2)+Vector3.one*direction)<0.01f)
            direction=-direction;

        objectToScale.localScale = Vector3.Lerp(objectToScale.localScale,new Vector3(2,2,2)+Vector3.one*direction,4*Time.deltaTime);
        objectToScale.rotation = Quaternion.Lerp(objectToScale.rotation,Quaternion.Euler(0,90*direction,0),4*Time.deltaTime);
    }
}
1 Like

Wow, that’s a lot of code… any reason you don’t just use an animation and one or two lines of code to start the animation?? That way you can endlessly fiddle with the rates and feeds and jiggles and rotation and no code has to change, no crazy lerping and derping.

Or just use one of the many free tweening packages out there.