Skip to content

feat!: OnNetworkSpawn / OnNetworkDespawn #865

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 14 commits into from
Jun 14, 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
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ private void Awake()
m_Transform = transform;
}

public override void NetworkStart()
public override void OnNetworkSpawn()
{
void SetupVar<T>(NetworkVariable<T> v, T initialValue, ref T oldVal)
{
Expand Down
23 changes: 15 additions & 8 deletions com.unity.multiplayer.mlapi/Runtime/Core/NetworkBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,6 @@ protected NetworkBehaviour GetNetworkBehaviour(ushort behaviourId)
/// </summary>
public ulong OwnerClientId => NetworkObject.OwnerClientId;

internal bool NetworkStartInvoked = false;
internal bool InternalNetworkStartInvoked = false;

/// <summary>
/// Stores the network tick at the NetworkBehaviourUpdate time
/// This allows sending NetworkVariables not more often than once per network tick, regardless of the update rate
Expand All @@ -307,22 +304,32 @@ protected NetworkBehaviour GetNetworkBehaviour(ushort behaviourId)
/// <summary>
/// Gets called when message handlers are ready to be registered and the network is setup
/// </summary>
public virtual void NetworkStart() { }
public virtual void OnNetworkSpawn() { }

/// <summary>
/// Gets called when message handlers are ready to be registered and the network is setup. Provides a Payload if it was provided
/// 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 NetworkStart(Stream stream)
public virtual void OnNetworkSpawn(Stream stream)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stream overload is something we probably want to remove but will be a separate RFC/ PR

{
NetworkStart();
OnNetworkSpawn();
}

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

internal void InternalOnNetworkSpawn()
{
InitializeVariables();
}

internal void InternalOnNetworkDespawn()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plan is to have this empty function filled before pre-release as we will most likely have events to unsubscribe here. That's why I pre-emptively added this function for completeness.

{

}

/// <summary>
/// Gets called when the local client gains ownership of this object
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1478,7 +1478,7 @@ internal void OnClientDisconnectFromServer(ulong clientId)
if (PrefabHandler.ContainsHandler(ConnectedClients[clientId].PlayerObject.GlobalObjectIdHash))
{
PrefabHandler.HandleNetworkPrefabDestroy(ConnectedClients[clientId].PlayerObject);
SpawnManager.OnDestroyObject(ConnectedClients[clientId].PlayerObject.NetworkObjectId, false);
SpawnManager.OnDespawnObject(ConnectedClients[clientId].PlayerObject.NetworkObjectId, false);
}
else
{
Expand All @@ -1496,7 +1496,7 @@ internal void OnClientDisconnectFromServer(ulong clientId)
if (PrefabHandler.ContainsHandler(ConnectedClients[clientId].OwnedObjects[i].GlobalObjectIdHash))
{
PrefabHandler.HandleNetworkPrefabDestroy(ConnectedClients[clientId].OwnedObjects[i]);
SpawnManager.OnDestroyObject(ConnectedClients[clientId].OwnedObjects[i].NetworkObjectId, false);
SpawnManager.OnDespawnObject(ConnectedClients[clientId].OwnedObjects[i].NetworkObjectId, false);
}
else
{
Expand Down
30 changes: 9 additions & 21 deletions com.unity.multiplayer.mlapi/Runtime/Core/NetworkObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ private void OnDestroy()
{
if (NetworkManager != null && NetworkManager.SpawnManager != null && NetworkManager.SpawnManager.SpawnedObjects.ContainsKey(NetworkObjectId))
{
NetworkManager.SpawnManager.OnDestroyObject(NetworkObjectId, false);
NetworkManager.SpawnManager.OnDespawnObject(NetworkObjectId, false);
}
}

Expand Down Expand Up @@ -504,33 +504,21 @@ internal void InvokeBehaviourOnGainedOwnership()
}
}

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

internal void InvokeBehaviourNetworkSpawn(Stream stream)
internal void InvokeBehaviourNetworkDespawn()
{
for (int i = 0; i < ChildNetworkBehaviours.Count; i++)
{
//We check if we are it's NetworkObject owner incase a NetworkObject exists as a child of our NetworkObject
if (!ChildNetworkBehaviours[i].NetworkStartInvoked)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these checks did not do anything. They were always set to false before this function was run. The conclusion seems to be that this is legacy code which is not needed.

{
if (!ChildNetworkBehaviours[i].InternalNetworkStartInvoked)
{
ChildNetworkBehaviours[i].InternalNetworkStart();
ChildNetworkBehaviours[i].InternalNetworkStartInvoked = true;
}

ChildNetworkBehaviours[i].NetworkStart(stream);
ChildNetworkBehaviours[i].NetworkStartInvoked = true;
}
ChildNetworkBehaviours[i].InternalOnNetworkDespawn();
ChildNetworkBehaviours[i].OnNetworkDespawn();
}
}

Expand Down Expand Up @@ -698,7 +686,7 @@ internal void SerializeSceneObject(NetworkWriter writer, ulong targetClientId)
// If our current buffer position is greater than our positionBeforeNetworkVariableData then we wrote NetworkVariable data
// Part 1: This will include the total NetworkVariable data size, if there was NetworkVariable data written, to the stream
// in order to be able to skip past this entry on the deserialization side in the event this NetworkObject fails to be
// constructed (See Part 2 below in the DeserializeSceneObject method)
// constructed (See Part 2 below in the DeserializeSceneObject method)
if (buffer.Position > positionBeforeNetworkVariableData)
{
// Store our current stream buffer position
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public void HandleDestroyObject(ulong clientId, Stream stream)
using (var reader = PooledNetworkReader.Get(stream))
{
ulong networkId = reader.ReadUInt64Packed();
NetworkManager.SpawnManager.OnDestroyObject(networkId, true);
NetworkManager.SpawnManager.OnDespawnObject(networkId, true);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public void ReadField(Stream stream)
/// <inheritdoc />
public void WriteField(Stream stream)
{
using (var writer = PooledNetworkWriter.Get(stream))
using (var writer = PooledNetworkWriter.Get(stream))
{
writer.WriteObjectPacked(m_InternalValue); //BOX
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,6 @@ internal void SpawnNetworkObjectLocally(NetworkObject networkObject, ulong netwo
}
}

networkObject.ResetNetworkStartInvoked();

if (readPayload)
{
using (var payloadBuffer = PooledNetworkBuffer.Get())
Expand Down Expand Up @@ -452,7 +450,7 @@ internal void DespawnObject(NetworkObject networkObject, bool destroyObject = fa
throw new NotServerException("Only server can despawn objects");
}

OnDestroyObject(networkObject.NetworkObjectId, destroyObject);
OnDespawnObject(networkObject.NetworkObjectId, destroyObject);
}

// Makes scene objects ready to be reused
Expand Down Expand Up @@ -490,7 +488,7 @@ internal void ServerDestroySpawnedSceneObjects()
if (NetworkManager.PrefabHandler != null && NetworkManager.PrefabHandler.ContainsHandler(sobj))
{
NetworkManager.PrefabHandler.HandleNetworkPrefabDestroy(sobj);
OnDestroyObject(sobj.NetworkObjectId, false);
OnDespawnObject(sobj.NetworkObjectId, false);
}
else
{
Expand All @@ -514,7 +512,7 @@ internal void DestroyNonSceneObjects()
{
NetworkManager.PrefabHandler.HandleNetworkPrefabDestroy(networkObjects[i]);

OnDestroyObject(networkObjects[i].NetworkObjectId, false);
OnDespawnObject(networkObjects[i].NetworkObjectId, false);
}
else
{
Expand All @@ -538,7 +536,7 @@ internal void DestroySceneObjects()
if (NetworkManager.PrefabHandler.ContainsHandler(networkObjects[i]))
{
NetworkManager.PrefabHandler.HandleNetworkPrefabDestroy(networkObjects[i]);
OnDestroyObject(networkObjects[i].NetworkObjectId, false);
OnDespawnObject(networkObjects[i].NetworkObjectId, false);
}
else
{
Expand Down Expand Up @@ -599,21 +597,21 @@ internal void ClientCollectSoftSyncSceneObjectSweep(NetworkObject[] networkObjec
}
}

internal void OnDestroyObject(ulong networkId, bool destroyGameObject)
internal void OnDespawnObject(ulong networkId, bool destroyGameObject)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renaming this because this is really not OnDestroy but just OnDespawn.

{
if (NetworkManager == null)
{
return;
}

//Removal of spawned object
if (!SpawnedObjects.TryGetValue(networkId, out NetworkObject sobj))
if (!SpawnedObjects.TryGetValue(networkId, out NetworkObject networkObject))
{
Debug.LogWarning($"Trying to destroy object {networkId} but it doesn't seem to exist anymore!");
return;
}

if (!sobj.IsOwnedByServer && !sobj.IsPlayerObject && NetworkManager.Singleton.ConnectedClients.TryGetValue(sobj.OwnerClientId, out NetworkClient networkClient))
if (!networkObject.IsOwnedByServer && !networkObject.IsPlayerObject && NetworkManager.Singleton.ConnectedClients.TryGetValue(networkObject.OwnerClientId, out NetworkClient networkClient))
{
//Someone owns it.
for (int i = networkClient.OwnedObjects.Count - 1; i > -1; i--)
Expand All @@ -625,7 +623,8 @@ internal void OnDestroyObject(ulong networkId, bool destroyGameObject)
}
}

sobj.IsSpawned = false;
networkObject.IsSpawned = false;
networkObject.InvokeBehaviourNetworkDespawn();

if (NetworkManager != null && NetworkManager.IsServer)
{
Expand All @@ -641,7 +640,7 @@ internal void OnDestroyObject(ulong networkId, bool destroyGameObject)
var rpcQueueContainer = NetworkManager.RpcQueueContainer;
if (rpcQueueContainer != null)
{
if (sobj != null)
if (networkObject != null)
{
// As long as we have any remaining clients, then notify of the object being destroy.
if (NetworkManager.ConnectedClientsList.Count > 0)
Expand All @@ -668,14 +667,14 @@ internal void OnDestroyObject(ulong networkId, bool destroyGameObject)
}
}

var gobj = sobj.gameObject;
var gobj = networkObject.gameObject;

if (destroyGameObject && gobj != null)
{
if (NetworkManager.PrefabHandler.ContainsHandler(sobj))
if (NetworkManager.PrefabHandler.ContainsHandler(networkObject))
{
NetworkManager.PrefabHandler.HandleNetworkPrefabDestroy(sobj);
OnDestroyObject(networkId, false);
NetworkManager.PrefabHandler.HandleNetworkPrefabDestroy(networkObject);
OnDespawnObject(networkId, false);
}
else
{
Expand All @@ -688,7 +687,7 @@ internal void OnDestroyObject(ulong networkId, bool destroyGameObject)
// of the function
if (SpawnedObjects.Remove(networkId))
{
SpawnedObjectsList.Remove(sobj);
SpawnedObjectsList.Remove(networkObject);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ public IEnumerator TestRPCs()
// Start the instances
if (!MultiInstanceHelpers.Start(true, server, clients))
{
Debug.LogError("Failed to start instances");
Assert.Fail("Failed to start instances");
}

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading