Skip to content

Commit 82d4498

Browse files
committed
Added SceneSwitching
1 parent 412387d commit 82d4498

File tree

3 files changed

+117
-4
lines changed

3 files changed

+117
-4
lines changed

MLAPI/Data/NetworkingConfiguration.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class NetworkingConfiguration
1313
public List<string> MessageTypes = new List<string>();
1414
public List<string> PassthroughMessageTypes = new List<string>();
1515
internal HashSet<ushort> RegisteredPassthroughMessageTypes = new HashSet<ushort>();
16+
internal List<string> RegisteredScenes = new List<string>();
1617
public int MessageBufferSize = 65535;
1718
public int MaxMessagesPerFrame = 150;
1819
public int MaxConnections = 100;
@@ -29,6 +30,7 @@ public class NetworkingConfiguration
2930
//TODO
3031
public bool EncryptMessages = false;
3132
public bool AllowPassthroughMessages = true;
33+
public bool EnableSceneSwitching = true;
3234

3335
//Cached config hash
3436
private byte[] ConfigHash = null;
@@ -47,20 +49,29 @@ public byte[] GetConfig(bool cache = true)
4749
writer.Write(pair.Key);
4850
writer.Write((int)pair.Value);
4951
}
50-
MessageTypes.Sort();
51-
PassthroughMessageTypes.Sort();
5252
for (int i = 0; i < MessageTypes.Count; i++)
5353
{
5454
writer.Write(MessageTypes[i]);
5555
}
56-
for (int i = 0; i < PassthroughMessageTypes.Count; i++)
56+
if(AllowPassthroughMessages)
5757
{
58-
writer.Write(PassthroughMessageTypes[i]);
58+
for (int i = 0; i < PassthroughMessageTypes.Count; i++)
59+
{
60+
writer.Write(PassthroughMessageTypes[i]);
61+
}
62+
}
63+
if(EnableSceneSwitching)
64+
{
65+
for (int i = 0; i < RegisteredScenes.Count; i++)
66+
{
67+
writer.Write(RegisteredScenes[i]);
68+
}
5969
}
6070
writer.Write(HandleObjectSpawning);
6171
writer.Write(CompressMessages);
6272
writer.Write(EncryptMessages);
6373
writer.Write(AllowPassthroughMessages);
74+
writer.Write(EnableSceneSwitching);
6475
}
6576
using(SHA256Managed sha256 = new SHA256Managed())
6677
{

MLAPI/MonoBehaviours/Core/NetworkingManager.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ private ConnectionConfig Init(NetworkingConfiguration netConfig)
7171
MessageManager.reverseMessageTypes = new Dictionary<ushort, string>();
7272
SpawnManager.spawnedObjects = new Dictionary<uint, NetworkedObject>();
7373
SpawnManager.releasedNetworkObjectIds = new Stack<uint>();
74+
NetworkSceneManager.registeredSceneNames = new HashSet<string>();
75+
NetworkSceneManager.sceneIndexToString = new Dictionary<uint, string>();
76+
NetworkSceneManager.sceneNameToIndex = new Dictionary<string, uint>();
7477
if (NetworkConfig.HandleObjectSpawning)
7578
{
7679
NetworkedObject[] sceneObjects = FindObjectsOfType<NetworkedObject>();
@@ -87,14 +90,24 @@ private ConnectionConfig Init(NetworkingConfiguration netConfig)
8790
//MLAPI channels and messageTypes
8891
NetworkConfig.Channels.Add("MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", QosType.ReliableFragmentedSequenced);
8992
NetworkConfig.Channels.Add("MLAPI_POSITION_UPDATE", QosType.StateUpdate);
93+
NetworkConfig.Channels.Add("MLAPI_SCENE_SWTICH", QosType.AllCostDelivery);
9094
MessageManager.messageTypes.Add("MLAPI_CONNECTION_REQUEST", 0);
9195
MessageManager.messageTypes.Add("MLAPI_CONNECTION_APPROVED", 1);
9296
MessageManager.messageTypes.Add("MLAPI_ADD_OBJECT", 2);
9397
MessageManager.messageTypes.Add("MLAPI_CLIENT_DISCONNECT", 3);
9498
MessageManager.messageTypes.Add("MLAPI_DESTROY_OBJECT", 4);
99+
MessageManager.messageTypes.Add("MLAPI_SWITCH_SCENE", 5);
95100
NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromClient");
96101
NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromServer");
97102

103+
for (int i = 0; i < NetworkConfig.RegisteredScenes.Count; i++)
104+
{
105+
NetworkSceneManager.registeredSceneNames.Add(NetworkConfig.RegisteredScenes[i]);
106+
NetworkSceneManager.sceneIndexToString.Add((uint)i, NetworkConfig.RegisteredScenes[i]);
107+
NetworkSceneManager.sceneNameToIndex.Add(NetworkConfig.RegisteredScenes[i], (uint)i);
108+
}
109+
110+
98111
HashSet<string> channelNames = new HashSet<string>();
99112
foreach (KeyValuePair<string, QosType> pair in NetworkConfig.Channels)
100113
{
@@ -549,6 +562,19 @@ private void HandleIncomingData(int clientId, byte[] data, int channelId)
549562
}
550563
}
551564
break;
565+
case 5:
566+
//Scene switch
567+
if (isClient)
568+
{
569+
using (MemoryStream messageReadStream = new MemoryStream(incommingData))
570+
{
571+
using (BinaryReader messageReader = new BinaryReader(messageReadStream))
572+
{
573+
NetworkSceneManager.OnSceneSwitch(messageReader.ReadUInt32());
574+
}
575+
}
576+
}
577+
break;
552578
}
553579
}
554580
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
using UnityEngine;
7+
using UnityEngine.SceneManagement;
8+
9+
namespace MLAPI.NetworkingManagerComponents
10+
{
11+
internal static class NetworkSceneManager
12+
{
13+
internal static HashSet<string> registeredSceneNames;
14+
internal static Dictionary<string, uint> sceneNameToIndex;
15+
internal static Dictionary<uint, string> sceneIndexToString;
16+
private static Scene lastScene;
17+
private static Scene nextScene;
18+
private static bool isSwitching = false;
19+
20+
public static void SwitchScene(string sceneName)
21+
{
22+
if (isSwitching)
23+
{
24+
Debug.LogWarning("MLAPI: Scene switch already in progress");
25+
return;
26+
}
27+
else if(!registeredSceneNames.Contains(sceneName))
28+
{
29+
Debug.LogWarning("MLAPI: The scene " + sceneName + " is not registered as a switchable scene.");
30+
return;
31+
}
32+
isSwitching = true;
33+
lastScene = SceneManager.GetActiveScene();
34+
AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
35+
sceneLoad.completed += OnSceneLoaded;
36+
using(MemoryStream stream = new MemoryStream(4))
37+
{
38+
using (BinaryWriter writer = new BinaryWriter(stream))
39+
{
40+
writer.Write(sceneNameToIndex[sceneName]);
41+
}
42+
NetworkingManager.singleton.Send("MLAPI_SWITCH_SCENE", "MLAPI_SCENE_SWTICH", stream.GetBuffer());
43+
}
44+
}
45+
46+
internal static void OnSceneSwitch(uint sceneIndex)
47+
{
48+
if(!sceneIndexToString.ContainsKey(sceneIndex) ||registeredSceneNames.Contains(sceneIndexToString[sceneIndex]))
49+
{
50+
Debug.LogWarning("MLAPI: Server requested a scene switch to a non registered scene");
51+
return;
52+
}
53+
lastScene = SceneManager.GetActiveScene();
54+
AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(sceneIndexToString[sceneIndex], LoadSceneMode.Additive);
55+
sceneLoad.completed += OnSceneLoaded;
56+
}
57+
58+
private static void OnSceneLoaded(AsyncOperation operation)
59+
{
60+
List<NetworkedObject> objectsToKeep = SpawnManager.spawnedObjects.Values.ToList();
61+
//The last loaded scene
62+
nextScene = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
63+
for (int i = 0; i < objectsToKeep.Count; i++)
64+
{
65+
SceneManager.MoveGameObjectToScene(objectsToKeep[i].gameObject, nextScene);
66+
}
67+
AsyncOperation sceneLoad = SceneManager.UnloadSceneAsync(lastScene);
68+
sceneLoad.completed += OnSceneUnload;
69+
}
70+
71+
private static void OnSceneUnload(AsyncOperation operation)
72+
{
73+
isSwitching = false;
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)