Coroutine不会阻止Unity

时间:2017-11-06 17:41:06

标签: c# unity3d coroutine

我有一系列按钮,360视频将取决于您选择的按钮。我希望用户在播放下一个视频之前必须在按钮上进行5秒的光线投射。

这似乎工作正常,但是当光线不在按钮上时我需要协程停止。当光线不在正确的菜单项上时,我试图停止协程,但它仍然继续。这是我到目前为止所尝试的:

public Coroutine coroutine;

 void Update()
    {

        //create the ray to cast forward
        RaycastHit hit;
        Vector3 origin = transform.position;
        Vector3 direction = transform.forward;
        Ray ray = new Ray(origin, direction);
        Debug.DrawRay(origin, direction * 100, Color.blue);

        if (Physics.Raycast(ray, out hit))
        {
            objectCollided = hit.collider.gameObject.name;
            hasHit = true;

            if (objectCollided == "goForwardCube")
            {
                coroutine = StartCoroutine(WaitAndPrint());
            }
 else if (objectCollided != "goForwardCube")
            {
               StopCoroutine(coroutine);
            }

        }



  IEnumerator WaitAndPrint()
    {

            // suspend execution for 5 seconds
            ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.clear;
            forwardText.text = "5";
            yield return new WaitForSeconds(1);
            ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.blue;
            forwardText.text = "4";
            yield return new WaitForSeconds(1);
            ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.clear;
            forwardText.text = "3";
            yield return new WaitForSeconds(1);
            ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.blue;
            forwardText.text = "2";
            yield return new WaitForSeconds(1);
            ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.clear;
            forwardText.text = "1";
            yield return new WaitForSeconds(1);
            videoPlayer.url = "Assets/Videos/1(360).mp4";
            ButtonControl.DisableButtons();
            videoPlayer.Play();


    }

此外,自从实施此功能后,在下一个视频播放之前似乎有一段很长的停顿时间,而且看起来相当滞后。有没有办法改善这个?

1 个答案:

答案 0 :(得分:1)

因为您在更新功能中调用了协程,所以您可能会在按钮的每个帧上调用它。问题是StopCoroutine只停止具有给定名称的第一个协同程序。所以你开始的所有其他人都继续跑步。

要解决这个问题,除了光线投射之外,还要设置一个布尔值来检查你的Coroutine是否已经启动。

public Coroutine coroutine;
bool alreadyStarted = false;

void Update()
{

    //create the ray to cast forward
    RaycastHit hit;
    Vector3 origin = transform.position;
    Vector3 direction = transform.forward;
    Ray ray = new Ray(origin, direction);
    Debug.DrawRay(origin, direction * 100, Color.blue);

    if (Physics.Raycast(ray, out hit))
    {
        objectCollided = hit.collider.gameObject.name;
        hasHit = true;

        if (objectCollided == "goForwardCube" && !alreadyStarted)
        {
            alreadyStarted = true;
            coroutine = StartCoroutine(WaitAndPrint());
        }
        else if (objectCollided != "goForwardCube")
        {
           alreadyStarted = false;
           StopCoroutine(coroutine);
        }
    }
    else
    {
        alreadyStarted = false;
    }
}


IEnumerator WaitAndPrint()
{

        // suspend execution for 5 seconds
        ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.clear;
        forwardText.text = "5";
        yield return new WaitForSeconds(1);
        ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.blue;
        forwardText.text = "4";
        yield return new WaitForSeconds(1);
        ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.clear;
        forwardText.text = "3";
        yield return new WaitForSeconds(1);
        ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.blue;
        forwardText.text = "2";
        yield return new WaitForSeconds(1);
        ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.clear;
        forwardText.text = "1";
        yield return new WaitForSeconds(1);
        videoPlayer.url = "Assets/Videos/1(360).mp4";
        ButtonControl.DisableButtons();
        videoPlayer.Play();

        alreadyStarted = false;

}