Added SceneSwitching

This commit is contained in:
Albin Corén 2018-03-04 12:40:26 +01:00
parent 412387daab
commit 82d4498461
3 changed files with 117 additions and 4 deletions

View File

@ -13,6 +13,7 @@ namespace MLAPI
public List<string> MessageTypes = new List<string>();
public List<string> PassthroughMessageTypes = new List<string>();
internal HashSet<ushort> RegisteredPassthroughMessageTypes = new HashSet<ushort>();
internal List<string> RegisteredScenes = new List<string>();
public int MessageBufferSize = 65535;
public int MaxMessagesPerFrame = 150;
public int MaxConnections = 100;
@ -29,6 +30,7 @@ namespace MLAPI
//TODO
public bool EncryptMessages = false;
public bool AllowPassthroughMessages = true;
public bool EnableSceneSwitching = true;
//Cached config hash
private byte[] ConfigHash = null;
@ -47,20 +49,29 @@ namespace MLAPI
writer.Write(pair.Key);
writer.Write((int)pair.Value);
}
MessageTypes.Sort();
PassthroughMessageTypes.Sort();
for (int i = 0; i < MessageTypes.Count; i++)
{
writer.Write(MessageTypes[i]);
}
for (int i = 0; i < PassthroughMessageTypes.Count; i++)
if(AllowPassthroughMessages)
{
writer.Write(PassthroughMessageTypes[i]);
for (int i = 0; i < PassthroughMessageTypes.Count; i++)
{
writer.Write(PassthroughMessageTypes[i]);
}
}
if(EnableSceneSwitching)
{
for (int i = 0; i < RegisteredScenes.Count; i++)
{
writer.Write(RegisteredScenes[i]);
}
}
writer.Write(HandleObjectSpawning);
writer.Write(CompressMessages);
writer.Write(EncryptMessages);
writer.Write(AllowPassthroughMessages);
writer.Write(EnableSceneSwitching);
}
using(SHA256Managed sha256 = new SHA256Managed())
{

View File

@ -71,6 +71,9 @@ namespace MLAPI
MessageManager.reverseMessageTypes = new Dictionary<ushort, string>();
SpawnManager.spawnedObjects = new Dictionary<uint, NetworkedObject>();
SpawnManager.releasedNetworkObjectIds = new Stack<uint>();
NetworkSceneManager.registeredSceneNames = new HashSet<string>();
NetworkSceneManager.sceneIndexToString = new Dictionary<uint, string>();
NetworkSceneManager.sceneNameToIndex = new Dictionary<string, uint>();
if (NetworkConfig.HandleObjectSpawning)
{
NetworkedObject[] sceneObjects = FindObjectsOfType<NetworkedObject>();
@ -87,14 +90,24 @@ namespace MLAPI
//MLAPI channels and messageTypes
NetworkConfig.Channels.Add("MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", QosType.ReliableFragmentedSequenced);
NetworkConfig.Channels.Add("MLAPI_POSITION_UPDATE", QosType.StateUpdate);
NetworkConfig.Channels.Add("MLAPI_SCENE_SWTICH", QosType.AllCostDelivery);
MessageManager.messageTypes.Add("MLAPI_CONNECTION_REQUEST", 0);
MessageManager.messageTypes.Add("MLAPI_CONNECTION_APPROVED", 1);
MessageManager.messageTypes.Add("MLAPI_ADD_OBJECT", 2);
MessageManager.messageTypes.Add("MLAPI_CLIENT_DISCONNECT", 3);
MessageManager.messageTypes.Add("MLAPI_DESTROY_OBJECT", 4);
MessageManager.messageTypes.Add("MLAPI_SWITCH_SCENE", 5);
NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromClient");
NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromServer");
for (int i = 0; i < NetworkConfig.RegisteredScenes.Count; i++)
{
NetworkSceneManager.registeredSceneNames.Add(NetworkConfig.RegisteredScenes[i]);
NetworkSceneManager.sceneIndexToString.Add((uint)i, NetworkConfig.RegisteredScenes[i]);
NetworkSceneManager.sceneNameToIndex.Add(NetworkConfig.RegisteredScenes[i], (uint)i);
}
HashSet<string> channelNames = new HashSet<string>();
foreach (KeyValuePair<string, QosType> pair in NetworkConfig.Channels)
{
@ -549,6 +562,19 @@ namespace MLAPI
}
}
break;
case 5:
//Scene switch
if (isClient)
{
using (MemoryStream messageReadStream = new MemoryStream(incommingData))
{
using (BinaryReader messageReader = new BinaryReader(messageReadStream))
{
NetworkSceneManager.OnSceneSwitch(messageReader.ReadUInt32());
}
}
}
break;
}
}
}

View File

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace MLAPI.NetworkingManagerComponents
{
internal static class NetworkSceneManager
{
internal static HashSet<string> registeredSceneNames;
internal static Dictionary<string, uint> sceneNameToIndex;
internal static Dictionary<uint, string> sceneIndexToString;
private static Scene lastScene;
private static Scene nextScene;
private static bool isSwitching = false;
public static void SwitchScene(string sceneName)
{
if (isSwitching)
{
Debug.LogWarning("MLAPI: Scene switch already in progress");
return;
}
else if(!registeredSceneNames.Contains(sceneName))
{
Debug.LogWarning("MLAPI: The scene " + sceneName + " is not registered as a switchable scene.");
return;
}
isSwitching = true;
lastScene = SceneManager.GetActiveScene();
AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
sceneLoad.completed += OnSceneLoaded;
using(MemoryStream stream = new MemoryStream(4))
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(sceneNameToIndex[sceneName]);
}
NetworkingManager.singleton.Send("MLAPI_SWITCH_SCENE", "MLAPI_SCENE_SWTICH", stream.GetBuffer());
}
}
internal static void OnSceneSwitch(uint sceneIndex)
{
if(!sceneIndexToString.ContainsKey(sceneIndex) ||registeredSceneNames.Contains(sceneIndexToString[sceneIndex]))
{
Debug.LogWarning("MLAPI: Server requested a scene switch to a non registered scene");
return;
}
lastScene = SceneManager.GetActiveScene();
AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(sceneIndexToString[sceneIndex], LoadSceneMode.Additive);
sceneLoad.completed += OnSceneLoaded;
}
private static void OnSceneLoaded(AsyncOperation operation)
{
List<NetworkedObject> objectsToKeep = SpawnManager.spawnedObjects.Values.ToList();
//The last loaded scene
nextScene = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
for (int i = 0; i < objectsToKeep.Count; i++)
{
SceneManager.MoveGameObjectToScene(objectsToKeep[i].gameObject, nextScene);
}
AsyncOperation sceneLoad = SceneManager.UnloadSceneAsync(lastScene);
sceneLoad.completed += OnSceneUnload;
}
private static void OnSceneUnload(AsyncOperation operation)
{
isSwitching = false;
}
}
}