init
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user