2021-05-16 09:28:05 +00:00
|
|
|
|
// Bootstrap ServerWorld, ClientWorld just like in ECS.
|
2021-05-16 09:50:16 +00:00
|
|
|
|
|
|
|
|
|
using System;
|
2021-05-16 09:28:05 +00:00
|
|
|
|
using UnityEngine;
|
2021-05-16 07:55:39 +00:00
|
|
|
|
using UnityEngine.SceneManagement;
|
2021-05-16 07:10:31 +00:00
|
|
|
|
|
2021-05-16 09:28:05 +00:00
|
|
|
|
public class Bootstrap : MonoBehaviour
|
2021-05-16 07:10:31 +00:00
|
|
|
|
{
|
2021-05-16 07:55:39 +00:00
|
|
|
|
// Server/Client worlds for easy access
|
|
|
|
|
public const string ClientWorldName = "ClientWorld";
|
|
|
|
|
public const string ServerWorldName = "ServerWorld";
|
2021-05-16 09:28:52 +00:00
|
|
|
|
|
2021-05-16 09:27:27 +00:00
|
|
|
|
public static Scene ClientWorld;
|
|
|
|
|
public static Scene ServerWorld;
|
2021-05-16 09:28:52 +00:00
|
|
|
|
|
2021-05-16 09:31:01 +00:00
|
|
|
|
// original scene is not public. it will become the server scene after merge.
|
2021-05-16 09:27:27 +00:00
|
|
|
|
static Scene originalScene;
|
2021-05-16 09:31:01 +00:00
|
|
|
|
|
|
|
|
|
// this will always be the original scene's path.
|
|
|
|
|
public static string originalScenePath;
|
2021-05-16 09:28:52 +00:00
|
|
|
|
|
|
|
|
|
static bool initialized;
|
2021-05-16 07:55:39 +00:00
|
|
|
|
|
|
|
|
|
void Awake()
|
|
|
|
|
{
|
2021-05-16 09:27:27 +00:00
|
|
|
|
// we only do world initialization ONCE
|
|
|
|
|
// duplicating a scene would call Awake here again.
|
|
|
|
|
if (initialized) return;
|
|
|
|
|
initialized = true;
|
|
|
|
|
|
2021-05-16 07:55:39 +00:00
|
|
|
|
// remember the original scene
|
|
|
|
|
originalScene = SceneManager.GetActiveScene();
|
2021-05-16 09:27:27 +00:00
|
|
|
|
originalScenePath = originalScene.path;
|
2021-05-16 07:55:39 +00:00
|
|
|
|
|
|
|
|
|
// let's create a ServerWorld and ClientWorld like in DOTSNET
|
|
|
|
|
// so that even if we connect client 1 hour after starting server,
|
|
|
|
|
// the client still starts with a fresh client scene like everyone else.
|
|
|
|
|
SceneManager.CreateScene(ClientWorldName);
|
|
|
|
|
SceneManager.CreateScene(ServerWorldName);
|
|
|
|
|
ClientWorld = SceneManager.GetSceneByName(ClientWorldName);
|
|
|
|
|
ServerWorld = SceneManager.GetSceneByName(ServerWorldName);
|
|
|
|
|
|
|
|
|
|
// can't merge any scenes yet because not loaded in Awake() yet.
|
|
|
|
|
// setup OnSceneLoaded callback and continue there.
|
|
|
|
|
SceneManager.sceneLoaded += OnSceneLoaded;
|
2021-05-16 09:27:27 +00:00
|
|
|
|
|
|
|
|
|
// duplicate original scene. we'll move it into ClientWorld
|
|
|
|
|
// -> additive, otherwise we would just reload it
|
2021-05-16 09:50:16 +00:00
|
|
|
|
//SceneManager.LoadScene(originalScene.path, LoadSceneMode.Additive);
|
2021-05-16 07:55:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-16 09:42:25 +00:00
|
|
|
|
// remove audio listener and main camera from server world
|
|
|
|
|
static void StripServerWorld()
|
|
|
|
|
{
|
|
|
|
|
// backup active scene
|
|
|
|
|
Scene backup = SceneManager.GetActiveScene();
|
|
|
|
|
|
|
|
|
|
// load server scene
|
|
|
|
|
if (SceneManager.SetActiveScene(ServerWorld))
|
|
|
|
|
{
|
|
|
|
|
Debug.Log($"Bootstrap: stripping {ServerWorldName}");
|
|
|
|
|
|
|
|
|
|
// remove all audio listeners
|
|
|
|
|
foreach (AudioListener audio in FindObjectsOfType<AudioListener>())
|
|
|
|
|
Destroy(audio);
|
|
|
|
|
|
|
|
|
|
// remove all cameras
|
|
|
|
|
foreach (Camera cam in FindObjectsOfType<Camera>())
|
|
|
|
|
Destroy(cam);
|
|
|
|
|
|
2021-05-16 09:50:16 +00:00
|
|
|
|
// remove all lights, otherwise we have double intensity
|
|
|
|
|
//foreach (Light light in FindObjectsOfType<Light>())
|
|
|
|
|
// Destroy(light);
|
|
|
|
|
|
2021-05-16 09:42:25 +00:00
|
|
|
|
// restore active scene
|
|
|
|
|
if (!SceneManager.SetActiveScene(backup))
|
|
|
|
|
Debug.LogError($"Bootstrap: failed to restore active scene {backup.path}");
|
|
|
|
|
}
|
|
|
|
|
else Debug.LogError($"Bootstrap: failed to activate {ServerWorldName}");
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-16 07:55:39 +00:00
|
|
|
|
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
|
|
|
|
{
|
2021-05-16 09:50:16 +00:00
|
|
|
|
Debug.Log($"OnSceneLoaded: {scene.name} {scene.path}");
|
2021-05-16 09:27:27 +00:00
|
|
|
|
|
2021-05-16 07:55:39 +00:00
|
|
|
|
// is this for the original scene?
|
|
|
|
|
if (scene == originalScene)
|
|
|
|
|
{
|
2021-05-16 09:50:16 +00:00
|
|
|
|
//Debug.Log($"duplicated scene loaded");
|
|
|
|
|
SceneManager.MergeScenes(scene, ClientWorld);
|
|
|
|
|
Debug.Log($"Bootstrap: original scene merged into {ClientWorldName}!");
|
2021-05-16 09:27:27 +00:00
|
|
|
|
}
|
|
|
|
|
// not the same scene, but same path. so it's the duplicate.
|
|
|
|
|
else if (scene.path == originalScenePath)
|
|
|
|
|
{
|
2021-05-16 09:50:16 +00:00
|
|
|
|
//Debug.Log($"original scene loaded");
|
|
|
|
|
SceneManager.MergeScenes(scene, ServerWorld);
|
|
|
|
|
Debug.Log($"Bootstrap: original scene merged into {ServerWorldName}!");
|
|
|
|
|
StripServerWorld();
|
2021-05-16 07:55:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-16 07:10:31 +00:00
|
|
|
|
}
|