Skip to content

Commit c3f4344

Browse files
authored
Merge pull request #172 from MidLevel/spawn-scene-rewrite
Rewrote Spawn and Scene managment
2 parents 7d5f888 + 909cc90 commit c3f4344

File tree

111 files changed

+81317
-23198
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+81317
-23198
lines changed

MLAPI-Editor/MLAPI-Editor.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
<Compile Include="NetworkedBehaviourEditor.cs" />
5959
<Compile Include="NetworkedObjectEditor.cs" />
6060
<Compile Include="NetworkingManagerEditor.cs" />
61+
<Compile Include="PostProcessScene.cs" />
6162
<Compile Include="Properties\AssemblyInfo.cs" />
6263
<Compile Include="TrackedObjectEditor.cs" />
6364
</ItemGroup>

MLAPI-Editor/NetworkedObjectEditor.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,17 @@ public override void OnInspectorGUI()
3939
}
4040
else if (networkedObject.IsSpawned)
4141
{
42-
EditorGUILayout.LabelField("PrefabName: ", networkedObject.NetworkedPrefabName, EditorStyles.label);
43-
EditorGUILayout.LabelField("PrefabHash: ", networkedObject.NetworkedPrefabHash.ToString(), EditorStyles.label);
42+
EditorGUILayout.LabelField("PrefabHashGenerator: ", networkedObject.PrefabHashGenerator, EditorStyles.label);
43+
EditorGUILayout.LabelField("PrefabHash: ", networkedObject.PrefabHash.ToString(), EditorStyles.label);
44+
EditorGUILayout.LabelField("InstanceId: ", networkedObject.NetworkedInstanceId.ToString(), EditorStyles.label);
4445
EditorGUILayout.LabelField("NetworkId: ", networkedObject.NetworkId.ToString(), EditorStyles.label);
4546
EditorGUILayout.LabelField("OwnerId: ", networkedObject.OwnerClientId.ToString(), EditorStyles.label);
4647
EditorGUILayout.LabelField("IsSpawned: ", networkedObject.IsSpawned.ToString(), EditorStyles.label);
4748
EditorGUILayout.LabelField("IsLocalPlayer: ", networkedObject.IsLocalPlayer.ToString(), EditorStyles.label);
4849
EditorGUILayout.LabelField("IsOwner: ", networkedObject.IsOwner.ToString(), EditorStyles.label);
4950
EditorGUILayout.LabelField("IsOwnedByServer: ", networkedObject.IsOwnedByServer.ToString(), EditorStyles.label);
5051
EditorGUILayout.LabelField("IsPlayerObject: ", networkedObject.IsPlayerObject.ToString(), EditorStyles.label);
52+
EditorGUILayout.LabelField("IsSceneObject: ", (networkedObject.IsSceneObject == null ? "Null" : networkedObject.IsSceneObject.Value.ToString()), EditorStyles.label);
5153

5254
if (NetworkingManager.Singleton != null && NetworkingManager.Singleton.IsServer)
5355
{

MLAPI-Editor/NetworkingManagerEditor.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,9 @@ public override void OnInspectorGUI()
130130
EditorGUILayout.Space();
131131
channelsList.DoLayoutList();
132132
EditorGUILayout.Space();
133-
if (networkingManager.NetworkConfig.EnableSceneSwitching)
134-
{
135-
registeredScenesList.DoLayoutList();
136-
EditorGUILayout.Space();
137-
}
133+
134+
registeredScenesList.DoLayoutList();
135+
EditorGUILayout.Space();
138136

139137
serializedObject.ApplyModifiedProperties();
140138
base.OnInspectorGUI();

MLAPI-Editor/PostProcessScene.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using MLAPI;
4+
using UnityEditor.Callbacks;
5+
using UnityEngine;
6+
7+
namespace UnityEditor
8+
{
9+
public class NetworkScenePostProcess : MonoBehaviour
10+
{
11+
[PostProcessScene(int.MaxValue)]
12+
public static void ProcessScene()
13+
{
14+
List<NetworkedObject> traverseSortedObjects = MonoBehaviour.FindObjectsOfType<NetworkedObject>().ToList();
15+
16+
traverseSortedObjects.Sort((x, y) =>
17+
{
18+
List<int> xSiblingIndex = x.TraversedSiblingIndex();
19+
List<int> ySiblingIndex = x.TraversedSiblingIndex();
20+
21+
while (xSiblingIndex.Count > 0 && ySiblingIndex.Count > 0)
22+
{
23+
if (xSiblingIndex[0] < ySiblingIndex[0])
24+
return -1;
25+
26+
if (xSiblingIndex[0] > ySiblingIndex[0])
27+
return 1;
28+
29+
xSiblingIndex.RemoveAt(0);
30+
ySiblingIndex.RemoveAt(0);
31+
}
32+
33+
return 0;
34+
});
35+
36+
for (ulong i = 0; i < (ulong)traverseSortedObjects.Count; i++)
37+
traverseSortedObjects[(int)i].NetworkedInstanceId = i;
38+
}
39+
}
40+
41+
internal static class PrefabHelpers
42+
{
43+
internal static List<int> TraversedSiblingIndex(this NetworkedObject networkedObject)
44+
{
45+
List<int> paths = new List<int>();
46+
47+
Transform transform = networkedObject.transform;
48+
49+
while (transform != null)
50+
{
51+
paths.Add(transform.GetSiblingIndex());
52+
transform = transform.parent;
53+
}
54+
55+
paths.Reverse();
56+
57+
return paths;
58+
}
59+
}
60+
}

MLAPI/Data/NetworkConfig.cs

Lines changed: 16 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public class NetworkConfig
6060
/// </summary>
6161
[SerializeField]
6262
[HideInInspector]
63-
internal string PlayerPrefabName;
63+
internal ulong PlayerPrefabHash;
6464
/// <summary>
6565
/// The size of the receive message buffer. This is the max message size including any MLAPI overheads.
6666
/// </summary>
@@ -111,10 +111,6 @@ public class NetworkConfig
111111
/// </summary>
112112
public int SecondsHistory = 5;
113113
/// <summary>
114-
/// Wheter or not to enable scene switching
115-
/// </summary>
116-
public bool EnableSceneSwitching = true;
117-
/// <summary>
118114
/// If your logic uses the NetworkedTime, this should probably be turned off. If however it's needed to maximize accuracy, this is recommended to be turned on
119115
/// </summary>
120116
public bool EnableTimeResync = false;
@@ -124,13 +120,14 @@ public class NetworkConfig
124120
/// </summary>
125121
public bool ForceSamePrefabs = true;
126122
/// <summary>
127-
/// Decides how many bytes to use for Rpc messaging. Leave this to 2 bytes unless you are facing hash collisions
123+
/// If true, all NetworkedObject's need to be prefabs and all scene objects will be replaced on server side which causes all serialization to be lost. Useful for multi project setups
124+
/// If false, Only non scene objects have to be prefabs. Scene objects will be matched using their PrefabInstanceId which can be precomputed globally for a scene at build time. Useful for single projects
128125
/// </summary>
129-
public HashSize RpcHashSize = HashSize.VarIntTwoBytes;
126+
public bool UsePrefabSync = false;
130127
/// <summary>
131-
/// Decides how many bytes to use for Prefab names. Leave this to 2 bytes unless you are facing hash collisions
128+
/// Decides how many bytes to use for Rpc messaging. Leave this to 2 bytes unless you are facing hash collisions
132129
/// </summary>
133-
public HashSize PrefabHashSize = HashSize.VarIntTwoBytes;
130+
public HashSize RpcHashSize = HashSize.VarIntTwoBytes;
134131
/// <summary>
135132
/// Wheter or not to enable encryption
136133
/// The amount of seconds to wait on all clients to load requested scene before the SwitchSceneProgress onComplete callback, that waits for all clients to complete loading, is called anyway.
@@ -213,13 +210,6 @@ public string ToBase64()
213210
writer.WriteString(config.RegisteredScenes[i]);
214211
}
215212

216-
writer.WriteUInt16Packed((ushort)config.NetworkedPrefabs.Count);
217-
for (int i = 0; i < config.NetworkedPrefabs.Count; i++)
218-
{
219-
writer.WriteBool(config.NetworkedPrefabs[i].playerPrefab);
220-
writer.WriteString(config.NetworkedPrefabs[i].name);
221-
}
222-
223213
writer.WriteInt32Packed(config.MessageBufferSize);
224214
writer.WriteInt32Packed(config.ReceiveTickrate);
225215
writer.WriteInt32Packed(config.MaxReceiveEventsPerTickRate);
@@ -233,10 +223,11 @@ public string ToBase64()
233223
writer.WriteInt32Packed(config.SecondsHistory);
234224
writer.WriteBool(config.EnableEncryption);
235225
writer.WriteBool(config.SignKeyExchange);
236-
writer.WriteBool(config.EnableSceneSwitching);
237226
writer.WriteInt32Packed(config.LoadSceneTimeOut);
238227
writer.WriteBool(config.EnableTimeResync);
239228
writer.WriteBits((byte)config.RpcHashSize, 3);
229+
writer.WriteBool(ForceSamePrefabs);
230+
writer.WriteBool(UsePrefabSync);
240231
stream.PadStream();
241232

242233
return Convert.ToBase64String(stream.ToArray());
@@ -248,8 +239,7 @@ public string ToBase64()
248239
/// Sets the NetworkConfig data with that from a base64 encoded version
249240
/// </summary>
250241
/// <param name="base64">The base64 encoded version</param>
251-
/// <param name="createDummyObject">Wheter or not to create dummy objects for NetworkedPrefabs</param>
252-
public void FromBase64(string base64, bool createDummyObject = false)
242+
public void FromBase64(string base64)
253243
{
254244
NetworkConfig config = this;
255245
byte[] binary = Convert.FromBase64String(base64);
@@ -280,27 +270,6 @@ public void FromBase64(string base64, bool createDummyObject = false)
280270
config.RegisteredScenes.Add(reader.ReadString().ToString());
281271
}
282272

283-
ushort networkedPrefabsCount = reader.ReadUInt16Packed();
284-
config.NetworkedPrefabs.Clear();
285-
GameObject root = createDummyObject ? new GameObject("MLAPI: Dummy prefabs") : null;
286-
for (int i = 0; i < networkedPrefabsCount; i++)
287-
{
288-
bool playerPrefab = reader.ReadBool();
289-
string prefabName = reader.ReadString().ToString();
290-
GameObject dummyPrefab = createDummyObject ? new GameObject("REPLACEME: " + prefabName + "(Dummy prefab)", typeof(NetworkedObject)) : null;
291-
if (dummyPrefab != null)
292-
{
293-
dummyPrefab.GetComponent<NetworkedObject>().NetworkedPrefabName = prefabName;
294-
dummyPrefab.transform.SetParent(root.transform); //This is just here to not ruin your hierarchy
295-
}
296-
NetworkedPrefab networkedPrefab = new NetworkedPrefab()
297-
{
298-
playerPrefab = playerPrefab,
299-
prefab = dummyPrefab
300-
};
301-
config.NetworkedPrefabs.Add(networkedPrefab);
302-
}
303-
304273
config.MessageBufferSize = reader.ReadInt32Packed();
305274
config.ReceiveTickrate = reader.ReadInt32Packed();
306275
config.MaxReceiveEventsPerTickRate = reader.ReadInt32Packed();
@@ -314,10 +283,11 @@ public void FromBase64(string base64, bool createDummyObject = false)
314283
config.SecondsHistory = reader.ReadInt32Packed();
315284
config.EnableEncryption = reader.ReadBool();
316285
config.SignKeyExchange = reader.ReadBool();
317-
config.EnableSceneSwitching = reader.ReadBool();
318286
config.LoadSceneTimeOut = reader.ReadInt32Packed();
319287
config.EnableTimeResync = reader.ReadBool();
320288
config.RpcHashSize = (HashSize)reader.ReadBits(3);
289+
config.ForceSamePrefabs = reader.ReadBool();
290+
config.UsePrefabSync = reader.ReadBool();
321291
}
322292
}
323293
}
@@ -349,29 +319,25 @@ public ulong GetConfig(bool cache = true)
349319
writer.WriteByte((byte)Channels[i].Type);
350320
}
351321

