2016-01-05 57 views
2

我有两个脚本,其中有协程。它在第一个中工作得很好,但不是在第二个中,因为没有明显的原因。协程暂停工作

它可以在这一个:

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.1

然而,在这种没有按”第二个脚本发生:

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),然后停止。 这是怎么回事?

+1

@ 31eee384谢谢。问题出在'DestroyAllCubes()'中的Destroy()方法。在此之后,协程会停止吗?剧本本身不在场景中,所以不能被破坏或任何东西。 – Milen

+0

我认为在你的第二个循环中需要像这样:while(camera.GetComponent ()。aperture <= 0.6f)' –

+0

@ Calleth'Zion'同样的事情,'='不会必须对手头的问题做任何事情。 – Milen

回答

2

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

协程停止,因为你的游戏对象GameOverController被附加到被销毁。推测Unity会在恢复其协程之前检查一个对象是否仍然存在,并且如果该对象被销毁,Unity不会继续执行它。

为了解决这个问题,你可以在动画完成之前(也许把破坏代码放在协程中的while循环之后)延迟销毁GameObject,或者把组件放在一个不会被销毁的GameObject上。

+0

脚本没有附加到任何东西 – Milen

+0

@Milen然后它如何运行? 'MonoBehaviors'总是附加一个游戏对象 - 你必须误解它是如何创建的。 – 31eee384

+0

“未连接”我的意思是它没有被连接到检查器中的游戏对象。 – Milen

0

在大多数情况下,这意味着您的对象或脚本变为非活动状态。最好的方法来检查这是添加OnDisable()方法到您的脚本,并从它调用日志记录