添加空场景

新建一个Scene,命名为“Empty”,删除里面的灯光和摄像机,并将它放进Build Setting里面

GameSceneManager

在Scripts文件夹下新建GameSceneManager脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameSceneManager : SingletonPattern<GameSceneManager>
{
public event Action OnSceneLoaded;
public event Action OnSceneStartLoad;
/// <summary>
/// 当前场景名
/// </summary>
public string CurrentSceneName { get; set; }
/// <summary>
/// 当前场景是否加载完成
/// </summary>
public bool AlreadyLoadScene { get; set; } = false;
private MonoBehaviour m_Mono;
public static int LoadingProgress = 0;//static??
public void Init(MonoBehaviour mono)
{
this.m_Mono = mono;
}
/// <summary>
/// 加载场景
/// </summary>
/// <param name="name">场景名</param>
public void LoadScene(string name)
{
m_Mono.StartCoroutine(LoadSceneAsync(name));
}
/// <summary>
/// 设置场景环境(根据配置表)
/// </summary>
void SetSceneSetting(string sceneName)
{

}
IEnumerator LoadSceneAsync(string name)
{
OnSceneStartLoad?.Invoke();
ClearCache();
AlreadyLoadScene = false;
AsyncOperation unLoadScene = SceneManager.LoadSceneAsync("Empty",LoadSceneMode.Single);
while(unLoadScene != null && !unLoadScene.isDone)
{
yield return new WaitForEndOfFrame();
}

LoadingProgress = 0;
int targetProgress = 0;
AsyncOperation asyncScene = SceneManager.LoadSceneAsync(name);
if(asyncScene != null && !asyncScene.isDone)
{
asyncScene.allowSceneActivation = false;
while (asyncScene.progress < 0.9f)
{
targetProgress = (int)asyncScene.progress * 100;
yield return new WaitForEndOfFrame();
//平滑过渡
while (LoadingProgress < targetProgress)
{
++LoadingProgress;
yield return new WaitForEndOfFrame();
}
}
CurrentSceneName = name;
SetSceneSetting(CurrentSceneName);
targetProgress = 100;
while (LoadingProgress < targetProgress - 2)
{
++LoadingProgress;
yield return new WaitForEndOfFrame();
}
LoadingProgress = 100;
asyncScene.allowSceneActivation = true;
AlreadyLoadScene = true;
OnSceneLoaded?.Invoke();
}
yield return null;
}

private void ClearCache()
{
ObjectPoolManager.Instance.ClearCache();
ResourceManager.Instance.ClearCache();
}
}

LoadingUI

制作一个LoadingPanel,里面有一个Progress Bar和txt Prg;做成Prefab并添加离线数据(参考上一节)

LoadingPanel脚本

1
2
3
4
5
6
7
8
using UnityEngine;
using UnityEngine.UI;

public class LoadingPanel : MonoBehaviour
{
public Image progressBar;
public Text txtPrg;
}

ConstentStr

1
2
3
4
5
6
7
8
9
10
11
12
public class ConstentStr
{
#region 界面名称,带拓展名用于加载
public const string LOADINGPANEL = "LoadingPanel.prefab";
public const string MENUPANEL = "MenuPanel.prefab";
#endregion

#region 场景名称
public const string EMPTYSCENE = "Empty";
public const string MENUSCENE = "Menu";
#endregion
}

LoadingWnd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LoadingWnd : WindowBase
{
private LoadingPanel m_LoadingPanel;
//要加载的场景名称
private string m_SceneName;
public override void OnAwake(params object[] args)
{
m_LoadingPanel = GameObject.GetComponent<LoadingPanel>();
m_SceneName = args[0].ToString();
GameSceneManager.Instance.OnSceneLoaded += LoadOtherSceneStartUI;

}
public override void OnUpdate()
{
if (m_LoadingPanel == null)
{
return;
}
m_LoadingPanel.progressBar.fillAmount = GameSceneManager.LoadingProgress / 100.0f;
m_LoadingPanel.txtPrg.text = string.Format("{0}%",GameSceneManager.LoadingProgress);
}
/// <summary>
/// 加载对应场景的开始UI
/// </summary>
void LoadOtherSceneStartUI()
{
if (m_SceneName == ConstentStr.MENUSCENE)
{
UIManager.Instance.CreateWindow(ConstentStr.MENUPANEL);
}
UIManager.Instance.CloseWnd(ConstentStr.LOADINGPANEL);
}

}


GameSceneManager调用

1
2
3
4
5
6
7
8
9
10
/// <summary>
/// 加载场景
/// </summary>
/// <param name="name">场景名</param>
public void LoadScene(string name)
{
m_Mono.StartCoroutine(LoadSceneAsync(name));
UIManager.Instance.CreateWindow(ConstentStr.LOADINGPANEL,true,false,name);
}