From 020847a91bc1e124e466a522788a3810ad609676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Cor=C3=A9n?= <2108U9@gmail.com> Date: Wed, 28 Mar 2018 19:40:40 +0200 Subject: [PATCH] Added NetworkedNavMeshAgent --- .../MonoBehaviours/Core/NetworkingManager.cs | 4 + .../Prototyping/NetworkedNavMeshAgent.cs | 160 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 MLAPI/MonoBehaviours/Prototyping/NetworkedNavMeshAgent.cs diff --git a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs index 6cf5638..9e048e1 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs @@ -126,6 +126,8 @@ namespace MLAPI NetworkConfig.Channels.Add("MLAPI_INTERNAL", QosType.ReliableFragmentedSequenced); NetworkConfig.Channels.Add("MLAPI_POSITION_UPDATE", QosType.StateUpdate); NetworkConfig.Channels.Add("MLAPI_ANIMATION_UPDATE", QosType.ReliableSequenced); + NetworkConfig.Channels.Add("MLAPI_NAV_AGENT_STATE", QosType.ReliableSequenced); + NetworkConfig.Channels.Add("MLAPI_NAV_AGENT_CORRECTION", QosType.StateUpdate); MessageManager.messageTypes.Add("MLAPI_CONNECTION_REQUEST", 0); MessageManager.messageTypes.Add("MLAPI_CONNECTION_APPROVED", 1); MessageManager.messageTypes.Add("MLAPI_ADD_OBJECT", 2); @@ -141,6 +143,8 @@ namespace MLAPI NetworkConfig.MessageTypes.Add("MLAPI_HandleAnimationMessage"); NetworkConfig.MessageTypes.Add("MLAPI_HandleAnimationParameterMessage"); NetworkConfig.MessageTypes.Add("MLAPI_HandleAnimationTriggerMessage"); + NetworkConfig.MessageTypes.Add("MLAPI_OnNavMeshStateUpdate"); + NetworkConfig.MessageTypes.Add("MLAPI_OnNavMeshCorrectionUpdate"); if (NetworkConfig.EnableSceneSwitching) { diff --git a/MLAPI/MonoBehaviours/Prototyping/NetworkedNavMeshAgent.cs b/MLAPI/MonoBehaviours/Prototyping/NetworkedNavMeshAgent.cs new file mode 100644 index 0000000..76c8dcd --- /dev/null +++ b/MLAPI/MonoBehaviours/Prototyping/NetworkedNavMeshAgent.cs @@ -0,0 +1,160 @@ +using System.Collections.Generic; +using System.IO; +using UnityEngine; +using UnityEngine.AI; + +namespace MLAPI.MonoBehaviours.Prototyping +{ + public class NetworkedNavMeshAgent : NetworkedBehaviour + { + private NavMeshAgent agent; + public bool EnableProximity = false; + public float ProximityRange = 50f; + public float CorrectionDelay = 3f; + + private static byte[] stateUpdateBuffer = new byte[36]; + private static byte[] correctionBuffer = new byte[24]; + + private void Awake() + { + agent = GetComponent(); + } + + public override void NetworkStart() + { + if (isClient) + { + RegisterMessageHandler("MLAPI_OnNavMeshStateUpdate", OnNavMeshStateUpdate); + RegisterMessageHandler("MLAPI_OnNavMeshCorrectionUpdate", OnNavMeshCorrectionUpdate); + } + } + + private Vector3 lastDestination = Vector3.zero; + private float lastCorrectionTime = 0f; + private void Update() + { + if (!isServer) + return; + + if(agent.destination != lastDestination) + { + lastDestination = agent.destination; + using (MemoryStream stream = new MemoryStream(stateUpdateBuffer)) + { + using (BinaryWriter writer = new BinaryWriter(stream)) + { + writer.Write(agent.destination.x); + writer.Write(agent.destination.y); + writer.Write(agent.destination.z); + + writer.Write(agent.velocity.x); + writer.Write(agent.velocity.y); + writer.Write(agent.velocity.z); + + writer.Write(transform.position.x); + writer.Write(transform.position.y); + writer.Write(transform.position.z); + } + if (!EnableProximity) + { + SendToClientsTarget("MLAPI_OnNavMeshStateUpdate", "MLAPI_NAV_AGENT_STATE", stream.GetBuffer()); + } + else + { + List proximityClients = new List(); + foreach (KeyValuePair client in NetworkingManager.singleton.connectedClients) + { + if (Vector3.Distance(client.Value.PlayerObject.transform.position, transform.position) <= ProximityRange) + proximityClients.Add(client.Key); + } + SendToClientsTarget(proximityClients, "MLAPI_OnNavMeshStateUpdate", "MLAPI_NAV_AGENT_STATE", stream.GetBuffer()); + } + } + } + + if(Time.time - lastCorrectionTime >= CorrectionDelay) + { + using (MemoryStream stream = new MemoryStream(correctionBuffer)) + { + using (BinaryWriter writer = new BinaryWriter(stream)) + { + writer.Write(agent.velocity.x); + writer.Write(agent.velocity.y); + writer.Write(agent.velocity.z); + + writer.Write(transform.position.x); + writer.Write(transform.position.y); + writer.Write(transform.position.z); + } + + if (!EnableProximity) + { + SendToClientsTarget("MLAPI_OnNavMeshCorrectionUpdate", "MLAPI_NAV_AGENT_CORRECTION", stream.GetBuffer()); + } + else + { + List proximityClients = new List(); + foreach (KeyValuePair client in NetworkingManager.singleton.connectedClients) + { + if (Vector3.Distance(client.Value.PlayerObject.transform.position, transform.position) <= ProximityRange) + proximityClients.Add(client.Key); + } + SendToClientsTarget(proximityClients, "MLAPI_OnNavMeshCorrectionUpdate", "MLAPI_NAV_AGENT_CORRECTION", stream.GetBuffer()); + } + } + } + } + + private void OnNavMeshStateUpdate(int clientId, byte[] data) + { + using (MemoryStream stream = new MemoryStream(data)) + { + using (BinaryReader reader = new BinaryReader(stream)) + { + float xDestination = reader.ReadSingle(); + float yDestination = reader.ReadSingle(); + float zDestination = reader.ReadSingle(); + + float xVel = reader.ReadSingle(); + float yVel = reader.ReadSingle(); + float zVel = reader.ReadSingle(); + + float xPos = reader.ReadSingle(); + float yPos = reader.ReadSingle(); + float zPos = reader.ReadSingle(); + + Vector3 destination = new Vector3(xDestination, yDestination, zDestination); + Vector3 velocity = new Vector3(xVel, yVel, zVel); + Vector3 position = new Vector3(xPos, yPos, zPos); + + agent.SetDestination(destination); + agent.velocity = velocity; + agent.Warp(position); + } + } + } + + private void OnNavMeshCorrectionUpdate(int clinetId, byte[] data) + { + using (MemoryStream stream = new MemoryStream(data)) + { + using (BinaryReader reader = new BinaryReader(stream)) + { + float xVel = reader.ReadSingle(); + float yVel = reader.ReadSingle(); + float zVel = reader.ReadSingle(); + + float xPos = reader.ReadSingle(); + float yPos = reader.ReadSingle(); + float zPos = reader.ReadSingle(); + + Vector3 velocity = new Vector3(xVel, yVel, zVel); + Vector3 position = new Vector3(xPos, yPos, zPos); + + agent.velocity = velocity; + agent.Warp(position); + } + } + } + } +}