Skip to content

Commit 0b90d02

Browse files
authored
Merge pull request #11 from TwoTenPvP/object-pooling
Object pooling Rewrite
2 parents b639927 + 92c5036 commit 0b90d02

File tree

5 files changed

+175
-3
lines changed

5 files changed

+175
-3
lines changed

MLAPI/Data/NetworkPool.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using UnityEngine;
2+
3+
namespace MLAPI.Data
4+
{
5+
internal class NetworkPool
6+
{
7+
internal int spawnablePrefabIndex;
8+
internal GameObject[] objects;
9+
internal ushort poolId;
10+
11+
internal NetworkPool(int prefabIndex, uint size, ushort poolIndex)
12+
{
13+
objects = new GameObject[size];
14+
poolId = poolIndex;
15+
for (int i = 0; i < size; i++)
16+
{
17+
GameObject go = Object.Instantiate(NetworkingManager.singleton.SpawnablePrefabs[prefabIndex], Vector3.zero, Quaternion.identity);
18+
go.GetComponent<NetworkedObject>().IsPooledObject = true;
19+
go.GetComponent<NetworkedObject>().PoolId = poolId;
20+
go.GetComponent<NetworkedObject>().Spawn();
21+
go.name = "Pool Id: " + poolId + " #" + i;
22+
go.SetActive(false);
23+
}
24+
}
25+
26+
internal GameObject SpawnObject(Vector3 position, Quaternion rotation)
27+
{
28+
for (int i = 0; i < objects.Length; i++)
29+
{
30+
if (objects[i].activeInHierarchy)
31+
{
32+
GameObject go = objects[i];
33+
go.transform.position = position;
34+
go.transform.rotation = rotation;
35+
go.SetActive(true);
36+
}
37+
}
38+
Debug.LogWarning("MLAPI: The pool " + poolId + " has ran out of space");
39+
return null;
40+
}
41+
}
42+
}

MLAPI/MLAPI.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
</Reference>
5656
</ItemGroup>
5757
<ItemGroup>
58+
<Compile Include="Data\NetworkPool.cs" />
5859
<Compile Include="Data\TrackedPointData.cs" />
5960
<Compile Include="NetworkingManagerComponents\LagCompensationManager.cs" />
6061
<Compile Include="MonoBehaviours\Core\NetworkedBehaviour.cs" />
@@ -65,6 +66,7 @@
6566
<Compile Include="MonoBehaviours\Core\TrackedObject.cs" />
6667
<Compile Include="MonoBehaviours\Prototyping\NetworkedTransform.cs" />
6768
<Compile Include="NetworkingManagerComponents\MessageManager.cs" />
69+
<Compile Include="NetworkingManagerComponents\NetworkPoolManager.cs" />
6870
<Compile Include="NetworkingManagerComponents\NetworkSceneManager.cs" />
6971
<Compile Include="NetworkingManagerComponents\SpawnManager.cs" />
7072
<Compile Include="Properties\AssemblyInfo.cs" />

