c# - 协程停止工作

标签 c# unity-game-engine coroutine

我有两个带有协程的脚本。它在第一个中工作得很好,但在第二个中却不起作用,没有明显的原因。

它适用于这个:

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.ImageEffects;

public class GameStartController : MonoBehaviour {
    public Button startButton;
    public GameObject cubeSpawner;

    // Use this for initialization
    private void Start() {
        startButton = startButton.GetComponent<Button>();   
    }

    public void StartGame() {
        EnableCubeSpawner();
        SpawnStartingCubes();
        HideStartMenu();
        StartCoroutine("FocusCamera");
        PlayBackgroundMusic();
    }

    // Enables the cube spawner, so it can start spawning cubes
    private void EnableCubeSpawner() {
        cubeSpawner.SetActive(true);
    }

    private void SpawnStartingCubes() {
        cubeSpawner.GetComponent<CubeSpawner>().GenerateStartingCubes();
    }

    private void PlayBackgroundMusic() {
        var audio = GameObject.FindWithTag("Audio").GetComponent<AudioController>();
        audio.PlayBackgroundMusic();
    }

    private void HideStartMenu() {
        startButton.transform.parent.GetComponent<CanvasGroup>().interactable = false;
        startButton.transform.parent.GetComponent<CanvasGroup>().alpha = 0f;
    }

    private IEnumerator FocusCamera() {
        var camera = GameObject.FindWithTag("MainCamera").GetComponent<Camera>();
        var velocity = 0f;

        while (Mathf.Abs(camera.GetComponent<DepthOfField>().aperture) > 0.001f) {
            Debug.Log(Mathf.Abs(camera.GetComponent<DepthOfField>().aperture));

            camera.GetComponent<DepthOfField>().aperture = Mathf.SmoothDamp(camera.GetComponent<DepthOfField>().aperture, 0f, ref velocity, 0.3f);
            yield return null;
        }

        camera.GetComponent<DepthOfField>().aperture = 0f;
    }
}

协程工作得很好,相机光圈从 0.6 平滑地变为 0。

但是在第二个脚本中这不会发生:

using System.Collections;
using System.Linq;
using UnityEngine;
using UnityStandardAssets.ImageEffects;

public class GameOverController : MonoBehaviour {
    public void EndGame() {
        StartCoroutine("UnfocusCamera");
        DisableCubeSpawner();
        DestroyAllCubes();
        StopBackgroundMusic();
        ShowStartMenu();
    }

    // Disables the cube spawner, so it can stop spawning cubes
    private void DisableCubeSpawner() {
        var cubeSpawner = GameObject.FindWithTag("CubeSpawner");
        cubeSpawner.SetActive(false);
    }

    private void DestroyAllCubes() {
        var gameObjects = FindObjectsOfType(typeof(GameObject));

        foreach (var gameObject in gameObjects.Where(gameObject => gameObject.name.Contains("Cube"))) {
            Destroy(gameObject);
        }
    }

    private void StopBackgroundMusic() {
        var audio = GameObject.FindWithTag("Audio").GetComponent<AudioController>();
        audio.StopBackgroundMusic();
    }

    private void ShowStartMenu() {
        var startMenu = GameObject.FindWithTag("StartMenu");
        startMenu.GetComponent<CanvasGroup>().interactable = true;
        startMenu.GetComponent<CanvasGroup>().alpha = 1f;
    }

    private IEnumerator UnfocusCamera() {
        var camera = GameObject.FindWithTag("MainCamera").GetComponent<Camera>();
        var velocity = 0f;

        while (camera.GetComponent<DepthOfField>().aperture < 0.6f) {
            Debug.Log(Mathf.Abs(camera.GetComponent<DepthOfField>().aperture));
            camera.GetComponent<DepthOfField>().aperture = Mathf.SmoothDamp(camera.GetComponent<DepthOfField>().aperture, 0.6f, ref velocity, 0.3f);
            yield return null;
        }

//        camera.GetComponent<DepthOfField>().aperture = 0f;
    }
}

它仅适用于一帧(光圈从 0 到 0.03),然后停止。 为什么会发生这种情况?

最佳答案

如果您销毁(或禁用)游戏对象,则在附加到该对象的组件上运行的协程将停止。我无法找到这方面的主要来源,但这里还有另外两个堆栈溢出问题:

协程停止,因为您的 GameOverController 附加的 GameObject 被销毁。想必Unity在恢复协程之前会检查一个对象是否仍然存在,如果该对象被销毁,Unity就不会继续执行它。

要解决此问题,您可以延迟销毁 GameObject,直到动画完成(也许将销毁代码放在协程中的 while 循环之后),或者将组件放在不会被销毁的 GameObject 上。

关于c# - 协程停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34620684/

相关文章:

c# - 您使用什么工具和技术来查找死代码?

github - Unity3D多人游戏开发 : How could we work on the same project simultaneously?

unity-game-engine - 在unity3d中预加载纹理

android - 无法将 Unity ARCore 项目作为 android .AAR 库运行

python - 异步 def 函数的“yield from”替代方案

c# - 我怎样才能读取 json 的每个文件

c# - 如何更改隐藏字段的名称属性?

c# - 返回类型数组

python - 如何从python中的协程获取返回值

python - 将带有回调的函数变成 Python 生成器?