Skip to content

refactor!: remove spawn payload technical debt #1005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 2 additions & 11 deletions com.unity.multiplayer.mlapi/Runtime/Core/NetworkBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -316,21 +316,12 @@ protected NetworkBehaviour GetNetworkBehaviour(ushort behaviourId)
public ulong OwnerClientId => NetworkObject.OwnerClientId;

/// <summary>
/// Gets called when message handlers are ready to be registered and the network is setup
/// Gets called when the <see cref="MLAPI.NetworkObject"/> gets spawned, message handlers are ready to be registered and the network is setup.
/// </summary>
public virtual void OnNetworkSpawn() { }

/// <summary>
/// Gets called when the <see cref="NetworkObject"/> gets spawned, message handlers are ready to be registered and the network is setup. Provides a Payload if it was provided
/// </summary>
/// <param name="stream">The stream containing the spawn payload</param>
public virtual void OnNetworkSpawn(Stream stream)
{
OnNetworkSpawn();
}

/// <summary>
/// Gets called when the <see cref="NetworkObject"/> gets de-spawned. Is called both on the server and clients.
/// Gets called when the <see cref="MLAPI.NetworkObject"/> gets despawned. Is called both on the server and clients.
/// </summary>
public virtual void OnNetworkDespawn() { }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1415,7 +1415,7 @@ internal void HandleApproval(ulong ownerClientId, bool createPlayerObject, uint?
if (createPlayerObject)
{
var networkObject = SpawnManager.CreateLocalNetworkObject(false, playerPrefabHash ?? NetworkConfig.PlayerPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash, ownerClientId, null, position, rotation);
SpawnManager.SpawnNetworkObjectLocally(networkObject, SpawnManager.GetNetworkObjectId(), false, true, ownerClientId, null, false, 0, false, false);
SpawnManager.SpawnNetworkObjectLocally(networkObject, SpawnManager.GetNetworkObjectId(), false, true, ownerClientId, null, false, false);

ConnectedClients[ownerClientId].PlayerObject = networkObject;
}
Expand Down
60 changes: 24 additions & 36 deletions com.unity.multiplayer.mlapi/Runtime/Core/NetworkObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using MLAPI.Configuration;
using MLAPI.Exceptions;
using MLAPI.Hashing;
using MLAPI.Logging;
using MLAPI.Messaging;
using MLAPI.Serialization.Pooled;
using MLAPI.Transports;
using MLAPI.Serialization;
using UnityEngine;
Expand Down Expand Up @@ -222,11 +220,10 @@ private void Awake()
}