MLAPI/MonoBehaviours/Core/NetworkedObject.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ public class NetworkedObject : MonoBehaviour
1414
[HideInInspector]
1515
public bool isPlayerObject = false;
1616
public bool ServerOnly = false;
17+
[HideInInspector]
18+
public bool IsPooledObject = false;
19+
[HideInInspector]
20+
public ushort PoolId;
1721
public bool isLocalPlayer
1822
{
1923
get

MLAPI/MonoBehaviours/Core/NetworkingManager.cs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using MLAPI.MonoBehaviours.Core;
2-
using MLAPI.NetworkingManagerComponents;
1+
using MLAPI.NetworkingManagerComponents;
32
using System;
43
using System.Collections;
54
using System.Collections.Generic;
@@ -72,6 +71,8 @@ private ConnectionConfig Init(NetworkingConfiguration netConfig)
7271
MessageManager.reverseMessageTypes = new Dictionary<ushort, string>();
7372
SpawnManager.spawnedObjects = new Dictionary<uint, NetworkedObject>();
7473
SpawnManager.releasedNetworkObjectIds = new Stack<uint>();
74+
NetworkPoolManager.Pools = new Dictionary<ushort, Data.NetworkPool>();
75+
NetworkPoolManager.PoolNamesToIndexes = new Dictionary<string, ushort>();
7576
NetworkSceneManager.registeredSceneNames = new HashSet<string>();
7677
NetworkSceneManager.sceneIndexToString = new Dictionary<uint, string>();
7778
NetworkSceneManager.sceneNameToIndex = new Dictionary<string, uint>();
@@ -98,6 +99,8 @@ private ConnectionConfig Init(NetworkingConfiguration netConfig)
9899
MessageManager.messageTypes.Add("MLAPI_CLIENT_DISCONNECT", 3);
99100
MessageManager.messageTypes.Add("MLAPI_DESTROY_OBJECT", 4);
100101
MessageManager.messageTypes.Add("MLAPI_SWITCH_SCENE", 5);
102+
MessageManager.messageTypes.Add("MLAPI_SPAWN_POOL_OBJECT", 6);
103+
MessageManager.messageTypes.Add("MLAPI_DESTROY_POOL_OBJECT", 7);
101104
NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromClient");
102105
NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromServer");
103106

@@ -488,13 +491,15 @@ private void HandleIncomingData(int clientId, byte[] data, int channelId)
488491
uint networkId = messageReader.ReadUInt32();
489492
int ownerId = messageReader.ReadInt32();
490493
int prefabId = messageReader.ReadInt32();
494+
bool isActive = messageReader.ReadBoolean();
491495
if(isPlayerObject)
492496
{
493497
SpawnManager.SpawnPlayerObject(ownerId, networkId);
494498
}
495499
else
496500
{
497-
SpawnManager.SpawnObject(prefabId, networkId, ownerId);
501+
GameObject go = SpawnManager.SpawnObject(prefabId, networkId, ownerId);
502+
go.SetActive(isActive);
498503
}
499504
}
500505
}
@@ -578,6 +583,40 @@ private void HandleIncomingData(int clientId, byte[] data, int channelId)
578583
}
579584
}
580585
break;
586+
case 6: //Spawn pool object
587+
if(isClient)
588+
{
589+
using (MemoryStream messageReadStream = new MemoryStream(incommingData))
590+
{
591+
using (BinaryReader messageReader = new BinaryReader(messageReadStream))
592+
{
593+
uint netId = messageReader.ReadUInt32();
594+
float xPos = messageReader.ReadSingle();
595+
float yPos = messageReader.ReadSingle();
596+
float zPos = messageReader.ReadSingle();
597+
float xRot = messageReader.ReadSingle();
598+
float yRot = messageReader.ReadSingle();
599+
float zRot = messageReader.ReadSingle();
600+
SpawnManager.spawnedObjects[netId].transform.position = new Vector3(xPos, yPos, zPos);
601+
SpawnManager.spawnedObjects[netId].transform.rotation = Quaternion.Euler(new Vector3(xRot, yRot, zRot));
602+
SpawnManager.spawnedObjects[netId].gameObject.SetActive(true);
603+
}
604+
}
605+
}
606+
break;
607+
case 7: //Destroy pool object
608+
if(isClient)
609+
{
610+
using (MemoryStream messageReadStream = new MemoryStream(incommingData))
611+
{
612+
using (BinaryReader messageReader = new BinaryReader(messageReadStream))
613+
{
614+
uint netId = messageReader.ReadUInt32();
615+
SpawnManager.spawnedObjects[netId].gameObject.SetActive(false);
616+
}
617+
}
618+
}
619+
break;
581620
}
582621
}
583622
}
@@ -943,6 +982,7 @@ private void HandleApproval(int clientId, bool approved)
943982
writer.Write(pair.Value.NetworkId);
944983
writer.Write(pair.Value.OwnerClientId);
945984
writer.Write(pair.Value.SpawnablePrefabIndex);
985+
writer.Write(pair.Value.gameObject.activeInHierarchy);
946986
}
947987
}
948988
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using MLAPI.Data;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using UnityEngine;
5+
6+
namespace MLAPI.NetworkingManagerComponents
7+
{
8+
public static class NetworkPoolManager
9+
{
10+
internal static Dictionary<ushort, NetworkPool> Pools;
11+
private static ushort PoolIndex = 0;
12+
internal static Dictionary<string, ushort> PoolNamesToIndexes;
13+
14+
//Server only
15+
public static void CreatePool(string poolName, int spawnablePrefabIndex, uint size = 16)
16+
{
17+
if(!NetworkingManager.singleton.isServer)
18+
{
19+
Debug.LogWarning("MLAPI: Pools can only be created on the server");
20+
return;
21+
}
22+
NetworkPool pool = new NetworkPool(spawnablePrefabIndex, size, PoolIndex);
23+
PoolNamesToIndexes.Add(poolName, PoolIndex);
24+
PoolIndex++;
25+
}
26+
27+
public static void DestroyPool(string poolName)
28+
{
29+
if (!NetworkingManager.singleton.isServer)
30+
{
31+
Debug.LogWarning("MLAPI: Pools can only be destroyed on the server");
32+
return;
33+
}
34+
for (int i = 0; i < Pools[PoolNamesToIndexes[poolName]].objects.Length; i++)
35+
{
36+
MonoBehaviour.Destroy(Pools[PoolNamesToIndexes[poolName]].objects[i]);
37+
}
38+
Pools.Remove(PoolNamesToIndexes[poolName]);
39+
}
40+
41+
public static GameObject SpawnPoolObject(string poolName, Vector3 position, Quaternion rotation)
42+
{
43+
if (!NetworkingManager.singleton.isServer)
44+
{
45+
Debug.LogWarning("MLAPI: Object spawning can only occur on server");
46+
return null;
47+
}
48+
GameObject go = Pools[PoolNamesToIndexes[poolName]].SpawnObject(position, rotation);
49+
using (MemoryStream stream = new MemoryStream(28))
50+
{
51+
using (BinaryWriter writer = new BinaryWriter(stream))
52+
{
53+
writer.Write(go.GetComponent<NetworkedObject>().NetworkId);
54+
writer.Write(position.x);
55+
writer.Write(position.y);
56+
writer.Write(position.z);
57+
writer.Write(rotation.eulerAngles.x);
58+
writer.Write(rotation.eulerAngles.y);
59+
writer.Write(rotation.eulerAngles.z);
60+
}
61+
NetworkingManager.singleton.Send("MLAPI_SPAWN_POOL_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer());
62+
}
63+
return go;
64+
}
65+
66+
public static void DestroyPoolObject(NetworkedObject netObject)
67+
{
68+
if (!NetworkingManager.singleton.isServer)
69+
{
70+
Debug.LogWarning("MLAPI: Objects can only be destroyed on the server");
71+
return;
72+
}
73+
netObject.gameObject.SetActive(false);
74+
using (MemoryStream stream = new MemoryStream(4))
75+
{
76+
using (BinaryWriter writer = new BinaryWriter(stream))
77+
{
78+
writer.Write(netObject.NetworkId);
79+
}
80+
NetworkingManager.singleton.Send("MLAPI_DESTROY_POOL_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer());
81+
}
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)