//------------------------------------------------------------
// 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));
}
}
}