Implement multiplayer scene loading
This commit is contained in:
@@ -44,4 +44,13 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 324a182340742c54cbdb3967f1916e29, type: 3}
|
m_Script: {fileID: 11500000, guid: 324a182340742c54cbdb3967f1916e29, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
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()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
StartCoroutine(AddDontDestroyToDependencies());
|
||||||
|
|
||||||
if (!isSoloRig) return;
|
if (!isSoloRig) return;
|
||||||
|
|
||||||
audioListener.enabled = true;
|
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()
|
public void DestroyDependencies()
|
||||||
{
|
{
|
||||||
foreach (var d in dependencies)
|
foreach (var d in dependencies)
|
||||||
@@ -121,7 +133,7 @@ public class PlayerComponent : NetworkBehaviour
|
|||||||
public void Toggle(bool active)
|
public void Toggle(bool active)
|
||||||
{
|
{
|
||||||
// Only toggle solo rig components, not multiplayer one
|
// Only toggle solo rig components, not multiplayer one
|
||||||
if (isSoloRig)
|
if (networkObject == null || isSoloRig)
|
||||||
{
|
{
|
||||||
foreach (var d in dependencies)
|
foreach (var d in dependencies)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,13 +9,40 @@ using Zenject;
|
|||||||
|
|
||||||
public class SceneManager : NetworkBehaviour
|
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,
|
lobbySceneName = LobbyScene?.name;
|
||||||
Entrance = 1,
|
entranceSceneName = EntranceScene?.name;
|
||||||
Forge = 2
|
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]
|
[Inject]
|
||||||
[ReadOnly]
|
[ReadOnly]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
@@ -27,35 +54,139 @@ public class SceneManager : NetworkBehaviour
|
|||||||
|
|
||||||
[ReadOnly]
|
[ReadOnly]
|
||||||
[SerializeField]
|
[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]
|
[Button]
|
||||||
public void SwitchToEntranceLevel()
|
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
|
NetworkManager.SceneManager.LoadScene(scene, LoadSceneMode.Single);
|
||||||
.LoadSceneAsync((int)scene);
|
|
||||||
|
|
||||||
operation.allowSceneActivation = false;
|
//var operation = UnityEngine.SceneManagement.SceneManager
|
||||||
|
// .LoadSceneAsync((int)scene);
|
||||||
|
|
||||||
float timer = 0;
|
//operation.allowSceneActivation = false;
|
||||||
|
|
||||||
while (timer <= fadeDuration && !operation.isDone)
|
//float timer = 0;
|
||||||
{
|
|
||||||
timer += Time.deltaTime;
|
//while (timer <= fadeDuration && !operation.isDone)
|
||||||
|
//{
|
||||||
|
// timer += Time.deltaTime;
|
||||||
yield return null;
|
yield return null;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//operation.allowSceneActivation = true;
|
||||||
|
|
||||||
|
//this.scene = scene;
|
||||||
|
|
||||||
|
//gameManager.LocalPlayer.FadeScreen(0, fadeDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
operation.allowSceneActivation = true;
|
//private IEnumerator SwitchToSceneSolo(Scene scene)
|
||||||
|
//{
|
||||||
|
// gameManager.LocalPlayer.FadeScreen(1, fadeDuration);
|
||||||
|
|
||||||
this.scene = scene;
|
// //NetworkManager.SceneManager.LoadScene()
|
||||||
|
|
||||||
gameManager.LocalPlayer.FadeScreen(0, fadeDuration);
|
// 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