浏览代码

major changes on location loader to fit the new scene re architecture

/main
Amel Negra 4 年前
当前提交
403824da
共有 1 个文件被更改,包括 114 次插入88 次删除
  1. 202
      UOP1_Project/Assets/Scripts/SceneManagement/LocationLoader.cs

202
UOP1_Project/Assets/Scripts/SceneManagement/LocationLoader.cs


using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
/// <summary>
/// This class manages the scene loading and unloading.

{
[Header("Initialization Scene")]
[SerializeField] private GameSceneSO _initializationScene = default;
[Header("Persistent Manager Scene")]
[SerializeField] private GameSceneSO _persistentManagersScene = default;
[Header("Load on start")]
[SerializeField] private GameSceneSO[] _mainMenuScenes = default;
[Header("Gameplay Scene")]
[SerializeField] private GameSceneSO _gameplayScene = default;
[Header("Loading Screen")]
[SerializeField] private GameObject _loadingInterface = default;
[SerializeField] private Image _loadingProgressBar = default;
[Header("Load Events")]
//The location load event we are listening to
[SerializeField] private LoadEventChannelSO _loadLocation = default;
//The menu load event we are listening to
[SerializeField] private LoadEventChannelSO _loadMenu = default;
[Header("Load Event")]
//The load event we are listening to
[SerializeField] private LoadEventChannelSO _loadEventChannel = default;
[Header("Broadcasting on")]
[SerializeField] private BoolEventChannelSO _ToggleLoadingScreen = default;
[SerializeField] private VoidEventChannelSO _OnSceneReady = default;
private List<GameSceneSO> _persistentScenes = new List<GameSceneSO>(); //Scenes to keep loaded when a load event is raised
_loadEventChannel.OnLoadingRequested += LoadScenes;
if (_loadLocation != null)
{
_loadLocation.OnLoadingRequested += LoadLocation;
}
if (_loadMenu != null)
{
_loadMenu.OnLoadingRequested += LoadMenu;
}
_loadEventChannel.OnLoadingRequested -= LoadScenes;
}
private void Start()
{
if (SceneManager.GetActiveScene().path == _initializationScene.scenePath)
if (_loadLocation != null)
{
_loadLocation.OnLoadingRequested -= LoadLocation;
}
if (_loadMenu != null)
LoadMainMenu();
_loadMenu.OnLoadingRequested -= LoadMenu;
private void LoadMainMenu()
/// <summary>
/// This function loads the location scenes passed as array parameter
/// </summary>
/// <param name="locationsToLoad"></param>
/// <param name="showLoadingScreen"></param>
private void LoadLocation(GameSceneSO[] locationsToLoad, bool showLoadingScreen)
LoadScenes(_mainMenuScenes, false);
//When loading a location, we want to keep the persistent managers and gameplay scenes loaded
_persistentScenes.Add(_persistentManagersScene);
_persistentScenes.Add(_gameplayScene);
AddScenesToUnload(_persistentScenes);
LoadScenes(locationsToLoad, showLoadingScreen);
/// This function loads the scenes passed as array parameter
/// This function loads the menu scenes passed as array parameter
/// <param name="locationsToLoad"></param>
/// <param name="MenuToLoad"></param>
private void LoadMenu(GameSceneSO[] MenuToLoad, bool showLoadingScreen)
{
//When loading a menu, we only want to keep the persistent managers scene loaded
_persistentScenes.Add(_persistentManagersScene);
AddScenesToUnload(_persistentScenes);
LoadScenes(MenuToLoad, showLoadingScreen);
}
//Take the first scene in the array as the scene we want to set active
AddScenesToUnload();
Debug.Log("active scene = " + _activeScene.scenePath);
_loadingInterface.SetActive(true);
_ToggleLoadingScreen.RaiseEvent(true);
}
if (_scenesToLoadAsyncOperations.Count == 0)

string currentScenePath = locationsToLoad[i].scenePath;
if (IsSceneLoaded(currentScenePath) == false)
{
if (runningLoader == null)
{
_scenesToLoadAsyncOperations.Add(SceneManager.LoadSceneAsync(currentScenePath, LoadSceneMode.Additive));
_scenesToLoadAsyncOperations[i].completed += SetActiveScene;
// TODO: Run a coroutine for each scene loading that updates a combined value
// for the progress bar. This way, as each scene completes loading, we will
// know what scene it is. Then decide if it activates right away or not.
// runningLoader = StartCoroutine(TrackLoadingProgress(locationsToLoad[i]));
}
}
_scenesToLoadAsyncOperations.Add(SceneManager.LoadSceneAsync(currentScenePath, LoadSceneMode.Additive));
}
if (_scenesToLoadAsyncOperations.Count > 0)
//Checks if any of the persistent scenes is not loaded yet and load it if unloaded
//This is especially useful when we go from main menu to first location
for (int i = 0; i < _persistentScenes.Count; ++i)
{
if (IsSceneLoaded(_persistentScenes[i].scenePath) == false)
// TODO: locationsToLoad[0] is a place holder right now.
runningLoader = StartCoroutine(TrackLoadingProgress(locationsToLoad[0]));
_scenesToLoadAsyncOperations.Add(SceneManager.LoadSceneAsync(_persistentScenes[i].scenePath, LoadSceneMode.Additive));
StartCoroutine(WaitForLoading(showLoadingScreen));
}
private IEnumerator WaitForLoading(bool showLoadingScreen)
{
bool _loadingDone = false;
// Wait until all scenes are loaded
while (!_loadingDone)
{
for (int i = 0; i < _scenesToLoadAsyncOperations.Count; ++i)
{
if (!_scenesToLoadAsyncOperations[i].isDone)
{
break;
}
else
{
_loadingDone = true;
_scenesToLoadAsyncOperations.Clear();
}
}
yield return null;
}
//Set the active scene
SetActiveScene();
if (showLoadingScreen)
{
//Raise event to disable loading screen
_ToggleLoadingScreen.RaiseEvent(true);
}
/// SetActiveScene(AsyncOperation asyncOp) is called by AsyncOperation.complete event.
/// This function is called when all the scenes have been loaded
/// <param name="asyncOp"></param>
private void SetActiveScene(AsyncOperation asyncOp)
private void SetActiveScene()
// TODO: As each event completes, decide if it needs to activate right away.
//Raise the event to inform that the scene is loaded and set active
_OnSceneReady.RaiseEvent();
private void AddScenesToUnload()
private void AddScenesToUnload(List<GameSceneSO> persistentScenes)
for (int i = 0; i < SceneManager.sceneCount; i++)
for (int i = 0; i < SceneManager.sceneCount; ++i)
var scene = SceneManager.GetSceneAt(i);
var scenePath = scene.path;
if (scenePath != _initializationScene.scenePath && scenePath != _activeScene.scenePath)
Scene scene = SceneManager.GetSceneAt(i);
string scenePath = scene.path;
for (int j = 0; j < persistentScenes.Count; ++j)
Debug.Log("Added scene to unload = " + scenePath);
_scenesToUnload.Add(scene);
if (scenePath != persistentScenes[j].scenePath)
{
//Check if we reached the last persistent scenes check
if (j == persistentScenes.Count-1)
{
//If the scene is not one of the persistent scenes, we add it to the scenes to unload
_scenesToUnload.Add(scene);
}
}
else
{
//We move the next scene check as soon as we find that the scene is one of the persistent scenes
break;
}
}
}
}

if (_scenesToUnload != null)
{
for (int i = 0; i < _scenesToUnload.Count; i++)
for (int i = 0; i < _scenesToUnload.Count; ++i)
{
SceneManager.UnloadSceneAsync(_scenesToUnload[i]);
}

}
}
return false;
}
/// <summary>
/// This function updates the loading progress once per frame until loading is complete
/// </summary>
/// <param name="sceneReference">This is a place holder for the moment</param>
/// <returns>IEnumerator</returns>
private IEnumerator TrackLoadingProgress(GameSceneSO sceneReference)
{
float totalProgress = 0;
// When the scene reaches 0.9f, it means that it is loaded
// The remaining 0.1f are for the integration
while (totalProgress <= 0.9f)
{
totalProgress = 0;
for (int i = 0; i < _scenesToLoadAsyncOperations.Count; ++i)
{
Debug.Log("Scene " + i + " :" + _scenesToLoadAsyncOperations[i].isDone + " progress = " + _scenesToLoadAsyncOperations[i].progress);
totalProgress += _scenesToLoadAsyncOperations[i].progress;
}
//The fillAmount is for all scenes, so we divide the progress by the number of scenes to load
_loadingProgressBar.fillAmount = totalProgress / _scenesToLoadAsyncOperations.Count;
Debug.Log("progress bar " + _loadingProgressBar.fillAmount + " and value = " + totalProgress / _scenesToLoadAsyncOperations.Count);
yield return null;
}
_scenesToLoadAsyncOperations.Clear();
runningLoader = null;
//Hide progress bar when loading is done
_loadingInterface.SetActive(false);
}
private void ExitGame()

正在加载...
取消
保存