Skip to content

Commit f9275d7

Browse files
committed
feat: Added support for no PlayerObject
BREAKING CHANGE: This changes the connection approval delegate slightly. It also adds a new optional bool to StartHost. In addition, if using the new support for no Player Object, your game code has to be aware of it. All these changes are easy to migrate.
1 parent 7481deb commit f9275d7

File tree

7 files changed

+94
-56
lines changed

7 files changed

+94
-56
lines changed

MLAPI-Editor/NetworkingManagerEditor.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class NetworkingManagerEditor : Editor
3636
private SerializedProperty timeResyncIntervalProperty;
3737
private SerializedProperty enableNetworkedVarProperty;
3838
private SerializedProperty ensureNetworkedVarLengthSafetyProperty;
39+
private SerializedProperty createPlayerPrefabProperty;
3940
private SerializedProperty forceSamePrefabsProperty;
4041
private SerializedProperty usePrefabSyncProperty;
4142
private SerializedProperty recycleNetworkIdsProperty;
@@ -114,6 +115,7 @@ private void Init()
114115
timeResyncIntervalProperty = networkConfigProperty.FindPropertyRelative("TimeResyncInterval");
115116
enableNetworkedVarProperty = networkConfigProperty.FindPropertyRelative("EnableNetworkedVar");
116117
ensureNetworkedVarLengthSafetyProperty = networkConfigProperty.FindPropertyRelative("EnsureNetworkedVarLengthSafety");
118+
createPlayerPrefabProperty = networkConfigProperty.FindPropertyRelative("CreatePlayerPrefab");
117119
forceSamePrefabsProperty = networkConfigProperty.FindPropertyRelative("ForceSamePrefabs");
118120
usePrefabSyncProperty = networkConfigProperty.FindPropertyRelative("UsePrefabSync");
119121
recycleNetworkIdsProperty = networkConfigProperty.FindPropertyRelative("RecycleNetworkIds");
@@ -152,6 +154,7 @@ private void CheckNullProperties()
152154
timeResyncIntervalProperty = networkConfigProperty.FindPropertyRelative("TimeResyncInterval");
153155
enableNetworkedVarProperty = networkConfigProperty.FindPropertyRelative("EnableNetworkedVar");
154156
ensureNetworkedVarLengthSafetyProperty = networkConfigProperty.FindPropertyRelative("EnsureNetworkedVarLengthSafety");
157+
createPlayerPrefabProperty = networkConfigProperty.FindPropertyRelative("CreatePlayerPrefab");
155158
forceSamePrefabsProperty = networkConfigProperty.FindPropertyRelative("ForceSamePrefabs");
156159
usePrefabSyncProperty = networkConfigProperty.FindPropertyRelative("UsePrefabSync");
157160
recycleNetworkIdsProperty = networkConfigProperty.FindPropertyRelative("RecycleNetworkIds");
@@ -314,6 +317,7 @@ public override void OnInspectorGUI()
314317
EditorGUILayout.PropertyField(secondsHistoryProperty);
315318

316319
EditorGUILayout.LabelField("Spawning", EditorStyles.boldLabel);
320+
EditorGUILayout.PropertyField(createPlayerPrefabProperty);
317321
EditorGUILayout.PropertyField(forceSamePrefabsProperty);
318322
EditorGUILayout.PropertyField(usePrefabSyncProperty);
319323

MLAPI/Configuration/NetworkConfig.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ public class NetworkConfig
4848
/// The default player prefab
4949
/// </summary>
5050
[SerializeField]
51-
internal ulong PlayerPrefabHash;
51+
internal ulong? PlayerPrefabHash;
52+
/// <summary>
53+
/// Whether or not a player object should be created by default. This value can be overriden on a case by case basis with ConnectionApproval.
54+
/// </summary>
55+
[Tooltip("Whether or not a player object should be created by default. This value can be overriden on a case by case basis with ConnectionApproval.")]
56+
public bool CreatePlayerPrefab;
5257
/// <summary>
5358
/// Amount of times per second the receive queue is emptied and all messages inside are processed.
5459
/// </summary>

MLAPI/Core/NetworkingManager.cs

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -162,12 +162,12 @@ internal set
162162
/// <summary>
163163
/// Delegate type called when connection has been approved
164164
/// </summary>
165-
/// <param name="clientId">The clientId of the approved client</param>
166-
/// <param name="prefabHash">The prefabHash to use for the client</param>
165+
/// <param name="createPlayerObject">If true, a player object will be created. Otherwise the client will have no object.</param>
166+
/// <param name="playerPrefabHash">The prefabHash to use for the client. If createPlayerObject is false, this is ignored. If playerPrefabHash is null, the default player prefab is used.</param>
167167
/// <param name="approved">Whether or not the client was approved</param>
168-
/// <param name="position">The position to spawn the client at</param>
169-
/// <param name="rotation">The rotation to spawn the client with</param>
170-
public delegate void ConnectionApprovedDelegate(ulong clientId, ulong? prefabHash, bool approved, Vector3? position, Quaternion? rotation);
168+
/// <param name="position">The position to spawn the client at. If null, the prefab position is used.</param>
169+
/// <param name="rotation">The rotation to spawn the client with. If null, the prefab position is used.</param>
170+
public delegate void ConnectionApprovedDelegate(bool createPlayerObject, ulong? playerPrefabHash, bool approved, Vector3? position, Quaternion? rotation);
171171
/// <summary>
172172
/// The callback to invoke during connection approval
173173
/// </summary>
@@ -284,15 +284,31 @@ private void OnValidate()
284284
}
285285

286286
int playerPrefabCount = NetworkConfig.NetworkedPrefabs.Count(x => x.PlayerPrefab == true);
287+
287288
if (playerPrefabCount == 0)
289+
{
290+
291+
}
292+
293+
if (playerPrefabCount == 0 && !NetworkConfig.ConnectionApproval && NetworkConfig.CreatePlayerPrefab)
288294
{
289295
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("There is no NetworkedPrefab marked as a PlayerPrefab");
290296
}
291297
else if (playerPrefabCount > 1)
292298
{
293299
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Only one networked prefab can be marked as a player prefab");
294300
}
295-
else NetworkConfig.PlayerPrefabHash = NetworkConfig.NetworkedPrefabs.Find(x => x.PlayerPrefab == true).Hash;
301+
302+
NetworkedPrefab prefab = NetworkConfig.NetworkedPrefabs.FirstOrDefault(x => x.PlayerPrefab == true);
303+
304+
if (prefab == null)
305+
{
306+
NetworkConfig.PlayerPrefabHash = prefab.Hash;
307+
}
308+
else
309+
{
310+
NetworkConfig.PlayerPrefabHash = null;
311+
}
296312
}
297313