/// <summary>
/// Shows a previously hidden object to a client
/// Shows a previously hidden <see cref="NetworkObject"/> to a client
/// </summary>
/// <param name="clientId">The client to show the object to</param>
/// <param name="payload">An optional payload to send as part of the spawn</param>
public void NetworkShow(ulong clientId, Stream payload = null)
/// <param name="clientId">The client to show the <see cref="NetworkObject"/> to</param>
public void NetworkShow(ulong clientId)
{
if (!IsSpawned)
{
Expand All @@ -245,16 +242,15 @@ public void NetworkShow(ulong clientId, Stream payload = null)

Observers.Add(clientId);

NetworkManager.SpawnManager.SendSpawnCallForObject(clientId, OwnerClientId, this, payload);
NetworkManager.SpawnManager.SendSpawnCallForObject(clientId, OwnerClientId, this);
}

/// <summary>
/// Shows a list of previously hidden objects to a client
/// Shows a list of previously hidden <see cref="NetworkObject"/>s to a client
/// </summary>
/// <param name="networkObjects">The objects to show</param>
/// <param name="networkObjects">The <see cref="NetworkObject"/>s to show</param>
/// <param name="clientId">The client to show the objects to</param>
/// <param name="payload">An optional payload to send as part of the spawns</param>
public static void NetworkShow(List<NetworkObject> networkObjects, ulong clientId, Stream payload = null)
public static void NetworkShow(List<NetworkObject> networkObjects, ulong clientId)
{
if (networkObjects == null || networkObjects.Count == 0)
{
Expand Down Expand Up @@ -304,7 +300,7 @@ public static void NetworkShow(List<NetworkObject> networkObjects, ulong clientI
networkObjects[i].Observers.Add(clientId);

networkManager.SpawnManager.WriteSpawnCallForObject(nonNullContext.NetworkWriter, clientId,
networkObjects[i], payload);
networkObjects[i]);
}
}
}
Expand Down Expand Up @@ -429,7 +425,7 @@ private void OnDestroy()
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SpawnInternal(Stream spawnPayload, bool destroyWithScene, ulong? ownerClientId, bool playerObject)
private void SpawnInternal(bool destroyWithScene, ulong? ownerClientId, bool playerObject)
{
if (!NetworkManager.IsListening)
{
Expand All @@ -441,52 +437,44 @@ private void SpawnInternal(Stream spawnPayload, bool destroyWithScene, ulong? ow
throw new NotServerException($"Only server can spawn {nameof(NetworkObject)}s");
}

if (spawnPayload != null)
{
spawnPayload.Position = 0;
}

NetworkManager.SpawnManager.SpawnNetworkObjectLocally(this, NetworkManager.SpawnManager.GetNetworkObjectId(), false, playerObject, ownerClientId, spawnPayload, spawnPayload != null, spawnPayload == null ? 0 : (int)spawnPayload.Length, false, destroyWithScene);
NetworkManager.SpawnManager.SpawnNetworkObjectLocally(this, NetworkManager.SpawnManager.GetNetworkObjectId(), false, playerObject, ownerClientId,null, false, destroyWithScene);
ulong ownerId = ownerClientId != null ? ownerClientId.Value : NetworkManager.ServerClientId;
for (int i = 0; i < NetworkManager.ConnectedClientsList.Count; i++)
{
if (Observers.Contains(NetworkManager.ConnectedClientsList[i].ClientId))
{
NetworkManager.SpawnManager.SendSpawnCallForObject(NetworkManager.ConnectedClientsList[i].ClientId, ownerId, this, spawnPayload);
NetworkManager.SpawnManager.SendSpawnCallForObject(NetworkManager.ConnectedClientsList[i].ClientId, ownerId, this);
}
}
}

/// <summary>
/// Spawns this GameObject across the network. Can only be called from the Server
/// Spawns this <see cref="NetworkObject"/> across the network. Can only be called from the Server
/// </summary>
/// <param name="spawnPayload">The writer containing the spawn payload</param>
/// <param name="destroyWithScene">Should the object be destroyed when the scene is changed</param>
public void Spawn(Stream spawnPayload = null, bool destroyWithScene = false)
public void Spawn(bool destroyWithScene = false)
{
SpawnInternal(spawnPayload, destroyWithScene, null, false);
SpawnInternal(destroyWithScene, null, false);
}

/// <summary>
/// Spawns an object across the network with a given owner. Can only be called from server
/// Spawns a <see cref="NetworkObject"/> across the network with a given owner. Can only be called from server
/// </summary>
/// <param name="clientId">The clientId to own the object</param>
/// <param name="spawnPayload">The writer containing the spawn payload</param>
/// <param name="destroyWithScene">Should the object be destroyd when the scene is changed</param>
public void SpawnWithOwnership(ulong clientId, Stream spawnPayload = null, bool destroyWithScene = false)
/// <param name="destroyWithScene">Should the object be destroyed when the scene is changed</param>
public void SpawnWithOwnership(ulong clientId, bool destroyWithScene = false)
{
SpawnInternal(spawnPayload, destroyWithScene, clientId, false);
SpawnInternal(destroyWithScene, clientId, false);
}

/// <summary>
/// Spawns an object across the network and makes it the player object for the given client
/// Spawns a <see cref="NetworkObject"/> across the network and makes it the player object for the given client
/// </summary>
/// <param name="clientId">The clientId whos player object this is</param>
/// <param name="spawnPayload">The writer containing the spawn payload</param>
/// <param name="destroyWithScene">Should the object be destroyd when the scene is changed</param>
public void SpawnAsPlayerObject(ulong clientId, Stream spawnPayload = null, bool destroyWithScene = false)
public void SpawnAsPlayerObject(ulong clientId, bool destroyWithScene = false)
{
SpawnInternal(spawnPayload, destroyWithScene, clientId, true);
SpawnInternal(destroyWithScene, clientId, true);
}

/// <summary>
Expand Down Expand Up @@ -781,12 +769,12 @@ internal static void CheckOrphanChildren()
}
}

