A sample of code from a Unity Scenemanager I made for a game jam.
public class SceneLoader : MonoBehaviour, IEventListener
{
[System.Serializable]
public class SceneGroup
{
public string name;
public List<int> indices;
}
[SerializeField] private List<SceneGroup> sceneGroups;
[SerializeField] private GameObject loadScreenCamera;
[SerializeField] private GameObject loadScreenCanvas;
List<int> activeSceneIndices;
private int numLoadedScenes = -1;
private int numScenesMaintained = 0;
private EventManager eventManager;
private Coroutine isLoading = null;
// Start is called before the first frame update
private void Awake()
{
Team2Proj.GameCore.Instance.Build();
Application.targetFrameRate = 90;
//Cursor.visible = false;
activeSceneIndices = new List<int>();
FullUnloadThenLoad(sceneGroups[1].indices);
eventManager = EventManager.GetInstance();
}
void OnEnable()
{
SceneManager.sceneLoaded += CheckSceneLoading;
SceneManager.sceneUnloaded += CheckSceneUnloading;
}
void OnDisable()
{
SceneManager.sceneLoaded -= CheckSceneLoading;
SceneManager.sceneUnloaded -= CheckSceneUnloading;
}
public void FullUnloadThenLoadByName(string sceneName)
{
SceneGroup matchingItem = sceneGroups.Where(item => item.name == sceneName).First();
FullUnloadThenLoad(matchingItem.indices);
}
void FullUnloadThenLoad(List<int> indices)
{
//if we aren't already loading something
if (isLoading == null)
{
//activate loading screen
if (loadScreenCamera && loadScreenCanvas)
{
loadScreenCanvas.SetActive(true);
loadScreenCamera.SetActive(true);
}
//then start the loading coroutine
isLoading = StartCoroutine(LoadScenes(indices));
}
}
public void AdditiveLoadByName(string sceneName)
{
SceneGroup matchingItem = sceneGroups.Where(item => item.name == sceneName).First();
AdditiveLoad(matchingItem.indices);
}
void AdditiveLoad(List<int> indices)
{
foreach (int index in indices)
{
if (activeSceneIndices.Contains(index))
{
Debug.LogError("Attempted to load already loaded scene with index " + index);
return;
}
}
//if we aren't already loading something
if (isLoading == null)
{
//activate loading screen
if (loadScreenCamera && loadScreenCanvas)
{
loadScreenCanvas.SetActive(true);
loadScreenCamera.SetActive(true);
}
//then start the loading coroutine
isLoading = StartCoroutine(LoadWithoutUnload(indices));
}
}
public void UnloadScenesByName(string sceneName)
{
SceneGroup matchingItem = sceneGroups.Where(item => item.name == sceneName).First();
UnloadScenes(matchingItem.indices);
}
void UnloadScenes(List<int> indices)
{
foreach (int index in indices)
{
if (!activeSceneIndices.Contains(index))
{
Debug.LogError("Attempted to unload currently unloaded scene with index " + index);
return;
}
}
//if we aren't already loading something
if (isLoading == null)
{
//activate loading screen
if (loadScreenCamera && loadScreenCanvas)
{
loadScreenCanvas.SetActive(true);
loadScreenCamera.SetActive(true);
}
//then start the loading coroutine
isLoading = StartCoroutine(UnloadSome(indices));
}
}
private IEnumerator LoadWithoutUnload(List<int> indices)
{
//load the new set of scenes and store their indices
for (int i = 0; i < indices.Count; ++i)
{
activeSceneIndices.Add(indices[i]);
SceneManager.LoadSceneAsync(indices[i], LoadSceneMode.Additive);
}
//wait for all new scenes to be loaded
do
{
yield return new WaitForEndOfFrame();
} while (numLoadedScenes != numScenesMaintained + indices.Count);
//deactivate the loading screen
if (loadScreenCamera && loadScreenCanvas)
{
loadScreenCanvas.SetActive(false);
loadScreenCamera.SetActive(false);
}
isLoading = null;
}
private IEnumerator UnloadSome(List<int> indices)
{
int currentScenesLoaded = numLoadedScenes;
foreach (int index in indices)
{
if (activeSceneIndices.Contains(index))
{
SceneManager.UnloadSceneAsync(index);
activeSceneIndices.Remove(index);
}
}
//wait for scenes to be unloaded
do
{
yield return new WaitForEndOfFrame();
} while (numLoadedScenes != currentScenesLoaded - indices.Count);
//deactivate the loading screen
if (loadScreenCamera && loadScreenCanvas)
{
loadScreenCanvas.SetActive(false);
loadScreenCamera.SetActive(false);
}
isLoading = null;
}
private IEnumerator LoadScenes(List<int> indices)
{
//unload all active scenes
for (int i = 0; i < activeSceneIndices.Count; ++i)
{
SceneManager.UnloadSceneAsync(activeSceneIndices[i]);
}
//wait for all old scenes to be unloaded
do
{
yield return new WaitForEndOfFrame();
} while (numLoadedScenes != numScenesMaintained);
numScenesMaintained = numLoadedScenes;
//clear old scene indices
activeSceneIndices.Clear();
//load the new set of scenes and store their indices
for (int i = 0; i < indices.Count; ++i)
{
activeSceneIndices.Add(indices[i]);
SceneManager.LoadSceneAsync(indices[i], LoadSceneMode.Additive);
}
//wait for all new scenes to be loaded
do
{
yield return new WaitForEndOfFrame();
} while (numLoadedScenes != numScenesMaintained + indices.Count);
numScenesMaintained = numLoadedScenes;
//deactivate the loading screen
if (loadScreenCamera && loadScreenCanvas)
{
loadScreenCanvas.SetActive(false);
loadScreenCamera.SetActive(false);
}
isLoading = null;
}
void CheckSceneLoading(Scene scene, LoadSceneMode mode)
{
++numLoadedScenes;
}
void CheckSceneUnloading(Scene scene)
{
--numLoadedScenes;
}
public void HandleEvent(Event incomingEvent)
{
switch (incomingEvent.GetEventType())
{
}
}
Like this:
Like Loading...