diff --git a/MLAPI/Data/NetworkingConfiguration.cs b/MLAPI/Data/NetworkingConfiguration.cs index 072e221..37e62a2 100644 --- a/MLAPI/Data/NetworkingConfiguration.cs +++ b/MLAPI/Data/NetworkingConfiguration.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Net; using System.Security.Cryptography; using UnityEngine.Networking; diff --git a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs index 3ea4cf7..719dd9d 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs @@ -83,12 +83,14 @@ namespace MLAPI //MLAPI channels and messageTypes NetworkConfig.Channels.Add("MLAPI_RELIABLE_FRAGMENTED", QosType.ReliableFragmented); + NetworkConfig.Channels.Add("MLAPI_POSITION_UPDATE", QosType.StateUpdate); MessageManager.messageTypes.Add("MLAPI_CONNECTION_REQUEST", 0); MessageManager.messageTypes.Add("MLAPI_CONNECTION_APPROVED", 1); MessageManager.messageTypes.Add("MLAPI_ADD_OBJECT", 2); MessageManager.messageTypes.Add("MLAPI_CLIENT_DISCONNECT", 3); MessageManager.messageTypes.Add("MLAPI_DESTROY_OBJECT", 4); - + NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromClient"); + NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromServer"); HashSet channelNames = new HashSet(); foreach (KeyValuePair pair in NetworkConfig.Channels) diff --git a/MLAPI/MonoBehaviours/Prototyping/NetworkedTransform.cs b/MLAPI/MonoBehaviours/Prototyping/NetworkedTransform.cs new file mode 100644 index 0000000..e378575 --- /dev/null +++ b/MLAPI/MonoBehaviours/Prototyping/NetworkedTransform.cs @@ -0,0 +1,143 @@ +using MLAPI; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace MLAP +{ + public class NetworkedTransform : NetworkedBehaviour + { + [Range(0, 120)] + public int SendsPerSecond = 20; + [Tooltip("This assumes that the SendsPerSecond is synced across clients")] + public bool AssumeSyncedSends = true; + [Tooltip("This requires AssumeSyncedSends to be true")] + public bool InterpolatePosition = true; + [Tooltip("The transform will snap if the distance is greater than this distance")] + public float SnapDistance = 10f; + public bool InterpolateServer = true; + public float MinMeters = 0.15f; + public float MinDegrees = 1.5f; + private float timeForLerp; + private float lerpT; + private Vector3 lerpStartPos; + private Quaternion lerpStartRot; + private Vector3 lerpEndPos; + private Quaternion lerpEndRot; + private float lastSendTime; + + private void OnValidate() + { + if (!AssumeSyncedSends && InterpolatePosition) + InterpolatePosition = false; + if (InterpolateServer && !InterpolatePosition) + InterpolateServer = false; + } + + + void Awake() + { + if (isServer) + { + RegisterMessageHandler("MLAPI_OnRecieveTransformFromClient", OnRecieveTransformFromClient); + } + if (isClient) + { + RegisterMessageHandler("MLAPI_OnRecieveTransformFromServer", OnRecieveTransformFromServer); + } + if(AssumeSyncedSends) + { + timeForLerp = 1f / SendsPerSecond; + } + } + + void Update() + { + if(isLocalPlayer) + { + if(Time.time - lastSendTime >= timeForLerp) + { + lastSendTime = Time.time; + } + } + else + { + lerpT += Time.deltaTime / timeForLerp; + transform.position = Vector3.Lerp(lerpStartPos, lerpEndPos, lerpT); + transform.rotation = Quaternion.Slerp(lerpStartRot, lerpEndRot, lerpT); + } + } + + private void OnRecieveTransformFromServer(int clientId, byte[] data) + { + if (isServer) + return; + using (MemoryStream stream = new MemoryStream(data)) + { + using (BinaryReader reader = new BinaryReader(stream)) + { + uint netId = reader.ReadUInt32(); + if (networkId != netId) + return; + float xPos = reader.ReadSingle(); + float yPos = reader.ReadSingle(); + float zPos = reader.ReadSingle(); + float xRot = reader.ReadSingle(); + float yRot = reader.ReadSingle(); + float zRot = reader.ReadSingle(); + lerpStartPos = transform.position; + lerpStartRot = transform.rotation; + lerpEndPos = new Vector3(xPos, yPos, zRot); + lerpEndRot = Quaternion.Euler(xRot, yRot, zRot); + lerpT = 0; + } + } + } + + private void OnRecieveTransformFromClient(int clientId, byte[] data) + { + using(MemoryStream readStream = new MemoryStream(data)) + { + using(BinaryReader reader = new BinaryReader(readStream)) + { + float xPos = reader.ReadSingle(); + float yPos = reader.ReadSingle(); + float zPos = reader.ReadSingle(); + float xRot = reader.ReadSingle(); + float yRot = reader.ReadSingle(); + float zRot = reader.ReadSingle(); + if (InterpolateServer) + { + lerpStartPos = transform.position; + lerpStartRot = transform.rotation; + lerpEndPos = new Vector3(xPos, yPos, zRot); + lerpEndRot = Quaternion.Euler(xRot, yRot, zRot); + lerpT = 0; + } + else + { + transform.position = new Vector3(xPos, yPos, zPos); + transform.rotation = Quaternion.Euler(new Vector3(xRot, yRot, zRot)); + } + using (MemoryStream writeStream = new MemoryStream()) + { + using(BinaryWriter writer = new BinaryWriter(writeStream)) + { + writer.Write(networkId); + writer.Write(xPos); + writer.Write(yPos); + writer.Write(zPos); + writer.Write(xRot); + writer.Write(yRot); + writer.Write(zRot); + } + SendToNonLocalClients("MLAPI_OnRecieveTransformFromServer", "MLAPI_POSITION_UPDATE", writeStream.ToArray()); + } + } + } + } + } +}