internal void InvokeBehaviourNetworkSpawn(Stream stream)
internal void InvokeBehaviourNetworkSpawn()
{
for (int i = 0; i < ChildNetworkBehaviours.Count; i++)
{
ChildNetworkBehaviours[i].InternalOnNetworkSpawn();
ChildNetworkBehaviours[i].OnNetworkSpawn(stream);
ChildNetworkBehaviours[i].OnNetworkSpawn();
}
}

Expand Down Expand Up @@ -1055,7 +1043,7 @@ internal static NetworkObject DeserializeSceneObject(NetworkBuffer objectStream,
}

// Spawn the NetworkObject
networkManager.SpawnManager.SpawnNetworkObjectLocally(networkObject, networkId, isSceneObject, isPlayerObject, ownerClientId, objectStream, false, 0, true, false);
networkManager.SpawnManager.SpawnNetworkObjectLocally(networkObject, networkId, isSceneObject, isPlayerObject, ownerClientId, objectStream, true, false);

return networkObject;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,9 @@ public void HandleAddObject(ulong clientId, Stream stream)

var (isReparented, latestParent) = NetworkObject.ReadNetworkParenting(reader);

var hasPayload = reader.ReadBool();
var payLoadLength = hasPayload ? reader.ReadInt32Packed() : 0;

