197 lines
7.1 KiB
C#
197 lines
7.1 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
using VOID.Generic.Navigation;
|
|
using VOID.Generic.Objects.Unit;
|
|
using VOID.Generic.Player;
|
|
using VOID.Generic.SaveLoad;
|
|
using VOID.UserInterface.LoadingScreen;
|
|
using VOID.Generic.Util;
|
|
using VOID.Generic.World;
|
|
|
|
namespace VOID.Generic
|
|
{
|
|
public class GameLoopManager : MonoBehaviour
|
|
{
|
|
public static GameLoopManager current { get; private set; }
|
|
|
|
[SerializeField] private SceneReference _mainMenuScene;
|
|
[SerializeField] private SceneReference _LoadingScreenScene;
|
|
[SerializeField] private SceneReference _lobbyScene;
|
|
[SerializeField] private SceneReference _worldGeneratorScene;
|
|
|
|
private void Awake()
|
|
{
|
|
if (current)
|
|
{
|
|
Debug.LogWarning("Instance of " + nameof(GameLoopManager) + " already exists!");
|
|
Destroy(this);
|
|
return;
|
|
}
|
|
|
|
// Only one instance for whole game, this should manage scene changing nad using all other managers
|
|
// DontDestroyOnLoad works only on root game object so we need to unparent it
|
|
current = this;
|
|
current.transform.parent = null;
|
|
DontDestroyOnLoad(this);
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
// Only for dev/debug purpose - start instantly current scene
|
|
if (SceneManager.GetActiveScene().path != _mainMenuScene)
|
|
{
|
|
StartCoroutine(InitializeDebugScene());
|
|
return;
|
|
}
|
|
|
|
StartCoroutine(InitializeMainMenu());
|
|
}
|
|
|
|
private IEnumerator InitializeDebugScene()
|
|
{
|
|
// wait for other things
|
|
yield return new WaitForFixedUpdate();
|
|
|
|
// So far only thing needed for dev/debug scene to work is initialize player's units
|
|
if (PlayerController.current.mainUnit)
|
|
{
|
|
PlayerController.current.SetMainUnit(PlayerController.current.mainUnit);
|
|
PlayerController.current.SetMainUnitActive();
|
|
CameraManager.current.stickTo = PlayerController.current.mainUnit.transform;
|
|
}
|
|
|
|
if (PlayerController.current.subUnit)
|
|
{
|
|
PlayerController.current.SetSubUnit(PlayerController.current.subUnit);
|
|
}
|
|
|
|
// Create (if missing) profile and load it
|
|
PlayerProfileManager.current.SelectProfile(PlayerProfileManager.current.GetDefaultProfile());
|
|
}
|
|
|
|
private IEnumerator InitializeMainMenu()
|
|
{
|
|
// wait for other things
|
|
yield return new WaitForFixedUpdate();
|
|
|
|
// Load last profile if exists
|
|
var defaultProfile = PlayerProfileManager.current.GetDefaultProfile();
|
|
if (defaultProfile != null) PlayerProfileManager.current.SelectProfile(defaultProfile);
|
|
|
|
LoadMainMenuAfter().ForEach(action => action.Invoke());
|
|
}
|
|
|
|
#region BeforeLoading
|
|
|
|
public void LoadMainMenu()
|
|
{
|
|
StartCoroutine(LoadScene(_mainMenuScene, LoadMainMenuAfter()));
|
|
}
|
|
|
|
public void LoadLobby()
|
|
{
|
|
StartCoroutine(LoadScene(_lobbyScene, LoadLobbyAfter()));
|
|
}
|
|
|
|
public void LoadGenerator(UnitObject playerUnit)
|
|
{
|
|
// Dont destroy selected avatar by player on scene change, to do that we need to remove its PARENT!
|
|
playerUnit.gameObject.transform.parent = null;
|
|
DontDestroyOnLoad(playerUnit.gameObject);
|
|
|
|
StartCoroutine(LoadScene(_worldGeneratorScene, LoadGeneratorAfter(playerUnit)));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region LoadingScreen
|
|
|
|
private IEnumerator LoadScene(SceneReference sceneReference, List<Action> onLoadAfter)
|
|
{
|
|
// Load LoadingScene
|
|
// Reset loading progress
|
|
// Previous scene will be automatically unloaded
|
|
var loadAsync = SceneManager.LoadSceneAsync(_LoadingScreenScene, LoadSceneMode.Single);
|
|
yield return new WaitUntil(() => loadAsync.isDone);
|
|
LoadingScreenUI.current.SetProgress(0f);
|
|
yield return new WaitForEndOfFrame();
|
|
|
|
// Load wanted scene
|
|
// Important - make that scene active before any Awake() execute!
|
|
var sceneAsync = SceneManager.LoadSceneAsync(sceneReference, LoadSceneMode.Additive);
|
|
sceneAsync.completed += _ => SceneManager.SetActiveScene(SceneManager.GetSceneByPath(sceneReference));
|
|
yield return new WaitUntil(() => sceneAsync.isDone);
|
|
LoadingScreenUI.current.SetProgress(0.2f);
|
|
yield return new WaitForEndOfFrame();
|
|
|
|
// Additional steps to do before fully changing to next scene
|
|
if (onLoadAfter.Count > 0)
|
|
{
|
|
var progressPerAction = 0.8f / onLoadAfter.Count;
|
|
for (var i = 0; i < onLoadAfter.Count; i++)
|
|
{
|
|
onLoadAfter[i].Invoke();
|
|
LoadingScreenUI.current.SetProgress(0.2f + (i+1) * progressPerAction);
|
|
yield return new WaitForEndOfFrame();
|
|
}
|
|
}
|
|
|
|
// Set progress to 100% + TODO: wait 1 second so we won't be too "fast"
|
|
LoadingScreenUI.current.SetProgress(1f);
|
|
yield return new WaitForSecondsRealtime(1f);
|
|
|
|
// Change to next scene + remove loading screen
|
|
SceneManager.UnloadSceneAsync(_LoadingScreenScene);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region AfterLoading
|
|
|
|
private List<Action> LoadGeneratorAfter(UnitObject playerUnit)
|
|
{
|
|
return new List<Action> { GenerateWorld, GenerateNavMesh, InitializePlayer };
|
|
|
|
void GenerateWorld()
|
|
{
|
|
// Generate world
|
|
var seed = RandomUtil.RandomInteger(0, int.MaxValue);
|
|
WorldGeneratorManager.current.Generate(150, seed, true);
|
|
Debug.Log("World Generated with seed: " + seed);
|
|
}
|
|
|
|
void GenerateNavMesh()
|
|
{
|
|
// Build nav mesh for whole map
|
|
NavigationManager.current.BuildNavMesh();
|
|
}
|
|
|
|
void InitializePlayer()
|
|
{
|
|
// initialize managers with selected player avatar
|
|
playerUnit.transform.position = new Vector3(0, 0, 0);
|
|
PlayerController.current.SetMainUnit(playerUnit);
|
|
PlayerController.current.SetMainUnitActive();
|
|
CameraManager.current.stickTo = playerUnit.transform;
|
|
|
|
// Make avatar destroyable again on scene change
|
|
SceneManager.MoveGameObjectToScene(playerUnit.gameObject, SceneManager.GetActiveScene());
|
|
}
|
|
}
|
|
|
|
private List<Action> LoadMainMenuAfter()
|
|
{
|
|
return new List<Action>() { };
|
|
}
|
|
|
|
private List<Action> LoadLobbyAfter()
|
|
{
|
|
return new List<Action>() { };
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |