Skip to content

Commit 82bd361

Browse files
pkaminskiTwoTenPvP
authored andcommitted
fix(core): spawn objects under the correct parent. (#247)
* fix(core): spawn objects under the correct parent. * fix: Fixed object diff cases for parent sync * fix: Parenting for non scene objects * fix: Added warning when violating the spawn order * feat: Added support to disable parenting per object
1 parent 622c026 commit 82bd361

File tree

5 files changed

+277
-177
lines changed

5 files changed

+277
-177
lines changed

MLAPI/Core/NetworkedObject.cs

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.ComponentModel;
44
using System.IO;
@@ -32,7 +32,7 @@ internal void ValidateHash()
3232
{
3333
PrefabHashGenerator = gameObject.name;
3434
}
35-
35+
3636
PrefabHash = PrefabHashGenerator.GetStableHash64();
3737
}
3838

@@ -60,9 +60,9 @@ internal set
6060
_ownerClientId = value;
6161
}
6262
}
63-
63+
6464
internal ulong? _ownerClientId = null;
65-
65+
6666
/// <summary>
6767
/// InstanceId is the id that is unique to the object and scene for a scene object when UsePrefabSync is false.
6868
/// If UsePrefabSync is true or if it's used on non scene objects, this has no effect.
@@ -85,6 +85,10 @@ internal set
8585
[SerializeField]
8686
public string PrefabHashGenerator;
8787
/// <summary>
88+
/// If true, the object will always be replicated as root on clients and the parent will be ignored.
89+
/// </summary>
90+
public bool AlwaysReplicateAsRoot;
91+
/// <summary>
8892
/// Gets if this object is a player object
8993
/// </summary>
9094
[EditorBrowsable(EditorBrowsableState.Never)]
@@ -153,7 +157,7 @@ internal set
153157
/// Delegate invoked when the MLAPI needs to know if the object should be visible to a client, if null it will assume true
154158
/// </summary>
155159
public VisibilityDelegate CheckObjectVisibility = null;
156-
160+
157161
/// <summary>
158162
/// Whether or not to destroy this object if it's owner is destroyed.
159163
/// If false, the objects ownership will be given to the server.
@@ -172,7 +176,7 @@ public HashSet<ulong>.Enumerator GetObservers()
172176
{
173177
throw new SpawnStateException("Object is not spawned");
174178
}
175-
179+
176180
return observers.GetEnumerator();
177181
}
178182

@@ -187,7 +191,7 @@ public bool IsNetworkVisibleTo(ulong clientId)
187191
{
188192
throw new SpawnStateException("Object is not spawned");
189193
}
190-
194+
191195
return observers.Contains(clientId);
192196
}
193197

@@ -202,7 +206,7 @@ public void NetworkShow(ulong clientId, Stream payload = null)
202206
{
203207
throw new SpawnStateException("Object is not spawned");
204208
}
205-
209+
206210
if (!NetworkingManager.Singleton.IsServer)
207211
{
208212
throw new NotServerException("Only server can change visibility");
@@ -212,10 +216,10 @@ public void NetworkShow(ulong clientId, Stream payload = null)
212216
{
213217
throw new VisibilityChangeException("The object is already visible");
214218
}
215-
219+
216220
// Send spawn call
217221
observers.Add(clientId);
218-
222+
219223
SpawnManager.SendSpawnCallForObject(clientId, this, payload);
220224
}
221225

