我有一个有四个场景的游戏,一个菜单场景,一个加载场景和两个游戏场景。一切都很顺利,当我从菜单场景转换到我的游戏场景时,但每当我从游戏场景转换回菜单场景或重新加载游戏场景时,加载场景就会停止响应。我收到一条警告消息,说明“NetworkManager在编辑器中检测到脚本重新加载。这导致网络关闭”仅当我尝试重新加载当前活动的游戏场景时。 当我在构建中玩时,这个问题也存在!我使用print语句来追踪我的代码停止运行的位置,并且我发现这是导致游戏的Yield Return New WaitForSeconds()冻结。那是为什么?
我有两个控制转换的脚本。 一个简单的脚本调用UIButtons来告诉预加载场景中调用的第二个更复杂的脚本,以加载它应该加载并创建动画的场景。我确保我正在加载到正确的场景,并且所有场景都添加到我的构建设置中。
以下图片显示装载场景无响应。第一张图显示了当我尝试重新加载当前游戏场景时会发生什么,第二张图显示了当我尝试加载菜单场景时会发生什么:
我的加载场景脚本:
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);
}
}
答案 0 :(得分:1)
(1)请勿使用“打印”,请使用:
Debug.Log("fadeDuration is ....... " , fadeDuration.ToString("f4");
在致电FadeOut
之前添加该行代码,并请在FadeOut
CrossFadeAlpha
请注意,CrossFadeAlpha 非常难以使用!真是太痛苦了!它仅适用于UnityEngine.UI.Graphic
,与协同程序一起使用时很棘手。
public static void FadeOut(this Graphic g)
{
g.GetComponent<CanvasRenderer>().SetAlpha(1f);
g.CrossFadeAlpha(0f,.15f,false);
}
是的,有一个
它被卡在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();
}
(4)#你实际上必须有一个名为“preload”的场景,它只能预加载。
不幸的是,菜单场景不是你的预加载场景。
你必须有一个单独的预加载场景,除了那个“预加载”之外什么都不做。
请注意,您拥有的任何“游戏管理员”必须处于预加载场景中。这有点烦人,但就是这样。
“预加载”场景的目的是容纳你拥有的任何游戏经理。
您标记为“不会在加载时销毁”的仅场景必须仅“预加载”场景。就这么简单。
这有点令人讨厌,但非常简单可靠。