352-
if (EnableSceneSwitching)
322+
for (int i = 0; i < RegisteredScenes.Count; i++)
353323
{
354-
for (int i = 0; i < RegisteredScenes.Count; i++)
355-
{
356-
writer.WriteString(RegisteredScenes[i]);
357-
}
324+
writer.WriteString(RegisteredScenes[i]);
358325
}
359326

360327
if (ForceSamePrefabs)
361328
{
362-
List<NetworkedPrefab> sortedPrefabList = NetworkedPrefabs.OrderBy(x => x.hash).ToList();
329+
List<NetworkedPrefab> sortedPrefabList = NetworkedPrefabs.OrderBy(x => x.Hash).ToList();
363330
for (int i = 0; i < sortedPrefabList.Count; i++)
364331
{
365-
writer.WriteUInt64Packed(sortedPrefabList[i].hash);
332+
writer.WriteUInt64Packed(sortedPrefabList[i].Hash);
366333
}
367334
}
368335

369336
writer.WriteBool(ForceSamePrefabs);
337+
writer.WriteBool(UsePrefabSync);
370338
writer.WriteBool(EnableEncryption);
371-
writer.WriteBool(EnableSceneSwitching);
372339
writer.WriteBool(SignKeyExchange);
373340
writer.WriteBits((byte)RpcHashSize, 3);
374-
writer.WriteBits((byte)PrefabHashSize, 3);
375341
stream.PadStream();
376342

377343
if (cache)

MLAPI/Data/NetworkedPrefab.cs

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,48 +10,30 @@ namespace MLAPI.Data
1010
[Serializable]
1111
public class NetworkedPrefab
1212
{
13-
internal string name
13+
internal ulong Hash
1414
{
1515
get
1616
{
17-
if (prefab == null)
18-
{
19-
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("NetworkedPrefab is not assigned");
20-
return string.Empty;
21-
}
22-
else if (prefab.GetComponent<NetworkedObject>() == null)
23-
{
24-
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("The NetworkedPrefab " + prefab.name + " does not have a NetworkedObject");
25-
return prefab.name;
26-
}
27-
else return prefab.GetComponent<NetworkedObject>().NetworkedPrefabName;
28-
}
29-
}
30-
31-
internal ulong hash
32-
{
33-
get
34-
{
35-
if (prefab == null)
17+
if (Prefab == null)
3618
{
3719
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("NetworkedPrefab is not assigned");
3820
return 0;
3921
}
40-
else if (prefab.GetComponent<NetworkedObject>() == null)
22+
else if (Prefab.GetComponent<NetworkedObject>() == null)
4123
{
42-
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("The NetworkedPrefab " + prefab.name + " does not have a NetworkedObject");
24+
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("The NetworkedPrefab " + Prefab.name + " does not have a NetworkedObject");
4325
return 0;
4426
}
45-
else return prefab.GetComponent<NetworkedObject>().NetworkedPrefabHash;
27+
else return Prefab.GetComponent<NetworkedObject>().PrefabHash;
4628
}
4729
}
4830
/// <summary>
4931
/// The gameobject of the prefab
5032
/// </summary>
51-
public GameObject prefab;
33+
public GameObject Prefab;
5234
/// <summary>
5335
/// Wheter or not this is a playerPrefab
5436
/// </summary>
55-
public bool playerPrefab;
37+
public bool PlayerPrefab;
5638
}
5739
}

MLAPI/Data/SceneSwitchProgress.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using MLAPI.Data;
34
using UnityEngine;
45

56
namespace MLAPI.Components
@@ -41,7 +42,7 @@ public class SceneSwitchProgress
4142
/// The callback invoked when a client is done loading the scene.
4243
/// </summary>
4344
public event OnClientLoadedSceneDelegate OnClientLoadedScene;
44-
45+
4546
internal Guid guid { get; } = Guid.NewGuid();
4647

4748
private Coroutine timeOutCoroutine;

0 commit comments

Comments
 (0)