var networkObject = NetworkManager.SpawnManager.CreateLocalNetworkObject(softSync, prefabHash, ownerClientId, parentNetworkId, pos, rot, isReparented);
networkObject.SetNetworkParenting(isReparented, latestParent);
NetworkManager.SpawnManager.SpawnNetworkObjectLocally(networkObject, networkId, softSync, isPlayerObject, ownerClientId, stream, hasPayload, payLoadLength, true, false);
NetworkManager.SpawnManager.SpawnNetworkObjectLocally(networkObject, networkId, softSync, isPlayerObject, ownerClientId, stream, true, false);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ private void OnServerLoadedScene(Guid switchSceneGuid)
{
if (!keyValuePair.Value.IsPlayerObject)
{
m_NetworkManager.SpawnManager.SpawnNetworkObjectLocally(keyValuePair.Value, m_NetworkManager.SpawnManager.GetNetworkObjectId(), true, false, null, null, false, 0, false, true);
m_NetworkManager.SpawnManager.SpawnNetworkObjectLocally(keyValuePair.Value, m_NetworkManager.SpawnManager.GetNetworkObjectId(), true, false, null, null, false, true);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ internal NetworkObject CreateLocalNetworkObject(bool isSceneObject, uint globalO
}

// Ran on both server and client
internal void SpawnNetworkObjectLocally(NetworkObject networkObject, ulong networkId, bool sceneObject, bool playerObject, ulong? ownerClientId, Stream dataStream, bool readPayload, int payloadLength, bool readNetworkVariable, bool destroyWithScene)
internal void SpawnNetworkObjectLocally(NetworkObject networkObject, ulong networkId, bool sceneObject, bool playerObject, ulong? ownerClientId, Stream dataStream, bool readNetworkVariable, bool destroyWithScene)
{
if (networkObject == null)
{
Expand Down Expand Up @@ -350,24 +350,10 @@ internal void SpawnNetworkObjectLocally(NetworkObject networkObject, ulong netwo
networkObject.SetCachedParent(networkObject.transform.parent);
networkObject.ApplyNetworkParenting();
NetworkObject.CheckOrphanChildren();

if (readPayload)
{
using (var payloadBuffer = PooledNetworkBuffer.Get())
{
payloadBuffer.CopyUnreadFrom(dataStream, payloadLength);
dataStream.Position += payloadLength;
payloadBuffer.Position = 0;
networkObject.InvokeBehaviourNetworkSpawn(payloadBuffer);
}
}
else
{
networkObject.InvokeBehaviourNetworkSpawn(null);
}
networkObject.InvokeBehaviourNetworkSpawn();
}

internal void SendSpawnCallForObject(ulong clientId, ulong ownerClientId, NetworkObject networkObject, Stream payload)
internal void SendSpawnCallForObject(ulong clientId, ulong ownerClientId, NetworkObject networkObject)
{
//Currently, if this is called and the clientId (destination) is the server's client Id, this case
//will be checked within the below Send function. To avoid unwarranted allocation of a PooledNetworkBuffer
Expand All @@ -386,12 +372,12 @@ internal void SendSpawnCallForObject(ulong clientId, ulong ownerClientId, Networ
{
using (var nonNullContext = (InternalCommandContext)context)
{
WriteSpawnCallForObject(nonNullContext.NetworkWriter, ownerClientId, networkObject, payload);
WriteSpawnCallForObject(nonNullContext.NetworkWriter, ownerClientId, networkObject);
}
}
}

internal void WriteSpawnCallForObject(PooledNetworkWriter writer, ulong clientId, NetworkObject networkObject, Stream payload)
internal void WriteSpawnCallForObject(PooledNetworkWriter writer, ulong clientId, NetworkObject networkObject)
{
writer.WriteBool(networkObject.IsPlayerObject);
writer.WriteUInt64Packed(networkObject.NetworkObjectId);
Expand Down Expand Up @@ -437,24 +423,10 @@ internal void WriteSpawnCallForObject(PooledNetworkWriter writer, ulong clientId
var (isReparented, latestParent) = networkObject.GetNetworkParenting();
NetworkObject.WriteNetworkParenting(writer, isReparented, latestParent);
}


writer.WriteBool(payload != null);

if (payload != null)
{
writer.WriteInt32Packed((int)payload.Length);
}

if (NetworkManager.NetworkConfig.EnableNetworkVariable)
{
networkObject.WriteNetworkVariableData(writer.GetStream(), clientId);
}

if (payload != null)
{
payload.CopyTo(writer.GetStream());
}
}

internal void DespawnObject(NetworkObject networkObject, bool destroyObject = false)
Expand Down Expand Up @@ -583,7 +555,7 @@ internal void ServerSpawnSceneObjectsOnStartSweep()
{
if (networkObjects[i].IsSceneObject == null)
{
SpawnNetworkObjectLocally(networkObjects[i], GetNetworkObjectId(), true, false, null, null, false, 0, false, true);
SpawnNetworkObjectLocally(networkObjects[i], GetNetworkObjectId(), true, false, null, null, false, true);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ private IEnumerator SpawnObjects()
var no = go.GetComponent<NetworkObject>();
if (!no.IsSpawned)
{
no.Spawn(null, true);
no.Spawn(true);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion testproject/Assets/Tests/Manual/Scripts/StatsDisplay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private void OnClientConnectedCallback(ulong clientId)
var networkObject = GetComponent<NetworkObject>();
if (networkObject != null)
{
networkObject.SpawnWithOwnership(clientId, null, true);
networkObject.SpawnWithOwnership(clientId, true);
}
}
}
Expand Down