Search Unity

This code is working but how can I make it to work with one StartCoroutine ?

Discussion in 'Scripting' started by DubiDuboni, Sep 2, 2019.

  1. DubiDuboni

    DubiDuboni

    Joined:
    Feb 5, 2019
    Posts:
    131
    Now it's doing StartCoroutine inside StartCoroutine.
    And instead using two StartCoroutine I wonder how can I change the code to have the same behaviour but with one StartCoroutine.

    The behaviour now and how it should be with one StartCoroutine is that the first cube start rotating at once without waiting the next objects should start while the others still rotating but with random interval starters.

    That is what it's doing now but with two StartCoroutine and I want to do it with one.

    Code (csharp):
    1.  
    2.    public GameObject[] objectsToRotate;
    3.    public float duration = 5f;
    4.    public static bool desiredAngle = false;
    5.  
    6.    private Vector3 lastFwd;
    7.    private int rotcount = 0;
    8.  
    9.    private void OnMouseDown()
    10.    {
    11.        if (rotcount == 0)
    12.        {
    13.            rotcount = 1;
    14.            StartCoroutine(StartRotationOfObjects());
    15.        }
    16.    }
    17.  
    18.    private IEnumerator StartRotationOfObjects()
    19.    {
    20.        for (int i = 0; i < objectsToRotate.Length; i++)
    21.        {
    22.            // Random wait period before rotation starts
    23.            if (i == 0)
    24.            {
    25.                yield return new WaitForSeconds(0);
    26.            }
    27.            else
    28.            {
    29.                yield return new WaitForSeconds(Random.Range(0, 2f));
    30.            }
    31.  
    32.            StartCoroutine(Rotates(objectsToRotate[i].transform, duration));
    33.        }
    34.    }
    35.  
    36.    private IEnumerator Rotates(Transform objectToRotate, float duration)
    37.    {
    38.        Quaternion startRot = objectToRotate.rotation;
    39.        float t = 0.0f;
    40.        lastFwd = objectToRotate.transform.forward;
    41.  
    42.        rotcount++;
    43.  
    44.        while (t < duration)
    45.        {
    46.            t += Time.deltaTime;
    47.  
    48.            objectToRotate.rotation = startRot * Quaternion.AngleAxis(t / duration * 360f, Vector3.up);
    49.  
    50.            var curFwd = objectToRotate.transform.forward;
    51.            // measure the angle rotated since last frame:
    52.            var ang = Vector3.Angle(curFwd, lastFwd);
    53.  
    54.            if (myApproximation(ang, 179f, 1f) == true)
    55.            {
    56.                desiredAngle = true;
    57.            }
    58.  
    59.            yield return null;
    60.        }
    61.        objectToRotate.rotation = startRot;
    62.  
    63.        desiredAngle = false;
    64.  
    65.        if (rotcount == 4)
    66.            rotcount = 0;
    67.    }
    68.  
    69.    private bool myApproximation(float a, float b, float tolerance)
    70.    {
    71.        return (Mathf.Abs(a - b) < tolerance);
    72.    }
    73.  
     
  2. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    Why do you want to do it with one? it will be much harder to do it with one coroutine. It would be even easier to do it without coroutines in an update method instead.

    So, it is totally fine to have it in several coroutines as long as it makes the code better to read (and that is the case here).
     
    DubiDuboni likes this.