207 lines
5.7 KiB
C#
207 lines
5.7 KiB
C#
using Sirenix.OdinInspector;
|
|
using System.Collections;
|
|
using Unity.Netcode;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.SceneManagement;
|
|
using Zenject;
|
|
|
|
public class SceneManager : NetworkBehaviour
|
|
{
|
|
[SerializeField]
|
|
private Level lobbyLevel;
|
|
|
|
[SerializeField]
|
|
private Level entranceLevel;
|
|
|
|
[SerializeField]
|
|
private Level forgeLevel;
|
|
|
|
public Level[] Levels => new []{ entranceLevel, forgeLevel };
|
|
|
|
[Inject]
|
|
[ReadOnly]
|
|
[SerializeField]
|
|
private GameManager gameManager;
|
|
|
|
[ReadOnly]
|
|
[SerializeField]
|
|
private float fadeDuration = 2f;
|
|
|
|
[ReadOnly]
|
|
[SerializeField]
|
|
private Scene loadedScene;
|
|
|
|
public Scene LoadedScene => loadedScene;
|
|
|
|
public bool IsInLobby => loadedScene.name == lobbyLevel.sceneName;
|
|
|
|
public UnityEvent SceneLoaded;
|
|
|
|
private bool isMultiplayer => gameManager.IsMultiplayer;
|
|
|
|
private void Awake()
|
|
{
|
|
loadedScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
|
|
}
|
|
|
|
public override void OnNetworkSpawn()
|
|
{
|
|
NetworkManager.SceneManager.OnSceneEvent += OnSceneEvent;
|
|
|
|
Debug.Log("network spawn");
|
|
|
|
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;
|
|
SceneLoaded.Invoke();
|
|
}
|
|
|
|
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 SwitchToLobbyLevel()
|
|
{
|
|
SwitchToScene(lobbyLevel.sceneName);
|
|
}
|
|
|
|
[Button]
|
|
public void SwitchToEntranceLevel()
|
|
{
|
|
SwitchToScene(entranceLevel.sceneName);
|
|
}
|
|
|
|
[Button]
|
|
public void SwitchToForgeLevel()
|
|
{
|
|
SwitchToScene(forgeLevel.sceneName);
|
|
}
|
|
|
|
private void SwitchToScene(string sceneName)
|
|
{
|
|
if (isMultiplayer)
|
|
{
|
|
StartCoroutine(SwitchToSceneMultiplayer(sceneName));
|
|
}
|
|
else
|
|
{
|
|
StartCoroutine(SwitchToSceneSolo(sceneName));
|
|
}
|
|
}
|
|
|
|
private IEnumerator SwitchToSceneMultiplayer(string scene)
|
|
{
|
|
//gameManager.LocalPlayer.FadeScreen(1, fadeDuration);
|
|
|
|
NetworkManager.SceneManager.LoadScene(scene, LoadSceneMode.Single);
|
|
|
|
//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);
|
|
}
|
|
|
|
private IEnumerator SwitchToSceneSolo(string scene)
|
|
{
|
|
gameManager.LocalPlayer.FadeScreen(1, fadeDuration);
|
|
|
|
var operation = UnityEngine.SceneManagement.SceneManager
|
|
.LoadSceneAsync(scene);
|
|
|
|
operation.allowSceneActivation = false;
|
|
|
|
float timer = 0;
|
|
|
|
while (timer <= fadeDuration && !operation.isDone)
|
|
{
|
|
timer += Time.deltaTime;
|
|
yield return null;
|
|
}
|
|
|
|
operation.allowSceneActivation = true;
|
|
|
|
gameManager.LocalPlayer.FadeScreen(0, fadeDuration);
|
|
|
|
loadedScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
|
|
}
|
|
}
|