Search Unity

How can I start the objects rotation only once and wait for them to finish ?

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

  1. DubiDuboni

    DubiDuboni

    Joined:
    Feb 5, 2019
    Posts:
    131
    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class Rotate : MonoBehaviour
    7. {
    8.     public GameObject[] objectsToRotate;
    9.     public float duration = 5f;
    10.     public static bool desiredAngle = false;
    11.  
    12.     private Vector3 lastFwd;
    13.     private bool startRot = true;
    14.  
    15.     private void OnMouseDown()
    16.     {
    17.         if (startRot == true)
    18.         {
    19.             startRot = false;
    20.             StartCoroutine(StartRotationOfObjects());
    21.         }
    22.     }
    23.  
    24.     private IEnumerator StartRotationOfObjects()
    25.     {
    26.         for (int i = 0; i < objectsToRotate.Length; i++)
    27.         {
    28.             // Random wait period before rotation starts
    29.             if (i == 0)
    30.             {
    31.                 yield return new WaitForSeconds(0);
    32.             }
    33.             else
    34.             {
    35.                 yield return new WaitForSeconds(Random.Range(0, 2f));
    36.             }
    37.  
    38.             StartCoroutine(Rotates(objectsToRotate[i].transform, duration));
    39.         }
    40.  
    41.         startRot = true;
    42.     }
    43.  
    44.     private IEnumerator Rotates(Transform objectToRotate, float duration)
    45.     {
    46.         Quaternion startRot = objectToRotate.rotation;
    47.         float t = 0.0f;
    48.         lastFwd = objectToRotate.transform.forward;
    49.  
    50.         while (t < duration)
    51.         {
    52.             t += Time.deltaTime;
    53.  
    54.             objectToRotate.rotation = startRot * Quaternion.AngleAxis(t / duration * 360f, Vector3.up);
    55.  
    56.             var curFwd = objectToRotate.transform.forward;
    57.             // measure the angle rotated since last frame:
    58.             var ang = Vector3.Angle(curFwd, lastFwd);
    59.  
    60.             if (myApproximation(ang, 179f, 1f) == true)
    61.             {
    62.                 desiredAngle = true;
    63.             }
    64.  
    65.             yield return null;
    66.         }
    67.         objectToRotate.rotation = startRot;
    68.  
    69.         desiredAngle = false;
    70.     }
    71.  
    72.     private bool myApproximation(float a, float b, float tolerance)
    73.     {
    74.         return (Mathf.Abs(a - b) < tolerance);
    75.     }
    76. }
    77.  
    The objects in objectsToRotate should rotate once 360 degrees. While they are rotating I want that I will not be able to click the mouse over and over again in the OnMouseDown and only when all the objects finished rotating 360 degrees then to be able to start rotating them again in the OnMouseDown.

    I'm trying to use the startRot flag but it's not working. I can still click the mouse down and start the Coroutine over and over again before they finished rotating.