我有两个带有协程的脚本。出于显而易见的原因,它在第一个中工作得很好,但在第二个中却没有。
它适用于此:
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上。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句