Implement multiplayer scene loading
This commit is contained in:
@@ -44,4 +44,13 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 324a182340742c54cbdb3967f1916e29, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
playerController: {fileID: 0}
|
||||
LobbyScene: {fileID: 102900000, guid: eaec6d3575cfd2d42a5f87b082c898c8, type: 3}
|
||||
EntranceScene: {fileID: 102900000, guid: 07047a8cc3efe2043ad21378467317ee, type: 3}
|
||||
ForgeScene: {fileID: 102900000, guid: 0850bb9b948948349b83e3612aa421af, type: 3}
|
||||
lobbySceneName: Lobby
|
||||
entranceSceneName: Entrance
|
||||
forgeSceneName: Forge
|
||||
gameManager: {fileID: 0}
|
||||
fadeDuration: 2
|
||||
loadedScene:
|
||||
m_Handle: 0
|
||||
|
||||
@@ -65,6 +65,8 @@ public class PlayerComponent : NetworkBehaviour
|
||||
|
||||
private void Start()
|
||||
{
|
||||
StartCoroutine(AddDontDestroyToDependencies());
|
||||
|
||||
if (!isSoloRig) return;
|
||||
|
||||
audioListener.enabled = true;
|
||||
@@ -108,6 +110,16 @@ public class PlayerComponent : NetworkBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator AddDontDestroyToDependencies()
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
|
||||
foreach (var d in dependencies)
|
||||
{
|
||||
DontDestroyOnLoad(d);
|
||||
}
|
||||
}
|
||||
|
||||
public void DestroyDependencies()
|
||||
{
|
||||
foreach (var d in dependencies)
|
||||
@@ -121,7 +133,7 @@ public class PlayerComponent : NetworkBehaviour
|
||||
public void Toggle(bool active)
|
||||
{
|
||||
// Only toggle solo rig components, not multiplayer one
|
||||
if (isSoloRig)
|
||||
if (networkObject == null || isSoloRig)
|
||||
{
|
||||
foreach (var d in dependencies)
|
||||
{
|
||||
|
||||
@@ -9,13 +9,40 @@ using Zenject;
|
||||
|
||||
public class SceneManager : NetworkBehaviour
|
||||
{
|
||||
enum Scene
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public UnityEditor.SceneAsset LobbyScene;
|
||||
public UnityEditor.SceneAsset EntranceScene;
|
||||
public UnityEditor.SceneAsset ForgeScene;
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
Lobby = 0,
|
||||
Entrance = 1,
|
||||
Forge = 2
|
||||
lobbySceneName = LobbyScene?.name;
|
||||
entranceSceneName = EntranceScene?.name;
|
||||
forgeSceneName = ForgeScene?.name;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
[SerializeField]
|
||||
[ReadOnly]
|
||||
private string lobbySceneName;
|
||||
|
||||
[SerializeField]
|
||||
[ReadOnly]
|
||||
private string entranceSceneName;
|
||||
|
||||
[SerializeField]
|
||||
[ReadOnly]
|
||||
private string forgeSceneName;
|
||||
|
||||
//enum Scene
|
||||
//{
|
||||
// Lobby = 0,
|
||||
// Entrance = 1,
|
||||
// Forge = 2
|
||||
//}
|
||||
|
||||
[Inject]
|
||||
[ReadOnly]
|
||||
[SerializeField]
|
||||
@@ -27,35 +54,139 @@ public class SceneManager : NetworkBehaviour
|
||||
|
||||
[ReadOnly]
|
||||
[SerializeField]
|
||||
private Scene scene;
|
||||
private Scene loadedScene;
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
NetworkManager.SceneManager.OnSceneEvent += OnSceneEvent;
|
||||
|
||||
base.OnNetworkSpawn();
|
||||
}
|
||||
|
||||
private void OnSceneEvent(SceneEvent sceneEvent)
|
||||
{
|
||||
var clientOrServer = sceneEvent.ClientId == NetworkManager.ServerClientId ? "server" : "client";
|
||||
|
||||
switch (sceneEvent.SceneEventType)
|
||||
{
|
||||
case SceneEventType.LoadComplete:
|
||||
{
|
||||
// We want to handle this for only the server-side
|
||||
if (sceneEvent.ClientId == NetworkManager.ServerClientId)
|
||||
{
|
||||
// Keep track of the loaded scene, you need this to unload it
|
||||
loadedScene = sceneEvent.Scene;
|
||||
}
|
||||
|
||||
Debug.Log($"Loaded the {sceneEvent.SceneName} scene on " +
|
||||
$"{clientOrServer}-({sceneEvent.ClientId}).");
|
||||
|
||||
break;
|
||||
}
|
||||
case SceneEventType.UnloadComplete:
|
||||
{
|
||||
Debug.Log($"Unloaded the {sceneEvent.SceneName} scene on " +
|
||||
$"{clientOrServer}-({sceneEvent.ClientId}).");
|
||||
|
||||
break;
|
||||
}
|
||||
case SceneEventType.LoadEventCompleted:
|
||||
case SceneEventType.UnloadEventCompleted:
|
||||
{
|
||||
var loadUnload = sceneEvent.SceneEventType == SceneEventType.LoadEventCompleted ? "Load" : "Unload";
|
||||
|
||||
Debug.Log($"{loadUnload} event completed for the following client " +
|
||||
$"identifiers:({sceneEvent.ClientsThatCompleted})");
|
||||
|
||||
if (sceneEvent.ClientsThatTimedOut.Count > 0)
|
||||
{
|
||||
Debug.LogWarning($"{loadUnload} event timed out for the following client " +
|
||||
$"identifiers:({sceneEvent.ClientsThatTimedOut})");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckStatus(SceneEventProgressStatus status, bool isLoading = true)
|
||||
{
|
||||
var sceneEventAction = isLoading ? "load" : "unload";
|
||||
if (status != SceneEventProgressStatus.Started)
|
||||
{
|
||||
Debug.LogWarning($"Failed to {sceneEventAction} with" +
|
||||
$" a {nameof(SceneEventProgressStatus)}: {status}");
|
||||
}
|
||||
}
|
||||
|
||||
private void UnloadScene()
|
||||
{
|
||||
// Assure only the server calls this when the NetworkObject is
|
||||
// spawned and the scene is loaded.
|
||||
if (!IsServer || !IsSpawned || !loadedScene.IsValid() || !loadedScene.isLoaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var status = NetworkManager.SceneManager.UnloadScene(loadedScene);
|
||||
CheckStatus(status, false);
|
||||
}
|
||||
|
||||
[Button]
|
||||
public void SwitchToEntranceLevel()
|
||||
{
|
||||
StartCoroutine(SwitchToScene(Scene.Entrance));
|
||||
StartCoroutine(SwitchToSceneMultiplayer(entranceSceneName));
|
||||
}
|
||||
|
||||
private IEnumerator SwitchToScene(Scene scene)
|
||||
private IEnumerator SwitchToSceneMultiplayer(string scene)
|
||||
{
|
||||
gameManager.LocalPlayer.FadeScreen(1, fadeDuration);
|
||||
//gameManager.LocalPlayer.FadeScreen(1, fadeDuration);
|
||||
|
||||
var operation = UnityEngine.SceneManagement.SceneManager
|
||||
.LoadSceneAsync((int)scene);
|
||||
NetworkManager.SceneManager.LoadScene(scene, LoadSceneMode.Single);
|
||||
|
||||
operation.allowSceneActivation = false;
|
||||
//var operation = UnityEngine.SceneManagement.SceneManager
|
||||
// .LoadSceneAsync((int)scene);
|
||||
|
||||
float timer = 0;
|
||||
//operation.allowSceneActivation = false;
|
||||
|
||||
while (timer <= fadeDuration && !operation.isDone)
|
||||
{
|
||||
timer += Time.deltaTime;
|
||||
//float timer = 0;
|
||||
|
||||
//while (timer <= fadeDuration && !operation.isDone)
|
||||
//{
|
||||
// timer += Time.deltaTime;
|
||||
yield return null;
|
||||
}
|
||||
//}
|
||||
|
||||
operation.allowSceneActivation = true;
|
||||
//operation.allowSceneActivation = true;
|
||||
|
||||
this.scene = scene;
|
||||
//this.scene = scene;
|
||||
|
||||
gameManager.LocalPlayer.FadeScreen(0, fadeDuration);
|
||||
//gameManager.LocalPlayer.FadeScreen(0, fadeDuration);
|
||||
}
|
||||
|
||||
//private IEnumerator SwitchToSceneSolo(Scene scene)
|
||||
//{
|
||||
// gameManager.LocalPlayer.FadeScreen(1, fadeDuration);
|
||||
|
||||
// //NetworkManager.SceneManager.LoadScene()
|
||||
|
||||
// var operation = UnityEngine.SceneManagement.SceneManager
|
||||
// .LoadSceneAsync((int)scene);
|
||||
|
||||
// operation.allowSceneActivation = false;
|
||||
|
||||
// float timer = 0;
|
||||
|
||||
// while (timer <= fadeDuration && !operation.isDone)
|
||||
// {
|
||||
// timer += Time.deltaTime;
|
||||
// yield return null;
|
||||
// }
|
||||
|
||||
// operation.allowSceneActivation = true;
|
||||
|
||||
// this.scene = scene;
|
||||
|
||||
// gameManager.LocalPlayer.FadeScreen(0, fadeDuration);
|
||||
//}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user