协程不会停止Unity

Coroutine will not stop Unity

我有一个 select 按钮,360 度全景视频将取决于您 select 的按钮。我希望用户在播放下一个视频之前必须在按钮上播放 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();


    }

此外,自从实施此功能以来,在播放下一个视频之前似乎有很长的停顿,而且看起来很滞后。有什么办法可以改善吗?

因为您是在 Update 函数中调用协程,所以您可能会在 Raycast 在按钮上的每一帧调用它。问题是 StopCoroutine 只会停止第一个具有给定名称的协程。因此,您已经开始的所有其他内容继续 运行。

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

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;

}