//------------------------------------------------------------ // Game Framework // Copyright © 2013-2021 loyalsoft. All rights reserved. // Homepage: http://www.game7000.com/ // Feedback: http://www.game7000.com/ //------------------------------------------------------------ using GameFramework; using GameFramework.Resource; using GameFramework.Scene; using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; namespace UnityGameFramework.Runtime { /// /// 场景组件。 /// [DisallowMultipleComponent] [AddComponentMenu("Game Framework/Scene")] public sealed class SceneComponent : GameFrameworkComponent { private const int DefaultPriority = 0; private ISceneManager m_SceneManager = null; private EventComponent m_EventComponent = null; private readonly SortedDictionary m_SceneOrder = new SortedDictionary(StringComparer.Ordinal); private Camera m_MainCamera = null; private Scene m_GameFrameworkScene = default(Scene); [SerializeField] private bool m_EnableLoadSceneUpdateEvent = true; [SerializeField] private bool m_EnableLoadSceneDependencyAssetEvent = true; /// /// 获取当前场景主摄像机。 /// public Camera MainCamera { get { return m_MainCamera; } } /// /// 游戏框架组件初始化。 /// protected override void Awake() { base.Awake(); m_SceneManager = GameFrameworkEntry.GetModule(); if (m_SceneManager == null) { Log.Fatal("Scene manager is invalid."); return; } m_SceneManager.LoadSceneSuccess += OnLoadSceneSuccess; m_SceneManager.LoadSceneFailure += OnLoadSceneFailure; if (m_EnableLoadSceneUpdateEvent) { m_SceneManager.LoadSceneUpdate += OnLoadSceneUpdate; } if (m_EnableLoadSceneDependencyAssetEvent) { m_SceneManager.LoadSceneDependencyAsset += OnLoadSceneDependencyAsset; } m_SceneManager.UnloadSceneSuccess += OnUnloadSceneSuccess; m_SceneManager.UnloadSceneFailure += OnUnloadSceneFailure; m_GameFrameworkScene = UnityEngine.SceneManagement.SceneManager.GetSceneAt(GameEntry.GameFrameworkSceneId); if (!m_GameFrameworkScene.IsValid()) { Log.Fatal("Game Framework scene is invalid."); return; } } private void Start() { BaseComponent baseComponent = GameEntry.GetComponent(); if (baseComponent == null) { Log.Fatal("Base component is invalid."); return; } m_EventComponent = GameEntry.GetComponent(); if (m_EventComponent == null) { Log.Fatal("Event component is invalid."); return; } if (baseComponent.EditorResourceMode) { m_SceneManager.SetResourceManager(baseComponent.EditorResourceHelper); } else { m_SceneManager.SetResourceManager(GameFrameworkEntry.GetModule()); } } /// /// 获取场景名称。 /// /// 场景资源名称。 /// 场景名称。 public static string GetSceneName(string sceneAssetName) { if (string.IsNullOrEmpty(sceneAssetName)) { Log.Error("Scene asset name is invalid."); return null; } int sceneNamePosition = sceneAssetName.LastIndexOf('/'); if (sceneNamePosition + 1 >= sceneAssetName.Length) { Log.Error("Scene asset name '{0}' is invalid.", sceneAssetName); return null; } string sceneName = sceneAssetName.Substring(sceneNamePosition + 1); sceneNamePosition = sceneName.LastIndexOf(".unity"); if (sceneNamePosition > 0) { sceneName = sceneName.Substring(0, sceneNamePosition); } return sceneName; } /// /// 获取场景是否已加载。 /// /// 场景资源名称。 /// 场景是否已加载。 public bool SceneIsLoaded(string sceneAssetName) { return m_SceneManager.SceneIsLoaded(sceneAssetName); } /// /// 获取已加载场景的资源名称。 /// /// 已加载场景的资源名称。 public string[] GetLoadedSceneAssetNames() { return m_SceneManager.GetLoadedSceneAssetNames(); } /// /// 获取已加载场景的资源名称。 /// /// 已加载场景的资源名称。 public void GetLoadedSceneAssetNames(List results) { m_SceneManager.GetLoadedSceneAssetNames(results); } /// /// 获取场景是否正在加载。 /// /// 场景资源名称。 /// 场景是否正在加载。 public bool SceneIsLoading(string sceneAssetName) { return m_SceneManager.SceneIsLoading(sceneAssetName); } /// /// 获取正在加载场景的资源名称。 /// /// 正在加载场景的资源名称。 public string[] GetLoadingSceneAssetNames() { return m_SceneManager.GetLoadingSceneAssetNames(); } /// /// 获取正在加载场景的资源名称。 /// /// 正在加载场景的资源名称。 public void GetLoadingSceneAssetNames(List results) { m_SceneManager.GetLoadingSceneAssetNames(results); } /// /// 获取场景是否正在卸载。 /// /// 场景资源名称。 /// 场景是否正在卸载。 public bool SceneIsUnloading(string sceneAssetName) { return m_SceneManager.SceneIsUnloading(sceneAssetName); } /// /// 获取正在卸载场景的资源名称。 /// /// 正在卸载场景的资源名称。 public string[] GetUnloadingSceneAssetNames() { return m_SceneManager.GetUnloadingSceneAssetNames(); } /// /// 获取正在卸载场景的资源名称。 /// /// 正在卸载场景的资源名称。 public void GetUnloadingSceneAssetNames(List results) { m_SceneManager.GetUnloadingSceneAssetNames(results); } /// /// 检查场景资源是否存在。 /// /// 要检查场景资源的名称。 /// 场景资源是否存在。 public bool HasScene(string sceneAssetName) { if (string.IsNullOrEmpty(sceneAssetName)) { Log.Error("Scene asset name is invalid."); return false; } if (!sceneAssetName.StartsWith("Assets/", StringComparison.Ordinal) || !sceneAssetName.EndsWith(".unity", StringComparison.Ordinal)) { Log.Error("Scene asset name '{0}' is invalid.", sceneAssetName); return false; } return m_SceneManager.HasScene(sceneAssetName); } /// /// 加载场景。 /// /// 场景资源名称。 public void LoadScene(string sceneAssetName) { LoadScene(sceneAssetName, DefaultPriority, null); } /// /// 加载场景。 /// /// 场景资源名称。 /// 加载场景资源的优先级。 public void LoadScene(string sceneAssetName, int priority) { LoadScene(sceneAssetName, priority, null); } /// /// 加载场景。 /// /// 场景资源名称。 /// 用户自定义数据。 public void LoadScene(string sceneAssetName, object userData) { LoadScene(sceneAssetName, DefaultPriority, userData); } /// /// 加载场景。 /// /// 场景资源名称。 /// 加载场景资源的优先级。 /// 用户自定义数据。 public void LoadScene(string sceneAssetName, int priority, object userData) { if (string.IsNullOrEmpty(sceneAssetName)) { Log.Error("Scene asset name is invalid."); return; } if (!sceneAssetName.StartsWith("Assets/", StringComparison.Ordinal) || !sceneAssetName.EndsWith(".unity", StringComparison.Ordinal)) { Log.Error("Scene asset name '{0}' is invalid.", sceneAssetName); return; } m_SceneManager.LoadScene(sceneAssetName, priority, userData); } /// /// 卸载场景。 /// /// 场景资源名称。 public void UnloadScene(string sceneAssetName) { UnloadScene(sceneAssetName, null); } /// /// 卸载场景。 /// /// 场景资源名称。 /// 用户自定义数据。 public void UnloadScene(string sceneAssetName, object userData) { if (string.IsNullOrEmpty(sceneAssetName)) { Log.Error("Scene asset name is invalid."); return; } if (!sceneAssetName.StartsWith("Assets/", StringComparison.Ordinal) || !sceneAssetName.EndsWith(".unity", StringComparison.Ordinal)) { Log.Error("Scene asset name '{0}' is invalid.", sceneAssetName); return; } m_SceneManager.UnloadScene(sceneAssetName, userData); m_SceneOrder.Remove(sceneAssetName); } /// /// 设置场景顺序。 /// /// 场景资源名称。 /// 要设置的场景顺序。 public void SetSceneOrder(string sceneAssetName, int sceneOrder) { if (string.IsNullOrEmpty(sceneAssetName)) { Log.Error("Scene asset name is invalid."); return; } if (!sceneAssetName.StartsWith("Assets/", StringComparison.Ordinal) || !sceneAssetName.EndsWith(".unity", StringComparison.Ordinal)) { Log.Error("Scene asset name '{0}' is invalid.", sceneAssetName); return; } if (SceneIsLoading(sceneAssetName)) { m_SceneOrder[sceneAssetName] = sceneOrder; return; } if (SceneIsLoaded(sceneAssetName)) { m_SceneOrder[sceneAssetName] = sceneOrder; RefreshSceneOrder(); return; } Log.Error("Scene '{0}' is not loaded or loading.", sceneAssetName); } /// /// 刷新当前场景主摄像机。 /// public void RefreshMainCamera() { m_MainCamera = Camera.main; } private void RefreshSceneOrder() { if (m_SceneOrder.Count > 0) { string maxSceneName = null; int maxSceneOrder = 0; foreach (KeyValuePair sceneOrder in m_SceneOrder) { if (SceneIsLoading(sceneOrder.Key)) { continue; } if (maxSceneName == null) { maxSceneName = sceneOrder.Key; maxSceneOrder = sceneOrder.Value; continue; } if (sceneOrder.Value > maxSceneOrder) { maxSceneName = sceneOrder.Key; maxSceneOrder = sceneOrder.Value; } } if (maxSceneName == null) { SetActiveScene(m_GameFrameworkScene); return; } Scene scene = UnityEngine.SceneManagement.SceneManager.GetSceneByName(GetSceneName(maxSceneName)); if (!scene.IsValid()) { Log.Error("Active scene '{0}' is invalid.", maxSceneName); return; } SetActiveScene(scene); } else { SetActiveScene(m_GameFrameworkScene); } } private void SetActiveScene(Scene activeScene) { Scene lastActiveScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); if (lastActiveScene != activeScene) { UnityEngine.SceneManagement.SceneManager.SetActiveScene(activeScene); m_EventComponent.Fire(this, ActiveSceneChangedEventArgs.Create(lastActiveScene, activeScene)); } RefreshMainCamera(); } private void OnLoadSceneSuccess(object sender, GameFramework.Scene.LoadSceneSuccessEventArgs e) { if (!m_SceneOrder.ContainsKey(e.SceneAssetName)) { m_SceneOrder.Add(e.SceneAssetName, 0); } m_EventComponent.Fire(this, LoadSceneSuccessEventArgs.Create(e)); RefreshSceneOrder(); } private void OnLoadSceneFailure(object sender, GameFramework.Scene.LoadSceneFailureEventArgs e) { Log.Warning("Load scene failure, scene asset name '{0}', error message '{1}'.", e.SceneAssetName, e.ErrorMessage); m_EventComponent.Fire(this, LoadSceneFailureEventArgs.Create(e)); } private void OnLoadSceneUpdate(object sender, GameFramework.Scene.LoadSceneUpdateEventArgs e) { m_EventComponent.Fire(this, LoadSceneUpdateEventArgs.Create(e)); } private void OnLoadSceneDependencyAsset(object sender, GameFramework.Scene.LoadSceneDependencyAssetEventArgs e) { m_EventComponent.Fire(this, LoadSceneDependencyAssetEventArgs.Create(e)); } private void OnUnloadSceneSuccess(object sender, GameFramework.Scene.UnloadSceneSuccessEventArgs e) { m_EventComponent.Fire(this, UnloadSceneSuccessEventArgs.Create(e)); m_SceneOrder.Remove(e.SceneAssetName); RefreshSceneOrder(); } private void OnUnloadSceneFailure(object sender, GameFramework.Scene.UnloadSceneFailureEventArgs e) { Log.Warning("Unload scene failure, scene asset name '{0}'.", e.SceneAssetName); m_EventComponent.Fire(this, UnloadSceneFailureEventArgs.Create(e)); } } }