142 lines
4.6 KiB
C#
142 lines
4.6 KiB
C#
using System.Collections;
|
|
using FishNet;
|
|
using FishNet.Connection;
|
|
using FishNet.Managing.Scened;
|
|
using FishNet.Object;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
|
|
public class SceneLoader : NetworkBehaviour, IPointerClickHandler
|
|
{
|
|
[SerializeField] private string sceneName;
|
|
[SerializeField] public bool SceneStack;
|
|
[SerializeField] private Vector3 spawnPosition;
|
|
|
|
private int _stackedSceneHandle;
|
|
|
|
private void Start()
|
|
{
|
|
InstanceFinder.SceneManager.OnLoadEnd += SceneManager_OnLoadEnd;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (InstanceFinder.SceneManager != null)
|
|
InstanceFinder.SceneManager.OnLoadEnd -= SceneManager_OnLoadEnd;
|
|
}
|
|
|
|
|
|
private void OnTriggerEnter(Collider other)
|
|
{
|
|
var nob = other.GetComponent<NetworkObject>();
|
|
if (nob != null && nob.IsOwner) LoadScene(nob);
|
|
}
|
|
|
|
public void OnPointerClick(PointerEventData eventData)
|
|
{
|
|
Debug.Log("Clicked scene loader");
|
|
var nob = eventData.pointerCurrentRaycast.gameObject.GetComponent<NetworkObject>();
|
|
if (nob != null) LoadScene(nob);
|
|
}
|
|
|
|
private void SceneManager_OnLoadEnd(SceneLoadEndEventArgs data)
|
|
{
|
|
if (!data.QueueData.AsServer)
|
|
return;
|
|
if (!SceneStack)
|
|
return;
|
|
if (_stackedSceneHandle != 0)
|
|
return;
|
|
|
|
if (data.LoadedScenes.Length > 0)
|
|
_stackedSceneHandle = data.LoadedScenes[0].handle;
|
|
}
|
|
|
|
|
|
private void LoadScene(NetworkObject nob)
|
|
|
|
{
|
|
Debug.Log("Loading scene");
|
|
var sceneLoadData = new SceneLoadData(SceneLookupData.CreateData(sceneName));
|
|
sceneLoadData.ReplaceScenes = ReplaceOption.None;
|
|
sceneLoadData.Options.AllowStacking = true;
|
|
|
|
var connection = nob.Owner;
|
|
|
|
InstanceFinder.SceneManager.LoadConnectionScenes(nob.Owner, sceneLoadData);
|
|
MovePlayerToSpawnPositionServerRpc(connection);
|
|
// move player to spawn position
|
|
}
|
|
|
|
[ServerRpc(RequireOwnership = false)]
|
|
private void MovePlayerToSpawnPositionServerRpc(NetworkConnection connection)
|
|
{
|
|
Debug.Log("Moving player to spawn position (SERVERRPC)");
|
|
StartCoroutine(MovePlayerToSpawnPosition(connection));
|
|
}
|
|
|
|
private IEnumerator MovePlayerToSpawnPosition(NetworkConnection connection)
|
|
{
|
|
// yield return new WaitForEndOfFrame();
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
// get players network object
|
|
var player = connection.FirstObject;
|
|
|
|
if (player != null)
|
|
{
|
|
Debug.Log("Moving player to spawn position");
|
|
player.transform.position = spawnPosition;
|
|
|
|
UpdatePlayerPositionObserversRpc(player.ObjectId, 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)
|
|
{
|
|
// var player = InstanceFinder.ClientManager.Objects.Spawned[playerObjectId];
|
|
if (InstanceFinder.ClientManager.Objects.Spawned.TryGetValue(playerObjectId, out var playerObject))
|
|
playerObject.transform.position = position;
|
|
else
|
|
Debug.LogWarning("Player not found");
|
|
}
|
|
|
|
|
|
public void UnloadScene()
|
|
{
|
|
// if (_stackedScenceHandle == 0)
|
|
// return;
|
|
|
|
// InstanceFinder.SceneManager.UnloadScene(_stackedScenceHandle);
|
|
// _stackedScenceHandle = 0;
|
|
}
|
|
} |