277 lines
9.7 KiB
C#
277 lines
9.7 KiB
C#
using System.Collections.Generic;
|
|
using FishNet;
|
|
using FishNet.Connection;
|
|
using FishNet.Managing.Scened;
|
|
using FishNet.Object;
|
|
using Managers;
|
|
using UI;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using Utils;
|
|
|
|
public class SceneLoader : NetworkBehaviour, IPointerClickHandler
|
|
{
|
|
private static readonly Dictionary<int, string> playerScenes = new();
|
|
[SerializeField] public string sceneName;
|
|
[SerializeField] public Vector3 spawnPosition;
|
|
|
|
private int _stackedSceneHandle;
|
|
|
|
private void Awake()
|
|
{
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
InstanceFinder.SceneManager.OnLoadEnd += SceneManager_OnLoadEnd;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (InstanceFinder.SceneManager != null)
|
|
InstanceFinder.SceneManager.OnLoadEnd -= SceneManager_OnLoadEnd;
|
|
}
|
|
|
|
private void OnCollisionEnter(Collision collision)
|
|
{
|
|
GameLogger.Log("OnCollisionEnter triggered");
|
|
}
|
|
|
|
|
|
private void OnTriggerEnter2D(Collider2D other)
|
|
{
|
|
GameLogger.Log("OnTriggerEnter triggered");
|
|
if (!IsClientInitialized) return;
|
|
|
|
GameTimeManager.Instance.Pause();
|
|
LoadingScreenUIController.Instance.TriggerLoadingScreen();
|
|
|
|
GameLogger.Log("On Trigger ENTERED");
|
|
var nob = other.gameObject.GetComponent<NetworkObject>();
|
|
// GameLogger.Log("Player with clientID " + other.gameObject.GetInstanceID() + " entered trigger");
|
|
var otherConnection = other.GetComponent<NetworkObject>().Owner;
|
|
GameLogger.Log("Player with clientID " + otherConnection.ClientId + " entered trigger");
|
|
// if (nob != null) LoadScene(InstanceFinder.ClientManager.Connection.ClientId);
|
|
RequestSceneLoadServerRpc(otherConnection.ClientId);
|
|
GameTimeManager.Instance.Resume();
|
|
}
|
|
|
|
|
|
public void OnPointerClick(PointerEventData eventData)
|
|
{
|
|
/*if (!IsOwner)
|
|
{
|
|
GameLogger.Log("Not local player owner, not loading scene");
|
|
return;
|
|
}*/
|
|
|
|
GameLogger.Log("Clicked scene loader");
|
|
|
|
var clientId = InstanceFinder.ClientManager.Connection.ClientId;
|
|
GameLogger.Log("Player with clientID " + clientId + " clicked scene loader");
|
|
LoadScene(clientId);
|
|
}
|
|
|
|
[ServerRpc(RequireOwnership = false)]
|
|
public void RequestSceneLoadServerRpc(int clientId)
|
|
{
|
|
GameLogger.Log($"Received scene load request for client {clientId}");
|
|
LoadSceneForClient(clientId);
|
|
}
|
|
|
|
[Server]
|
|
private void LoadSceneForClient(int clientId)
|
|
{
|
|
GameLogger.Log($"Loading scene for client {clientId}");
|
|
|
|
var connection = InstanceFinder.ServerManager.Clients[clientId];
|
|
if (connection == null)
|
|
{
|
|
GameLogger.LogError($"No connection found for client {clientId}");
|
|
return;
|
|
}
|
|
|
|
var sceneLoadData = new SceneLoadData(SceneLookupData.CreateData(sceneName));
|
|
sceneLoadData.ReplaceScenes = ReplaceOption.All;
|
|
sceneLoadData.Options.AllowStacking = true; // Allow multiple scene instances
|
|
|
|
InstanceFinder.SceneManager.LoadConnectionScenes(connection, sceneLoadData);
|
|
|
|
// Unload the previous scene for this client
|
|
if (playerScenes.TryGetValue(clientId, out var previousScene))
|
|
InstanceFinder.SceneManager.UnloadConnectionScenes(connection, new SceneUnloadData(previousScene));
|
|
|
|
// Update the player's current scene
|
|
playerScenes[clientId] = sceneName;
|
|
|
|
// Move the player to the spawn position
|
|
var playerManager = PlayerManager.GetPlayerManager(clientId);
|
|
if (playerManager != null)
|
|
{
|
|
var player = playerManager.GetPlayerGo();
|
|
if (player != null)
|
|
{
|
|
player.transform.position = spawnPosition;
|
|
UpdatePlayerPositionObserversRpc(clientId, spawnPosition);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SceneManager_OnLoadEnd(SceneLoadEndEventArgs data)
|
|
{
|
|
if (!data.QueueData.AsServer)
|
|
return;
|
|
if (_stackedSceneHandle != 0)
|
|
return;
|
|
|
|
if (data.LoadedScenes.Length > 0)
|
|
_stackedSceneHandle = data.LoadedScenes[0].handle;
|
|
}
|
|
|
|
|
|
public override void OnStartServer()
|
|
{
|
|
GameLogger.Log("SceneLoader OnStartServer");
|
|
|
|
base.OnStartServer();
|
|
|
|
// var networkObject = GetComponent<NetworkObject>();
|
|
// if (networkObject != null) networkObject.GiveOwnership(NetworkManager.ServerManager.Clients[0]);
|
|
}
|
|
|
|
|
|
[ServerRpc(RequireOwnership = false)]
|
|
private void LoadScene(int clientId)
|
|
{
|
|
GameLogger.Log("Loading scene");
|
|
var sceneLoadData = new SceneLoadData(SceneLookupData.CreateData(sceneName));
|
|
sceneLoadData.ReplaceScenes = ReplaceOption.None;
|
|
sceneLoadData.Options.AllowStacking = false;
|
|
|
|
InstanceFinder.SceneManager.LoadConnectionScenes(InstanceFinder.ClientManager.Connection, sceneLoadData);
|
|
InstanceFinder.SceneManager.UnloadConnectionScenes(InstanceFinder.ClientManager.Connection,
|
|
new SceneUnloadData("StartMenu"));
|
|
|
|
// GameLogger.Log("Moving player to spawn position for clientId" + clientId);
|
|
// MovePlayerToSpawnPositionServerRpc(clientId);
|
|
// StartCoroutine(MovePlayerToSpawnPosition(clientId));
|
|
|
|
var player = PlayerManager.GetPlayerManager(clientId).GetPlayerGo();
|
|
var playerCamera = PlayerManager.GetPlayerManager(clientId).GetPlayerCamera();
|
|
// get players network object
|
|
if (player == null)
|
|
{
|
|
GameLogger.LogError("Player is null, can not move player to spawn position");
|
|
return;
|
|
}
|
|
|
|
GameLogger.Log("Moving player to spawn position: " + spawnPosition);
|
|
player.transform.position = spawnPosition;
|
|
|
|
playerCamera.gameObject.SetActive(true);
|
|
// if (Camera.main != null) Camera.main.gameObject.SetActive(false);
|
|
// playerCamera.gameObject.SetActive(true);
|
|
|
|
UpdatePlayerPositionObserversRpc(player.gameObject.GetInstanceID(), spawnPosition);
|
|
SetupPlayerCameraObserversRpc(clientId);
|
|
}
|
|
|
|
[ObserversRpc]
|
|
private void SetupPlayerCameraObserversRpc(int clientId)
|
|
{
|
|
GameLogger.Log("SetupPlayerCameraObserversRpc triggered for clientId: " + clientId);
|
|
var playerManager = PlayerManager.GetPlayerManager(clientId);
|
|
if (playerManager == null) return;
|
|
var playerGo = playerManager.GetPlayerGo();
|
|
if (playerGo == null) return;
|
|
|
|
var camera = playerGo.GetComponentInChildren<Camera>();
|
|
if (camera == null) return;
|
|
|
|
// enable camera only for the local player
|
|
camera.enabled = true;
|
|
Camera.main.gameObject.SetActive(false);
|
|
camera.tag = "MainCamera";
|
|
|
|
playerManager.SetupCamera();
|
|
}
|
|
|
|
// [ServerRpc(RequireOwnership = false)]
|
|
// private void MovePlayerToSpawnPositionServerRpc(int clientId)
|
|
// {
|
|
// GameLogger.Log("Preparing to move player to spawn position (SERVERRPC) for clientId " + clientId);
|
|
// StartCoroutine(MovePlayerToSpawnPosition(clientId));
|
|
// }
|
|
|
|
// private IEnumerator MovePlayerToSpawnPosition(int clientId)
|
|
// {
|
|
// // yield return new WaitForEndOfFrame();
|
|
// // wait until the scence is finished loading
|
|
// // yield return new WaitUntil(() => InstanceFinder.SceneManager
|
|
// yield return new WaitForSeconds(0.5f); // Wait a short time to ensure everything is set up
|
|
//
|
|
// var player = PlayerManager.GetPlayerManager(clientId).GetPlayerGo();
|
|
// // get players network object
|
|
//
|
|
// if (player == null)
|
|
// {
|
|
// GameLogger.LogError("Player is null, can not move player to spawn position");
|
|
// yield return null;
|
|
// }
|
|
//
|
|
// if (player != null)
|
|
// {
|
|
// GameLogger.Log("Moving player to spawn position: " + spawnPosition);
|
|
// player.transform.position = spawnPosition;
|
|
//
|
|
// UpdatePlayerPositionObserversRpc(player.gameObject.GetInstanceID(), spawnPosition);
|
|
// }
|
|
// }
|
|
|
|
// Get all scenes loaded for this connection
|
|
[ServerRpc(RequireOwnership = false)]
|
|
private void UnloadPreviousSceneServerRpc(NetworkConnection connection, string newSceneName)
|
|
{
|
|
var sceneConnections = InstanceFinder.SceneManager.SceneConnections;
|
|
|
|
foreach (var kvp in sceneConnections)
|
|
{
|
|
var scene = kvp.Key;
|
|
var connections = kvp.Value;
|
|
|
|
// Check if this scene is loaded for the current connection
|
|
if (connections.Contains(connection))
|
|
// Unload all scenes except the new one and any persistent scenes
|
|
/*if (scene.name != newSceneName && !scene.name.Equals("PersistentScene"))
|
|
{
|
|
var unloadSceneData = new SceneUnloadData(scene.name);
|
|
InstanceFinder.SceneManager.UnloadConnectionScenes(connection, unloadSceneData);
|
|
}*/
|
|
// unload scenes where no players are connected
|
|
if (scene.name != newSceneName)
|
|
{
|
|
var unloadSceneData = new SceneUnloadData(scene.name);
|
|
InstanceFinder.SceneManager.UnloadConnectionScenes(connection, unloadSceneData);
|
|
}
|
|
}
|
|
}
|
|
|
|
[ObserversRpc]
|
|
private void UpdatePlayerPositionObserversRpc(int playerObjectId, Vector3 position)
|
|
{
|
|
if (InstanceFinder.ClientManager.Objects.Spawned.TryGetValue(playerObjectId, out var playerObject))
|
|
playerObject.transform.position = position;
|
|
else
|
|
GameLogger.LogWarning("Player not found");
|
|
}
|
|
|
|
|
|
public void UnloadScene()
|
|
{
|
|
// if (_stackedScenceHandle == 0)
|
|
// return;
|
|
|
|
// InstanceFinder.SceneManager.UnloadScene(_stackedScenceHandle);
|
|
// _stackedScenceHandle = 0;
|
|
}
|
|
} |