切换场景时仍会短时间出现旧场景

Old scene still appears for short time when switching scene

所以我有一个 canvas,它不会被破坏,因为它持有并且滑块显示进度条。它还有一个按钮,当加载进度为 0.9 时可交互。我遇到的问题是当我单击按钮时(请参阅 activateNewScene())。基本上,当我单击按钮时,会加载我的场景并禁用我的 canvas。但问题是,在我禁用 canvas 后,旧场景仍然显示大约 0.5 秒,然后加载新场景。我想要的是 canvas 被禁用后,新场景应该出现。久不见旧景

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;

 public class SceneLoaderGameObject : MonoBehaviour {

 private SceneLoader sl;
 public Canvas cav;

 void Start () {
     sl = new SceneLoader ();
     cav.GetComponent<Canvas> ().enabled = false;
     DontDestroyOnLoad (this.gameObject);
     DontDestroyOnLoad (cav.transform.parent);
 }

 public void setNewNameAndLoadScene(string name){

     if (cav != null) {
         Slider slid = cav.transform.GetChild (1).GetComponent<Slider> ();
         Text tx = cav.transform.GetChild (2).GetComponent<Text> ();
         Button bttn = cav.transform.GetChild (3).GetComponent<Button> ();

         sl.setNewScene (name);
         sl.setSliderAndTextToChange (slid, tx);
         bttn.onClick.AddListener (() => activateNewScene ());
         cav.GetComponent<Canvas> ().enabled = true;
         cav.GetComponent<Canvas> ().sortingOrder = 1;

         StartCoroutine (sl.LoadAsynchron (name, bttn));

     }

 }

 public void  activateNewScene(){
     sl.AsgetOP().allowSceneActivation=true;
     cav.GetComponent<Canvas> ().sortingOrder = 1;
     cav.GetComponent<Canvas> ().enabled = false;
 }

}

编辑:这是加载场景的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class SceneLoader {

AsyncOperation operation;
string sceneName;
private Text txx =null;
private Slider slider=null;

public SceneLoader(){

}

public void setSliderAndTextToChange(Slider sl, Text tx){
    txx = tx;
    slider = sl;
}

public void setNewScene(string sceneName){

    if (sceneName.Length == 0) {
        throw new UnityException ("Please enter a name");
    }

    this.sceneName = sceneName;

}


public IEnumerator LoadAsynchron(string myMain, Button bttn){

    operation = SceneManager.LoadSceneAsync (myMain);
    operation.allowSceneActivation = false;
    while (operation.isDone == false) {
        float progress = Mathf.Clamp01 (operation.progress / 0.9f);
        slider.value = progress;
        txx.text = progress * 100f + " %";
        if (progress * 100f == 100f) {
            bttn.interactable = true;
        }
        yield return null;
    }
}

public AsyncOperation AsgetOP(){
    return operation;
}

}

SceneManager刚发布的时候,已知isDone只有在满足两个条件时才会为真:

1.场景加载完成后

2.场景激活时

我不知道这是否仍然正确,但我假设它是。

基本上,当您将 allowSceneActivation 设置为 false 时,条件 2 不满足,您将 运行 出问题。看起来 while (operation.isDone == false) 仍将执行,导致 bttn.interactable = true; 在您尝试加载新场景时也在每一帧执行。这是我的猜测。

while (operation.isDone == false) 替换为 while (operation.progress < 0.9f),然后将 bttn.interactable = true; 添加到该函数的末尾以防万一。

public IEnumerator LoadAsynchron(string myMain, Button bttn)
{
    operation = SceneManager.LoadSceneAsync(myMain);
    operation.allowSceneActivation = false;
    while (operation.progress < 0.9f)
    {
        float progress = Mathf.Clamp01(operation.progress / 0.9f);
        slider.value = progress;
        txx.text = progress * 100f + " %";
        if (progress * 100f == 100f)
        {
            bttn.interactable = true;
        }
        yield return null;
    }
    if (!bttn.interactable)
        bttn.interactable = true;
}

如果还是不行,建议你使用SceneManager.SetActiveScene函数。请参阅 post 中的 enableScene 函数。我也看到了这个问题,如果这仍然是个问题,你可能想向编辑器提交错误报告。

我明白了。我认为这是因为 canvas。尝试将代码放在禁用 canvas 的位置,并在函数 OnLevelWasLoaded 中将顺序设置为 0。所以基本上是这样的:

void OnLevelWasLoaded(){
    cav.GetComponent<Canvas> ().sortingOrder = 0;
    cav.GetComponent<Canvas> ().enabled = false;
}
public void  activateNewScene(string name){
    sl.AsgetOP ().allowSceneActivation = true;

    Scene sc = SceneManager.GetSceneByName(name);
    if (sc.IsValid ()) {
            SceneManager.SetActiveScene(sc);

    }

}

我在函数中添加了场景名称来激活它。