CorForine会导致Game无限期冻结(已编辑)

时间:2016-07-30 04:12:54

标签: c# performance debugging testing unity3d

我有一个有四个场景的游戏,一个菜单场景,一个加载场景和两个游戏场景。一切都很顺利,当我从菜单场景转换到我的游戏场景时,但每当我从游戏场景转换回菜单场景或重新加载游戏场景时,加载场景就会停止响应。我收到一条警告消息,说明“NetworkManager在编辑器中检测到脚本重新加载。这导致网络关闭”仅当我尝试重新加载当前活动的游戏场景时。 当我在构建中玩时,这个问题也存在!我使用print语句来追踪我的代码停止运行的位置,并且我发现这是导致游戏的Yield Return New WaitForSeconds()冻结。那是为什么?

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

以下图片显示装载场景无响应。第一张图显示了当我尝试重新加载当前游戏场景时会发生什么,第二张图显示了当我尝试加载菜单场景时会发生什么:

Loading Screen Freezing when I try to reload the game scene

Loading Screen Freezing when I try to load the menu scene

我的加载场景脚本:

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";
}

}

调用上述脚本的UIButtons脚本:

 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);
}
}

1 个答案:

答案 0 :(得分:1)

(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);
    }

(3)在Unity5中加载场景的问题!!!

是的,有一个

已知问题

它被卡在0.9上。也许这是手头的主要问题。

退房...... http://answers.unity3d.com/answers/1146173/view.html

和...... http://answers.unity3d.com/answers/1073667/view.html

一些基本的工作代码示例....

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();
    }

请注意,您等待“.isDone”,而不是观看浮动。

(4)#你实际上必须有一个名为“preload”的场景,它只能预加载。

不幸的是,菜单场景是你的预加载场景。

你必须有一个单独的预加载场景,除了那个“预加载”之外什么都不做。

请注意,您拥有的任何“游戏管理员”必须处于预加载场景中。这有点烦人,但就是这样。

“预加载”场景的目的是容纳你拥有的任何游戏经理。

您标记为“不会在加载时销毁”的场景必须“预加载”场景。就这么简单。

这有点令人讨厌,但非常简单可靠。