@@ -245,22 +249,22 @@ public static void NetworkShow(List<NetworkedObject> networkedObjects, ulong cli
245249
throw new VisibilityChangeException("NetworkedObject with NetworkId: " + networkedObjects[i].NetworkId + " is already visible");
246250
}
247251
}
248-
252+
249253
using (PooledBitStream stream = PooledBitStream.Get())
250254
{
251255
using (PooledBitWriter writer = PooledBitWriter.Get(stream))
252256
{
253257
writer.WriteUInt16Packed((ushort)networkedObjects.Count);
254258
}
255-
259+
256260
for (int i = 0; i < networkedObjects.Count; i++)
257261
{
258262
// Send spawn call
259263
networkedObjects[i].observers.Add(clientId);
260-
264+
261265
SpawnManager.WriteSpawnCallForObject(stream, clientId, networkedObjects[i], payload);
262266
}
263-
267+
264268
InternalMessageSender.Send(MLAPIConstants.MLAPI_ADD_OBJECTS, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, null);
265269
}
266270
}
@@ -275,7 +279,7 @@ public void NetworkHide(ulong clientId)
275279
{
276280
throw new SpawnStateException("Object is not spawned");
277281
}
278-
282+
279283
if (!NetworkingManager.Singleton.IsServer)
280284
{
281285
throw new NotServerException("Only server can change visibility");
@@ -290,11 +294,11 @@ public void NetworkHide(ulong clientId)
290294
{
291295
throw new VisibilityChangeException("Cannot hide an object from the server");
292296
}
293-
294-
297+
298+
295299
// Send destroy call
296300
observers.Remove(clientId);
297-
301+
298302
using (PooledBitStream stream = PooledBitStream.Get())
299303
{
300304
using (PooledBitWriter writer = PooledBitWriter.Get(stream))
@@ -305,7 +309,7 @@ public void NetworkHide(ulong clientId)
305309
}
306310
}
307311
}
308-
312+
309313
/// <summary>
310314
/// Hides a list of objects from a client
311315
/// </summary>
@@ -317,7 +321,7 @@ public static void NetworkHide(List<NetworkedObject> networkedObjects, ulong cli
317321
{
318322
throw new NotServerException("Only server can change visibility");
319323
}
320-
324+
321325
if (clientId == NetworkingManager.Singleton.ServerClientId)
322326
{
323327
throw new VisibilityChangeException("Cannot hide an object from the server");
@@ -343,20 +347,20 @@ public static void NetworkHide(List<NetworkedObject> networkedObjects, ulong cli
343347
using (PooledBitWriter writer = PooledBitWriter.Get(stream))
344348
{
345349
writer.WriteUInt16Packed((ushort)networkedObjects.Count);
346-
350+
347351
for (int i = 0; i < networkedObjects.Count; i++)
348352
{
349353
// Send destroy call
350354
networkedObjects[i].observers.Remove(clientId);
351-
355+
352356
writer.WriteUInt64Packed(networkedObjects[i].NetworkId);
353357
}
354358
}
355-
359+
356360
InternalMessageSender.Send(MLAPIConstants.MLAPI_DESTROY_OBJECTS, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, null);
357361
}
358362
}
359-
363+
360364
private void OnDestroy()
361365
{
362366
if (NetworkingManager.Singleton != null)
@@ -374,7 +378,7 @@ public void Spawn(Stream spawnPayload = null, bool destroyWithScene = false)
374378
{
375379
if (spawnPayload != null)
376380
spawnPayload.Position = 0;
377-
381+
378382
SpawnManager.SpawnNetworkedObjectLocally(this, SpawnManager.GetNetworkObjectId(), false, false, null, spawnPayload, spawnPayload != null, spawnPayload == null ? 0 : (int)spawnPayload.Length, false, destroyWithScene);
379383

380384
for (int i = 0; i < NetworkingManager.Singleton.ConnectedClientsList.Count; i++)
@@ -390,7 +394,7 @@ public void Spawn(Stream spawnPayload = null, bool destroyWithScene = false)
390394
/// Unspawns this GameObject and destroys it for other clients. This should be used if the object should be kept on the server
391395
/// </summary>
392396
public void UnSpawn()
393-
{
397+
{
394398
SpawnManager.UnSpawnObject(this);
395399
}
396400

@@ -404,7 +408,7 @@ public void SpawnWithOwnership(ulong clientId, Stream spawnPayload = null, bool
404408
{
405409
if (spawnPayload != null)
406410
spawnPayload.Position = 0;
407-
411+
408412
SpawnManager.SpawnNetworkedObjectLocally(this, SpawnManager.GetNetworkObjectId(), false, false, clientId, spawnPayload, spawnPayload != null, spawnPayload == null ? 0 : (int)spawnPayload.Length, false, destroyWithScene);
409413

410414
for (int i = 0; i < NetworkingManager.Singleton.ConnectedClientsList.Count; i++)
@@ -426,9 +430,9 @@ public void SpawnAsPlayerObject(ulong clientId, Stream spawnPayload = null, bool
426430
{
427431
if (spawnPayload != null)
428432
spawnPayload.Position = 0;
429-
433+
430434
SpawnManager.SpawnNetworkedObjectLocally(this, SpawnManager.GetNetworkObjectId(), false, true, clientId, spawnPayload, spawnPayload != null, spawnPayload == null ? 0 : (int)spawnPayload.Length, false, destroyWithScene);
431-
435+
432436
for (int i = 0; i < NetworkingManager.Singleton.ConnectedClientsList.Count; i++)
433437
{
434438
if (observers.Contains(NetworkingManager.Singleton.ConnectedClientsList[i].ClientId))
@@ -470,7 +474,7 @@ internal void InvokeBehaviourOnGainedOwnership()
470474
}
471475
}
472476

473-
internal void ResetNetworkedStartInvoked()
477+
internal void ResetNetworkedStartInvoked()
474478
{
475479
for (int i = 0; i < childNetworkedBehaviours.Count; i++)
476480
{
@@ -527,15 +531,15 @@ internal static void NetworkedBehaviourUpdate()
527531
{
528532
if (_lastProcessedObject >= SpawnManager.SpawnedObjectsList.Count)
529533
_lastProcessedObject = 0;
530-
534+
531535
// Sync all vars
532536
for (int j = 0; j < SpawnManager.SpawnedObjectsList[_lastProcessedObject].childNetworkedBehaviours.Count; j++)
533537
SpawnManager.SpawnedObjectsList[_lastProcessedObject].childNetworkedBehaviours[j].NetworkedVarUpdate();
534-
538+
535539
_lastProcessedObject++;
536540
}
537541
}
538-
542+
539543
internal void WriteNetworkedVarData(Stream stream, ulong clientId)
540544
{
541545
for (int i = 0; i < childNetworkedBehaviours.Count; i++)

0 commit comments

Comments
 (0)