Skip to content
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
42 changes: 42 additions & 0 deletions MLAPI/Data/NetworkPool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using UnityEngine;

namespace MLAPI.Data
{
internal class NetworkPool
{
internal int spawnablePrefabIndex;
internal GameObject[] objects;
internal ushort poolId;

internal NetworkPool(int prefabIndex, uint size, ushort poolIndex)
{
objects = new GameObject[size];
poolId = poolIndex;
for (int i = 0; i < size; i++)
{
GameObject go = Object.Instantiate(NetworkingManager.singleton.SpawnablePrefabs[prefabIndex], Vector3.zero, Quaternion.identity);
go.GetComponent<NetworkedObject>().IsPooledObject = true;
go.GetComponent<NetworkedObject>().PoolId = poolId;
go.GetComponent<NetworkedObject>().Spawn();
go.name = "Pool Id: " + poolId + " #" + i;
go.SetActive(false);
}
}

internal GameObject SpawnObject(Vector3 position, Quaternion rotation)
{
for (int i = 0; i < objects.Length; i++)
{
if (objects[i].activeInHierarchy)
{
GameObject go = objects[i];
go.transform.position = position;
go.transform.rotation = rotation;
go.SetActive(true);
}
}
Debug.LogWarning("MLAPI: The pool " + poolId + " has ran out of space");
return null;
}
}
}
2 changes: 2 additions & 0 deletions MLAPI/MLAPI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Data\NetworkPool.cs" />
<Compile Include="Data\TrackedPointData.cs" />
<Compile Include="NetworkingManagerComponents\LagCompensationManager.cs" />
<Compile Include="MonoBehaviours\Core\NetworkedBehaviour.cs" />
Expand All @@ -65,6 +66,7 @@
<Compile Include="MonoBehaviours\Core\TrackedObject.cs" />
<Compile Include="MonoBehaviours\Prototyping\NetworkedTransform.cs" />
<Compile Include="NetworkingManagerComponents\MessageManager.cs" />
<Compile Include="NetworkingManagerComponents\NetworkPoolManager.cs" />
<Compile Include="NetworkingManagerComponents\NetworkSceneManager.cs" />
<Compile Include="NetworkingManagerComponents\SpawnManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down
4 changes: 4 additions & 0 deletions MLAPI/MonoBehaviours/Core/NetworkedObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ public class NetworkedObject : MonoBehaviour
[HideInInspector]
public bool isPlayerObject = false;
public bool ServerOnly = false;
[HideInInspector]
public bool IsPooledObject = false;
[HideInInspector]
public ushort PoolId;
public bool isLocalPlayer
{
get
Expand Down
46 changes: 43 additions & 3 deletions MLAPI/MonoBehaviours/Core/NetworkingManager.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using MLAPI.MonoBehaviours.Core;
using MLAPI.NetworkingManagerComponents;
using MLAPI.NetworkingManagerComponents;
using System;
using System.Collections;
using System.Collections.Generic;
Expand Down Expand Up @@ -72,6 +71,8 @@ private ConnectionConfig Init(NetworkingConfiguration netConfig)
MessageManager.reverseMessageTypes = new Dictionary<ushort, string>();
SpawnManager.spawnedObjects = new Dictionary<uint, NetworkedObject>();
SpawnManager.releasedNetworkObjectIds = new Stack<uint>();
NetworkPoolManager.Pools = new Dictionary<ushort, Data.NetworkPool>();
NetworkPoolManager.PoolNamesToIndexes = new Dictionary<string, ushort>();
NetworkSceneManager.registeredSceneNames = new HashSet<string>();
NetworkSceneManager.sceneIndexToString = new Dictionary<uint, string>();
NetworkSceneManager.sceneNameToIndex = new Dictionary<string, uint>();
Expand All @@ -98,6 +99,8 @@ private ConnectionConfig Init(NetworkingConfiguration netConfig)
MessageManager.messageTypes.Add("MLAPI_CLIENT_DISCONNECT", 3);
MessageManager.messageTypes.Add("MLAPI_DESTROY_OBJECT", 4);
MessageManager.messageTypes.Add("MLAPI_SWITCH_SCENE", 5);
MessageManager.messageTypes.Add("MLAPI_SPAWN_POOL_OBJECT", 6);
MessageManager.messageTypes.Add("MLAPI_DESTROY_POOL_OBJECT", 7);
NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromClient");
NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromServer");

Expand Down Expand Up @@ -488,13 +491,15 @@ private void HandleIncomingData(int clientId, byte[] data, int channelId)
uint networkId = messageReader.ReadUInt32();
int ownerId = messageReader.ReadInt32();
int prefabId = messageReader.ReadInt32();
bool isActive = messageReader.ReadBoolean();
if(isPlayerObject)
{
SpawnManager.SpawnPlayerObject(ownerId, networkId);
}
else
{
SpawnManager.SpawnObject(prefabId, networkId, ownerId);
GameObject go = SpawnManager.SpawnObject(prefabId, networkId, ownerId);
go.SetActive(isActive);
}
}
}
Expand Down Expand Up @@ -578,6 +583,40 @@ private void HandleIncomingData(int clientId, byte[] data, int channelId)
}
}
break;
case 6: //Spawn pool object
if(isClient)
{
using (MemoryStream messageReadStream = new MemoryStream(incommingData))
{
using (BinaryReader messageReader = new BinaryReader(messageReadStream))
{
uint netId = messageReader.ReadUInt32();
float xPos = messageReader.ReadSingle();
float yPos = messageReader.ReadSingle();
float zPos = messageReader.ReadSingle();
float xRot = messageReader.ReadSingle();
float yRot = messageReader.ReadSingle();
float zRot = messageReader.ReadSingle();
SpawnManager.spawnedObjects[netId].transform.position = new Vector3(xPos, yPos, zPos);
SpawnManager.spawnedObjects[netId].transform.rotation = Quaternion.Euler(new Vector3(xRot, yRot, zRot));
SpawnManager.spawnedObjects[netId].gameObject.SetActive(true);
}
}
}
break;
case 7: //Destroy pool object
if(isClient)
{
using (MemoryStream messageReadStream = new MemoryStream(incommingData))
{
using (BinaryReader messageReader = new BinaryReader(messageReadStream))
{
uint netId = messageReader.ReadUInt32();
SpawnManager.spawnedObjects[netId].gameObject.SetActive(false);
}
}
}
break;
}
}
}
Expand Down Expand Up @@ -943,6 +982,7 @@ private void HandleApproval(int clientId, bool approved)
writer.Write(pair.Value.NetworkId);
writer.Write(pair.Value.OwnerClientId);
writer.Write(pair.Value.SpawnablePrefabIndex);
writer.Write(pair.Value.gameObject.activeInHierarchy);
}
}
}
Expand Down
84 changes: 84 additions & 0 deletions MLAPI/NetworkingManagerComponents/NetworkPoolManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using MLAPI.Data;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace MLAPI.NetworkingManagerComponents
{
public static class NetworkPoolManager
{
internal static Dictionary<ushort, NetworkPool> Pools;
private static ushort PoolIndex = 0;
internal static Dictionary<string, ushort> PoolNamesToIndexes;

//Server only
public static void CreatePool(string poolName, int spawnablePrefabIndex, uint size = 16)
{
if(!NetworkingManager.singleton.isServer)
{
Debug.LogWarning("MLAPI: Pools can only be created on the server");
return;
}
NetworkPool pool = new NetworkPool(spawnablePrefabIndex, size, PoolIndex);
PoolNamesToIndexes.Add(poolName, PoolIndex);
PoolIndex++;
}

public static void DestroyPool(string poolName)
{
if (!NetworkingManager.singleton.isServer)
{
Debug.LogWarning("MLAPI: Pools can only be destroyed on the server");
return;
}
for (int i = 0; i < Pools[PoolNamesToIndexes[poolName]].objects.Length; i++)
{
MonoBehaviour.Destroy(Pools[PoolNamesToIndexes[poolName]].objects[i]);
}
Pools.Remove(PoolNamesToIndexes[poolName]);
}

public static GameObject SpawnPoolObject(string poolName, Vector3 position, Quaternion rotation)
{
if (!NetworkingManager.singleton.isServer)
{
Debug.LogWarning("MLAPI: Object spawning can only occur on server");
return null;
}
GameObject go = Pools[PoolNamesToIndexes[poolName]].SpawnObject(position, rotation);
using (MemoryStream stream = new MemoryStream(28))
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(go.GetComponent<NetworkedObject>().NetworkId);
writer.Write(position.x);
writer.Write(position.y);
writer.Write(position.z);
writer.Write(rotation.eulerAngles.x);
writer.Write(rotation.eulerAngles.y);
writer.Write(rotation.eulerAngles.z);
}
NetworkingManager.singleton.Send("MLAPI_SPAWN_POOL_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer());
}
return go;
}

public static void DestroyPoolObject(NetworkedObject netObject)
{
if (!NetworkingManager.singleton.isServer)
{
Debug.LogWarning("MLAPI: Objects can only be destroyed on the server");
return;
}
netObject.gameObject.SetActive(false);
using (MemoryStream stream = new MemoryStream(4))
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(netObject.NetworkId);
}
NetworkingManager.singleton.Send("MLAPI_DESTROY_POOL_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer());
}
}
}
}