298314
private void Init(bool server)
@@ -494,7 +510,7 @@ public void StopClient()
494510
/// <summary>
495511
/// Starts a Host
496512
/// </summary>
497-
public void StartHost(Vector3? position = null, Quaternion? rotation = null, ulong? prefabHash = null, Stream payloadStream = null)
513+
public void StartHost(Vector3? position = null, Quaternion? rotation = null, bool? createPlayerObject = null, ulong? prefabHash = null, Stream payloadStream = null)
498514
{
499515
if (LogHelper.CurrentLogLevel <= LogLevel.Developer) LogHelper.LogInfo("StartHost()");
500516
if (IsServer || IsClient)
@@ -527,12 +543,15 @@ public void StartHost(Vector3? position = null, Quaternion? rotation = null, ulo
527543

528544
ConnectedClientsList.Add(ConnectedClients[hostClientId]);
529545

530-
NetworkedObject netObject = SpawnManager.CreateLocalNetworkedObject(false, 0, (prefabHash == null ? NetworkConfig.PlayerPrefabHash : prefabHash.Value), null, position, rotation);
531-
SpawnManager.SpawnNetworkedObjectLocally(netObject, SpawnManager.GetNetworkObjectId(), false, true, hostClientId, payloadStream, payloadStream != null, payloadStream == null ? 0 : (int)payloadStream.Length, false, false);
532-
533-
if (netObject.CheckObjectVisibility == null || netObject.CheckObjectVisibility(hostClientId))
546+
if ((createPlayerObject == null && NetworkConfig.CreatePlayerPrefab) || (createPlayerObject != null && createPlayerObject.Value))
534547
{
535-
netObject.observers.Add(hostClientId);
548+
NetworkedObject netObject = SpawnManager.CreateLocalNetworkedObject(false, 0, (prefabHash == null ? NetworkConfig.PlayerPrefabHash.Value : prefabHash.Value), null, position, rotation);
549+
SpawnManager.SpawnNetworkedObjectLocally(netObject, SpawnManager.GetNetworkObjectId(), false, true, hostClientId, payloadStream, payloadStream != null, payloadStream == null ? 0 : (int)payloadStream.Length, false, false);
550+
551+
if (netObject.CheckObjectVisibility == null || netObject.CheckObjectVisibility(hostClientId))
552+
{
553+
netObject.observers.Add(hostClientId);
554+
}
536555
}
537556

538557
SpawnManager.ServerSpawnSceneObjectsOnStartSweep();
@@ -1051,9 +1070,9 @@ private void SyncTime()
10511070

10521071
private readonly List<NetworkedObject> _observedObjects = new List<NetworkedObject>();
10531072

1054-
internal void HandleApproval(ulong clientId, ulong? prefabHash, bool approved, Vector3? position, Quaternion? rotation)
1073+
internal void HandleApproval(ulong clientId, bool createPlayerObject, ulong? playerPrefabHash, bool approved, Vector3? position, Quaternion? rotation)
10551074
{
1056-
if(approved)
1075+
if (approved)
10571076
{
10581077
// Inform new client it got approved
10591078
byte[] aesKey = PendingClients.ContainsKey(clientId) ? PendingClients[clientId].AesKey : null;
@@ -1072,10 +1091,14 @@ internal void HandleApproval(ulong clientId, ulong? prefabHash, bool approved, V
10721091
// This packet is unreliable, but if it gets through it should provide a much better sync than the potentially huge approval message.
10731092
SyncTime();
10741093

1075-
NetworkedObject netObject = SpawnManager.CreateLocalNetworkedObject(false, 0, (prefabHash == null ? NetworkConfig.PlayerPrefabHash : prefabHash.Value), null, position, rotation);
1076-
SpawnManager.SpawnNetworkedObjectLocally(netObject, SpawnManager.GetNetworkObjectId(), false, true, clientId, null, false, 0, false, false);
10771094

1078-
ConnectedClients[clientId].PlayerObject = netObject;
1095+
if (createPlayerObject)
1096+
{
1097+
NetworkedObject netObject = SpawnManager.CreateLocalNetworkedObject(false, 0, (playerPrefabHash == null ? NetworkConfig.PlayerPrefabHash.Value : playerPrefabHash.Value), null, position, rotation);
1098+
SpawnManager.SpawnNetworkedObjectLocally(netObject, SpawnManager.GetNetworkObjectId(), false, true, clientId, null, false, 0, false, false);
1099+
1100+
ConnectedClients[clientId].PlayerObject = netObject;
1101+
}
10791102

10801103
_observedObjects.Clear();
10811104

@@ -1178,29 +1201,29 @@ internal void HandleApproval(ulong clientId, ulong? prefabHash, bool approved, V
11781201

11791202
foreach (KeyValuePair<ulong, NetworkedClient> clientPair in ConnectedClients)
11801203
{
1181-
if (clientPair.Key == clientId || !ConnectedClients[clientId].PlayerObject.observers.Contains(clientPair.Key))
1204+
if (clientPair.Key == clientId || ConnectedClients[clientId].PlayerObject == null || !ConnectedClients[clientId].PlayerObject.observers.Contains(clientPair.Key))
11821205
continue; //The new client.
11831206

11841207
using (PooledBitStream stream = PooledBitStream.Get())
11851208
{
11861209
using (PooledBitWriter writer = PooledBitWriter.Get(stream))
11871210
{
11881211
writer.WriteBool(true);
1189-
writer.WriteUInt64Packed(ConnectedClients[clientId].PlayerObject.GetComponent<NetworkedObject>().NetworkId);
1212+
writer.WriteUInt64Packed(ConnectedClients[clientId].PlayerObject.NetworkId);
11901213
writer.WriteUInt64Packed(clientId);
11911214

1192-
//Does not have a parrent
1215+
//Does not have a parent
11931216
writer.WriteBool(false);
11941217

11951218
if (NetworkConfig.UsePrefabSync)
11961219
{
1197-
writer.WriteUInt64Packed(prefabHash == null ? NetworkConfig.PlayerPrefabHash : prefabHash.Value);
1220+
writer.WriteUInt64Packed(playerPrefabHash == null ? NetworkConfig.PlayerPrefabHash.Value : playerPrefabHash.Value);
11981221
}
11991222
else
12001223
{
12011224
// Not a softmap aka scene object
12021225
writer.WriteBool(false);
1203-
writer.WriteUInt64Packed(prefabHash == null ? NetworkConfig.PlayerPrefabHash : prefabHash.Value);
1226+
writer.WriteUInt64Packed(playerPrefabHash == null ? NetworkConfig.PlayerPrefabHash.Value : playerPrefabHash.Value);
12041227
}
12051228

12061229
if (ConnectedClients[clientId].PlayerObject.IncludeTransformWhenSpawning == null || ConnectedClients[clientId].PlayerObject.IncludeTransformWhenSpawning(clientId))

MLAPI/Messaging/InternalMessageHandler.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,14 @@ internal static void HandleConnectionRequest(ulong clientId, Stream stream)
186186
if (NetworkingManager.Singleton.NetworkConfig.ConnectionApproval)
187187
{
188188
byte[] connectionBuffer = reader.ReadByteArray();
189-
NetworkingManager.Singleton.ConnectionApprovalCallback(connectionBuffer, clientId, NetworkingManager.Singleton.HandleApproval);
189+
NetworkingManager.Singleton.ConnectionApprovalCallback(connectionBuffer, clientId, (createPlayerObject, playerPrefabHash, approved, position, rotation) =>
190+
{
191+
NetworkingManager.Singleton.HandleApproval(clientId, createPlayerObject, playerPrefabHash, approved, position, rotation);
192+
});
190193
}
191194
else
192195
{
193-
NetworkingManager.Singleton.HandleApproval(clientId, null, true, null, null);
196+
NetworkingManager.Singleton.HandleApproval(clientId, NetworkingManager.Singleton.NetworkConfig.CreatePlayerPrefab, null, true, null, null);
194197
}
195198
}
196199
}

MLAPI/Prototyping/NetworkedAnimator.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ private void FixedUpdate()
124124
List<ulong> clientsInProximity = new List<ulong>();
125125
foreach (KeyValuePair<ulong, NetworkedClient> client in NetworkingManager.Singleton.ConnectedClients)
126126
{
127-
if (Vector3.Distance(transform.position, client.Value.PlayerObject.transform.position) <= ProximityRange)
127+
if (client.Value.PlayerObject == null || Vector3.Distance(transform.position, client.Value.PlayerObject.transform.position) <= ProximityRange)
128128
clientsInProximity.Add(client.Key);
129129
}
130130
InvokeClientRpcPerformance(ApplyAnimParamMsg, clientsInProximity, stream);
@@ -196,7 +196,7 @@ private void CheckSendRate()
196196
List<ulong> clientsInProximity = new List<ulong>();
197197
foreach (KeyValuePair<ulong, NetworkedClient> client in NetworkingManager.Singleton.ConnectedClients)
198198
{
199-
if (Vector3.Distance(transform.position, client.Value.PlayerObject.transform.position) <= ProximityRange)
199+
if (client.Value.PlayerObject == null || Vector3.Distance(transform.position, client.Value.PlayerObject.transform.position) <= ProximityRange)
200200
clientsInProximity.Add(client.Key);
201201
}
202202
InvokeClientRpcPerformance(ApplyAnimParamMsg, clientsInProximity, stream);
@@ -249,7 +249,7 @@ private void SubmitAnimMsg(ulong clientId, Stream stream)
249249
List<ulong> clientsInProximity = new List<ulong>();
250250
foreach (KeyValuePair<ulong, NetworkedClient> client in NetworkingManager.Singleton.ConnectedClients)
251251
{
252-
if (Vector3.Distance(transform.position, client.Value.PlayerObject.transform.position) <= ProximityRange)
252+
if (client.Value.PlayerObject == null || Vector3.Distance(transform.position, client.Value.PlayerObject.transform.position) <= ProximityRange)
253253
clientsInProximity.Add(client.Key);
254254
}
255255
InvokeClientRpcPerformance(ApplyAnimMsg, clientsInProximity, stream);
@@ -283,7 +283,7 @@ private void SubmitAnimParamMsg(ulong clientId, Stream stream)
283283
List<ulong> clientsInProximity = new List<ulong>();
284284
foreach (KeyValuePair<ulong, NetworkedClient> client in NetworkingManager.Singleton.ConnectedClients)
285285
{
286-
if (Vector3.Distance(transform.position, client.Value.PlayerObject.transform.position) <= ProximityRange)
286+
if (client.Value.PlayerObject == null || Vector3.Distance(transform.position, client.Value.PlayerObject.transform.position) <= ProximityRange)
287287
clientsInProximity.Add(client.Key);
288288
}
289289
InvokeClientRpcPerformance(ApplyAnimParamMsg, clientsInProximity, stream);
@@ -308,7 +308,7 @@ private void SubmitAnimTriggerMsg(ulong clientId, Stream stream)
308308
List<ulong> clientsInProximity = new List<ulong>();
309309
foreach (KeyValuePair<ulong, NetworkedClient> client in NetworkingManager.Singleton.ConnectedClients)
310310
{
311-
if (Vector3.Distance(transform.position, client.Value.PlayerObject.transform.position) <= ProximityRange)
311+
if (client.Value.PlayerObject == null || Vector3.Distance(transform.position, client.Value.PlayerObject.transform.position) <= ProximityRange)
312312
clientsInProximity.Add(client.Key);
313313
}
314314
InvokeClientRpcPerformance(ApplyAnimTriggerMsg, clientsInProximity, stream);
@@ -435,7 +435,7 @@ public void SetTrigger(int hash)
435435
List<ulong> clientsInProximity = new List<ulong>();
436436
foreach (KeyValuePair<ulong, NetworkedClient> client in NetworkingManager.Singleton.ConnectedClients)
437437
{
438-
if (Vector3.Distance(transform.position, client.Value.PlayerObject.transform.position) <= ProximityRange)
438+
if (client.Value.PlayerObject == null || Vector3.Distance(transform.position, client.Value.PlayerObject.transform.position) <= ProximityRange)
439439
clientsInProximity.Add(client.Key);
440440
}
441441
InvokeClientRpcPerformance(ApplyAnimTriggerMsg, clientsInProximity, stream);

MLAPI/Prototyping/NetworkedNavMeshAgent.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ private void Update()
8080
List<ulong> proximityClients = new List<ulong>();
8181
foreach (KeyValuePair<ulong, NetworkedClient> client in NetworkingManager.Singleton.ConnectedClients)
8282
{
83-
if (Vector3.Distance(client.Value.PlayerObject.transform.position, transform.position) <= ProximityRange)
83+
if (client.Value.PlayerObject == null || Vector3.Distance(client.Value.PlayerObject.transform.position, transform.position) <= ProximityRange)
8484
proximityClients.Add(client.Key);
8585
}
8686
InvokeClientRpcPerformance(OnNavMeshStateUpdate, proximityClients, stream);
@@ -113,7 +113,7 @@ private void Update()
113113
List<ulong> proximityClients = new List<ulong>();
114114
foreach (KeyValuePair<ulong, NetworkedClient> client in NetworkingManager.Singleton.ConnectedClients)
115115
{
116-
if (Vector3.Distance(client.Value.PlayerObject.transform.position, transform.position) <= ProximityRange)
116+
if (client.Value.PlayerObject == null || Vector3.Distance(client.Value.PlayerObject.transform.position, transform.position) <= ProximityRange)
117117
proximityClients.Add(client.Key);
118118
}
119119
InvokeClientRpcPerformance(OnNavMeshCorrectionUpdate, proximityClients, stream);

0 commit comments

Comments
 (0)