C# WaitForSeconds()协同程序使游戏无限期冻结(已编辑)

C# WaitForSeconds()协同程序使游戏无限期冻结(已编辑),c#,performance,debugging,testing,unity3d,C#,Performance,Debugging,Testing,Unity3d,我有一个有四个场景的游戏,一个菜单场景,一个加载场景和两个游戏场景。一切正常,当我从菜单场景过渡到游戏场景时,但是每当我从游戏场景过渡回菜单场景或重新加载游戏场景时,加载场景就会停止响应。我收到一条警告消息,上面写着“NetworkManager在编辑器中检测到脚本重新加载。这导致网络关闭“只有在我尝试重新加载当前活动的游戏场景时才关闭。当我在构建中玩游戏时,这个问题也会出现!我使用print语句跟踪代码停止运行的位置,我发现这是返回新WaitForSeconds()的结果这导致游戏冻结。为什么

我有一个有四个场景的游戏,一个菜单场景,一个加载场景和两个游戏场景。一切正常,当我从菜单场景过渡到游戏场景时,但是每当我从游戏场景过渡回菜单场景或重新加载游戏场景时,加载场景就会停止响应。我收到一条警告消息,上面写着“NetworkManager在编辑器中检测到脚本重新加载。这导致网络关闭“只有在我尝试重新加载当前活动的游戏场景时才关闭。当我在构建中玩游戏时,这个问题也会出现!我使用print语句跟踪代码停止运行的位置,我发现这是返回新WaitForSeconds()的结果这导致游戏冻结。为什么

我有两个控制转换的脚本。一个简单的脚本调用UIButtons,告诉在预加载场景中调用的第二个更复杂的脚本加载它应该加载的场景并创建动画。我已经确保加载到正确的场景,并且所有场景都添加到我的bu中ild设置

以下图片显示加载场景未响应。第一张图片显示我尝试重新加载当前游戏场景时发生的情况,第二张图片显示我尝试加载菜单场景时发生的情况:

我的加载场景脚本:

public class LoadingScreenManager : MonoBehaviour {

[Header("Loading Visuals")]
public Image loadingIcon;
public Image loadingDoneIcon;
public Text loadingText;
public Image progressBar;
public Image fadeOverlay;

[Header("Timing Settings")]
public float waitOnLoadEnd = 0.25f;
public float fadeDuration = 0.25f;

[Header("Loading Settings")]
public LoadSceneMode loadSceneMode = LoadSceneMode.Single;
public ThreadPriority loadThreadPriority;

[Header("Other")]
// If loading additive, link to the cameras audio listener, to avoid multiple active audio listeners
public AudioListener audioListener;

AsyncOperation operation;
Scene currentScene;

public static int sceneToLoad = -1;
// IMPORTANT! This is the build index of your loading scene. You need to change this to match your actual scene index
static int loadingSceneIndex = 1;

public static void LoadScene(int levelNum) {                
    Application.backgroundLoadingPriority = ThreadPriority.High;
    sceneToLoad = levelNum;
    SceneManager.LoadScene(loadingSceneIndex);
}

void Start() {
    if (sceneToLoad < 0)
        return;

    fadeOverlay.gameObject.SetActive(true); // Making sure it's on so that we can crossfade Alpha
    currentScene = SceneManager.GetActiveScene();
    StartCoroutine(LoadAsync(sceneToLoad));
}

private IEnumerator LoadAsync(int levelNum) {
    ShowLoadingVisuals();

    yield return null; 

    FadeIn();
    StartOperation(levelNum);

    float lastProgress = 0f;

    // operation does not auto-activate scene, so it's stuck at 0.9
    while (DoneLoading() == false) {
        yield return null;

        if (Mathf.Approximately(operation.progress, lastProgress) == false) {
            progressBar.fillAmount = operation.progress;
            lastProgress = operation.progress;
        }
    }

    if (loadSceneMode == LoadSceneMode.Additive)
        audioListener.enabled = false;

    ShowCompletionVisuals();
  //THE PRINT STATEMENT WORKS FINE RIGHT HERE! The value of waitOnLoadEnd is only 1
    yield return new WaitForSeconds(waitOnLoadEnd);
 //THE PRINT STATEMENT STOPS RUNNING RIGHT HERE!  
    FadeOut();

    yield return new WaitForSeconds(fadeDuration);

    if (loadSceneMode == LoadSceneMode.Additive)
        SceneManager.UnloadScene(currentScene.name);
    else
        operation.allowSceneActivation = true;
}

private void StartOperation(int levelNum) {
    Application.backgroundLoadingPriority = loadThreadPriority;
    operation = SceneManager.LoadSceneAsync(levelNum, loadSceneMode);


    if (loadSceneMode == LoadSceneMode.Single)
        operation.allowSceneActivation = false;
}

private bool DoneLoading() {
    return (loadSceneMode == LoadSceneMode.Additive && operation.isDone) || (loadSceneMode == LoadSceneMode.Single && operation.progress >= 0.9f); 
}

void FadeIn() {
    fadeOverlay.CrossFadeAlpha(0, fadeDuration, true);
}

void FadeOut() {
    fadeOverlay.CrossFadeAlpha(1, fadeDuration, true);
}

void ShowLoadingVisuals() {
    loadingIcon.gameObject.SetActive(true);
    loadingDoneIcon.gameObject.SetActive(false);

    progressBar.fillAmount = 0f;
    loadingText.text = "LOADING...";
}

void ShowCompletionVisuals() {
    loadingIcon.gameObject.SetActive(false);
    loadingDoneIcon.gameObject.SetActive(true);

    progressBar.fillAmount = 1f;
    loadingText.text = "LOADING DONE";
}

}
公共类加载ScreenManager:MonoBehavior{
[标题(“加载视觉效果”)]
公共图像加载图标;
公共形象加载;
公共文本加载文本;
公众形象酒吧;
公众形象淡出;
[标题(“定时设置”)]
公共浮点数waitOnLoadEnd=0.25f;
公共浮动衰减率=0.25f;
[标题(“加载设置”)]
公共LoadSceneMode LoadSceneMode=LoadSceneMode.Single;
公共线程优先级加载线程优先级;
[标题(“其他”)]
//如果加载加法器,请链接到摄像头音频侦听器,以避免多个活动音频侦听器
公众听众;
异步操作;
场景当前场景;
公共静态int sceneToLoad=-1;
//重要提示!这是加载场景的生成索引。您需要更改它以匹配实际场景索引
静态int加载SCENEINDEX=1;
公共静态void加载场景(int-levelNum){
Application.backgroundLoadingPriority=ThreadPriority.High;
sceneToLoad=levelNum;
加载场景(加载场景索引);
}
void Start(){
如果(场景加载<0)
返回;
fadeOverlay.gameObject.SetActive(true);//确保它处于打开状态,以便我们可以交叉淡入淡出Alpha
currentScene=SceneManager.GetActiveScene();
start例程(LoadAsync(sceneToLoad));
}
私有IEnumerator LoadAsync(int-levelNum){
ShowLoadingVisuals();
收益返回空;
FadeIn();
开始操作(levelNum);
float lastProgress=0f;
//该操作不会自动激活场景,因此它停留在0.9
while(DoneLoading()==false){
收益返回空;
if(数学近似值(operation.progress,lastProgress)=false){
progressBar.fillAmount=operation.progress;
lastProgress=operation.progress;
}
}
if(loadSceneMode==loadSceneMode.Additive)
audioListener.enabled=false;
ShowCompletionVisuals();
//PRINT语句在这里工作正常!waitOnLoadEnd的值只有1
返回新的WaitForSeconds(waitOnLoadEnd);
//打印语句就在这里停止运行!
淡出();
返回新的WaitForSeconds(fadeDuration);
if(loadSceneMode==loadSceneMode.Additive)
SceneManager.UnloadScene(currentScene.name);
其他的
operation.allowSceneActivation=true;
}
私有无效开始操作(int-levelNum){
Application.backgroundLoadingPriority=loadThreadPriority;
operation=SceneManager.LoadSceneAsync(levelNum,loadSceneMode);
if(loadSceneMode==loadSceneMode.Single)
operation.allowSceneActivation=false;
}
私人书房{
return(loadSceneMode==loadSceneMode.Additive&&operation.isDone)| |(loadSceneMode==loadSceneMode.Single&&operation.progress>=0.9f);
}
void FadeIn(){
fadeOverlay.CrossFadeAlpha(0,fadeDuration,true);
}
无效衰减(){
fadeOverlay.CrossFadeAlpha(1,fadeDuration,true);
}
void show loadingvisuals(){
加载icon.gameObject.SetActive(true);
加载doneicon.gameObject.SetActive(false);
progressBar.fillAmount=0f;
loadingText.text=“正在加载…”;
}
作废ShowCompletionVisuals(){
加载icon.gameObject.SetActive(false);
加载doneicon.gameObject.SetActive(true);
progressBar.fillAmount=1f;
loadingText.text=“加载完成”;
}
}
UI上的脚本调用上述脚本的按钮:

 public class LoadingSceneButton : MonoBehaviour {

public void LoadSceneWithLoadingScreen(int sceneNumber){
    if (sceneNumber < 0 || sceneNumber >= SceneManager.sceneCountInBuildSettings) {
        Debug.LogWarning ("Can't Load Scene, because It Doesn't Exist!");
    }

    LoadingScreenManager.LoadScene (sceneNumber);
}
}
公共类加载场景按钮:MonoBehavior{
公共无效加载场景加载屏幕(int sceneNumber){
if(sceneumber<0 | | sceneumber>=SceneManager.sceneCountInBuildSettings){
Debug.LogWarning(“无法加载场景,因为它不存在!”);
}
LoadingScreenManager.LoadScene(Sceneumber);
}
}
(1)不要使用“打印”,请使用以下命令:

  Debug.Log("fadeDuration is ....... " , fadeDuration.ToString("f4");
在调用
FadeOut
之前添加该行代码,也请将其添加到
FadeOut


(2)
CrossFadeAlpha问题
请注意,CrossFadeAlpha非常难以使用!这是一个真正的难题!它只适用于
UnityEngine.UI.Graphic
,与协同程序一起使用时非常棘手

public static void FadeOut(this Graphic g)
    {
    g.GetComponent<CanvasRenderer>().SetAlpha(1f);
    g.CrossFadeAlpha(0f,.15f,false);
    }
公共静态无效淡出(此图g)
{
g、 GetComponent().SetAlpha(1f);
g、 CrossFadeAlpha(0f、.15f,假);
}

(3) 在Unity5中加载场景时出现问题!!! 是的,有一个

已知问题 它在0.9上卡住了。也许这是手头的主要问题

退房

而且

一些基本的工作代码示例。。
public void LaunchSoundboard()
    {
    StartCoroutine(_soundboard());
    }
private IEnumerator _soundboard()
    {
    Grid.music.Duck();

    yield return new WaitForSeconds(.2f);

    AsyncOperation ao;
    ao = UnityEngine.SceneManagement
       .SceneManager.LoadSceneAsync("YourSceneName");

    while (!ao.isDone)
        {
        yield return null;
        }

    // here, the new scene IS LOADED
    SoundBoard soundBoard = Object.FindObjectOfType<SoundBoard>();
    if(soundBoard==null) Debug.Log("WOE!");
    soundBoard.SomeFunctionInSoundboardScript();
    }