所以我有一个画布,它不会被破坏,因为它保持并且滑块显示进度条。它还有一个按钮,当加载进度为0.9时可以互动。我遇到的问题是当我点击按钮时(参见activateNewScene())。基本上发生的事情是,当我点击按钮是我加载我的场景和我禁用我的画布。但问题是,在禁用我的画布后,旧场景仍会显示约0.5秒,并且会加载新场景。我想要的是,在画布被禁用后,新场景应该出现。没有在短时间内看到旧场景。
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;
}
}
答案 0 :(得分:0)
首次发布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
功能。请参阅this
帖子中的enableScene
功能。我也看到了这方面的错误,如果这仍然是一个问题,你可能想要从编辑器提交错误报告。
答案 1 :(得分:0)
我明白了。我认为这是因为画布。尝试将代码放在禁用画布的位置,并在函数 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);
}
}
我将场景名称添加到函数中以激活它。