實現思路:
加載器加載場景 -> 加載進度通知UI -> 更新UI進度異步
1.場景加載器:
SceneLoader.csasync
using UnityEngine; using System.Collections; using UnityEngine.SceneManagement; /// <summary> /// 場景加載器 /// <param>ZhangYu 2017-06-15</param> /// </summary> public class SceneLoader : MonoBehaviour { // 場景名稱 public string sceneName; // 進度事件接收者 public Transform progressReceiver; // 加載進度 private float _progress = 0; // 異步加載信息 private AsyncOperation async; /// <summary> 加載當前配置的場景 </summary> public void load(){ loadScene(sceneName); } /// <summary> 加載場景 </summary> /// <param name="sceneName">場景名稱</param> public void loadScene(string sceneName) { if (isLoading) return; this.sceneName = sceneName; _progress = 0; enabled = true; StartCoroutine(loading()); if (progressReceiver != null) { progressReceiver.gameObject.SetActive(true); progressReceiver.SendMessage("onProgress", progress, SendMessageOptions.DontRequireReceiver); } } /// <summary> 開啓協程加載場景 </summary> private IEnumerator loading() { async = SceneManager.LoadSceneAsync(sceneName); yield return async; if (progressReceiver != null) progressReceiver.gameObject.SetActive(false); async = null; } #if UNITY_EDITOR // 屏蔽Animation關鍵幀事件中的loading()可選項 private IEnumerator loading(string sceneName) { yield return null; } #endif /// <summary> 正在加載 </summary> public bool isLoading { get { return async != null; } } /// <summary> 加載進度 </summary> public float progress { get { return _progress; } } /// <summary> 更新加載進度 </summary> private void Update() { if (async == null) { enabled = false; } else { // 加載進度值範圍是0~0.9 這裏作下處理 float progress = async.progress; progress = progress < 0.9f ? progress * (10 / 9f) : 1; _progress = progress; if (progressReceiver != null) { progressReceiver.SendMessage("onProgress", progress, SendMessageOptions.DontRequireReceiver); } } } }
2.進度條:
ProgressBar.cs編輯器
using System; using UnityEngine; using UnityEngine.UI; /// <summary> /// 進度條 /// <param>ZhangYu 2017-06-15</param> /// </summary> public class ProgressBar : MonoBehaviour, IOnProgress { // 進度條 public Slider slider; // 進度文本 public Text text; #if UNITY_EDITOR private void Reset() { slider = GetComponentInChildren<Slider>(); text = GetComponentInChildren<Text>(); } #endif /// <summary> 進度變動事件 </summary> public void onProgress(float progress) { if (slider != null) slider.value = progress; if (text != null) text.text = (int)(progress * 100) + "%"; } }
3.進度更新接口:
IOnProgress.cside
/// <summary> /// 進度更新接口 /// <param>ZhangYu 2017-06-15</param> /// </summary> public interface IOnProgress { /// <summary> 進度更新事件 </summary> /// <param name="progress">進度百分比</param> void onProgress(float progress); }
附送場景加載器 編輯器:
SceneLoaderEditor.csui
using UnityEditor; using UnityEngine; /// <summary> /// 場景加載器 編輯器 /// <para>ZhangYu 2018-06-15</para> /// </summary> [CanEditMultipleObjects] [CustomEditor(typeof(SceneLoader))] public class SceneLoaderEditor : Editor { public override void OnInspectorGUI() { // 重繪GUI SceneLoader loader = (SceneLoader)target; EditorGUI.BeginChangeCheck(); drawProperty("sceneName", "場景名稱"); drawProperty("progressReceiver", "進度事件接收者"); if (loader.isLoading) EditorGUILayout.FloatField("加載進度", loader.progress); if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties(); } private void drawProperty(string property, string label) { EditorGUILayout.PropertyField(serializedObject.FindProperty(property), new GUIContent(label), true); } }
附送進度條 編輯器:
ProgressBarEditor.csthis
using UnityEditor; using UnityEngine; /// <summary> /// 進度條 編輯器 /// <para>ZhangYu 2018-06-15</para> /// </summary> [CanEditMultipleObjects] [CustomEditor(typeof(ProgressBar))] public class ProgressBarEditor : Editor { public override void OnInspectorGUI() { // 重繪GUI EditorGUI.BeginChangeCheck(); drawProperty("slider", "進度條"); drawProperty("text", "進度文本"); if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties(); } private void drawProperty(string property, string label) { EditorGUILayout.PropertyField(serializedObject.FindProperty(property), new GUIContent(label), true); } }