首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Coroutine停止工作

Coroutine停止工作
EN

Stack Overflow用户
提问于 2016-01-05 20:31:22
回答 2查看 3.1K关注 0票数 2

我有两个脚本,里面有一个协同线。它在第一种情况下非常好,但在第二种情况下,没有明显的原因。

--它的工作原理是:

代码语言:javascript
复制
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.

然而,在第二个脚本中,没有发生这种情况:

代码语言:javascript
复制
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),然后就停止了。为什么会这样?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-05 22:56:05

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

协同线停止,因为连接到的GameObject GameOverController被破坏了。想必,在恢复协同之前,统一检查对象是否仍然存在,如果对象被销毁,统一将不再继续执行它。

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

票数 3
EN

Stack Overflow用户

发布于 2016-01-06 14:36:37

在大多数情况下,这意味着您的对象或脚本变得不活跃。检查这一点的最佳方法是将OnDisable()方法添加到脚本中并从脚本中调用日志记录

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34620684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档