为什么即使将其设置为false,标志也始终为true?

时间:2019-09-02 05:35:23

标签: c# unity3d

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

public class Rotate : MonoBehaviour
{
    public GameObject[] objectsToRotate;
    public float duration = 5f;
    public static bool desiredAngle = false;

    private Vector3 lastFwd;
    private bool startRot = true;

    private void OnMouseDown()
    {
        if (startRot == true)
        {
            startRot = false;
            StartCoroutine(StartRotationOfObjects());
        }
    }

    private IEnumerator StartRotationOfObjects()
    {
        for (int i = 0; i < objectsToRotate.Length; i++)
        {
            // Random wait period before rotation starts
            if (i == 0)
            {
                yield return new WaitForSeconds(0);
            }
            else
            {
                yield return new WaitForSeconds(Random.Range(0, 2f));
            }

            StartCoroutine(Rotates(objectsToRotate[i].transform, duration));
        }

        startRot = true;
    }

    private IEnumerator Rotates(Transform objectToRotate, float duration)
    {
        Quaternion startRot = objectToRotate.rotation;
        float t = 0.0f;
        lastFwd = objectToRotate.transform.forward;

        while (t < duration)
        {
            t += Time.deltaTime;

            objectToRotate.rotation = startRot * Quaternion.AngleAxis(t / duration * 360f, Vector3.up);

            var curFwd = objectToRotate.transform.forward;
            // measure the angle rotated since last frame:
            var ang = Vector3.Angle(curFwd, lastFwd);

            if (myApproximation(ang, 179f, 1f) == true)
            {
                desiredAngle = true;
            }

            yield return null;
        }
        objectToRotate.rotation = startRot;

        desiredAngle = false;
    }

    private bool myApproximation(float a, float b, float tolerance)
    {
        return (Mathf.Abs(a - b) < tolerance);
    }
}

我想禁用OnMouseDown代码,所以我将无法执行协程不间断时间。在所有对象完成旋转之后,再次启用OnMouseDown。我为此使用了startRot标志,但始终都是如此,我可以一直在OnMouseDown不间断地启动协程。

1 个答案:

答案 0 :(得分:0)

下面是代码的简化版本。

private void OnMouseDown()
{
    if (startRot == true)
    {
        startRot = false;
        StartCoroutine(StartRotationOfObjects());
    }
}

private IEnumerator StartRotationOfObjects()
{
    for (int i = 0; i < objectsToRotate.Length; i++)
    {
        if (i == 0)
        {
            yield return new WaitForSeconds(0);
        }
        else
        {
            yield return new WaitForSeconds(Random.Range(0, 2f));
        }
        StartCoroutine(Rotates(objectsToRotate[i].transform, duration));
    }

    startRot = true;
}

private IEnumerator Rotates(Transform objectToRotate, float duration)
{
    while (condition)
    {
        yield return null;
    }
}

首先,您需要OnMouseDown检查是否为true,并且首次运行它,以便它进入,将其设置为false并启动协程。

继续循环。第一个if检查无效,因为等待了0秒。但这实际上会影响体验。因此,在第一次运行时,它会输入该语句,并且基本上不等待。然后继续前进,开始旋转协程。

输入协程,将达到yield语句,将协程放入协程列表中以运行并返回。回到循环中,它将再次运行,这一次将等待2秒钟,然后运行下一个协程,依此类推,直到最后一个objectToRotate集合。

完成循环,将startRot设置回true。这意味着,即使协程可能没有完成,您也可以触发新协程。

您的解决方案是,您要等待一个轮换完成,然后才能使用以下方法开始新的轮换:

        if (i == 0)
        {
            yield return new WaitForSeconds(0);
        }
        else
        {
            yield return new WaitForSeconds(Random.Range(0, 2f));
        }
        yield StartCoroutine(Rotates(objectsToRotate[i].transform, duration));

或者您需要跟踪所有协程运行情况:

private int index = 0;
private IEnumerator StartRotationOfObjects()
{
    for (int i = 0; i < objectsToRotate.Length; i++)
    {
        if (i == 0)
        {
            yield return new WaitForSeconds(0);
        }
        else
        {
            yield return new WaitForSeconds(Random.Range(0, 2f));
        }
        StartCoroutine(Rotates(objectsToRotate[i].transform, duration);
    }
    while(index > 0){ yield return null; }
    startRot = true;
}

private IEnumerator Rotates(Transform objectToRotate, float duration)
{
    index++;
    while (condition)
    {
        yield return null;
    }
    index--;
}

现在,无论何时启动协程,索引都会增加,在协程结束时索引会减小,在主协程中,您会屈服直到索引返回0。