Added lag compensation
This commit is contained in:
parent
8484ed77e1
commit
90ab0cf020
@ -23,6 +23,7 @@ namespace MLAPI
|
||||
public bool ConnectionApproval = false;
|
||||
public Action<byte[], int, Action<int, bool>> ConnectionApprovalCallback = null;
|
||||
public byte[] ConnectionData = new byte[0];
|
||||
public float SecondsHistory = 5;
|
||||
public bool HandleObjectSpawning = true;
|
||||
//TODO
|
||||
public bool CompressMessages = false;
|
||||
|
10
MLAPI/Data/TrackedPointData.cs
Normal file
10
MLAPI/Data/TrackedPointData.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace MLAPI.Data
|
||||
{
|
||||
internal struct TrackedPointData
|
||||
{
|
||||
internal Vector3 position;
|
||||
internal Quaternion rotation;
|
||||
}
|
||||
}
|
41
MLAPI/MonoBehaviours/Core/LagCompensationManager.cs
Normal file
41
MLAPI/MonoBehaviours/Core/LagCompensationManager.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace MLAPI.MonoBehaviours.Core
|
||||
{
|
||||
public static class LagCompensationManager
|
||||
{
|
||||
public static List<TrackedObject> SimulationObjects = new List<TrackedObject>();
|
||||
|
||||
public static void Simulate(float secondsAgo, Action action)
|
||||
{
|
||||
for (int i = 0; i < SimulationObjects.Count; i++)
|
||||
{
|
||||
SimulationObjects[i].ReverseTransform(secondsAgo);
|
||||
}
|
||||
|
||||
action.Invoke();
|
||||
|
||||
for (int i = 0; i < SimulationObjects.Count; i++)
|
||||
{
|
||||
SimulationObjects[i].ResetStateTransform();
|
||||
}
|
||||
}
|
||||
|
||||
private static byte error = 0;
|
||||
public static void Simulate(int clientId, Action action)
|
||||
{
|
||||
float milisecondsDelay = NetworkTransport.GetCurrentRTT(NetworkingManager.singleton.hostId, clientId, out error) / 2f;
|
||||
Simulate(milisecondsDelay * 1000f, action);
|
||||
}
|
||||
|
||||
internal static void AddFrames()
|
||||
{
|
||||
for (int i = 0; i < SimulationObjects.Count; i++)
|
||||
{
|
||||
SimulationObjects[i].AddFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using MLAPI.NetworkingManagerComponents;
|
||||
using MLAPI.MonoBehaviours.Core;
|
||||
using MLAPI.NetworkingManagerComponents;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@ -255,7 +256,7 @@ namespace MLAPI
|
||||
}
|
||||
|
||||
//Receive stuff
|
||||
int hostId;
|
||||
internal int hostId;
|
||||
int clientId;
|
||||
int channelId;
|
||||
int receivedSize;
|
||||
@ -328,6 +329,7 @@ namespace MLAPI
|
||||
(messagesProcessed < NetworkConfig.MaxMessagesPerFrame || NetworkConfig.MaxMessagesPerFrame < 0));
|
||||
|
||||
}
|
||||
LagCompensationManager.AddFrames();
|
||||
}
|
||||
|
||||
private IEnumerator ApprovalTimeout(int clientId)
|
||||
|
80
MLAPI/MonoBehaviours/Core/TrackedObject.cs
Normal file
80
MLAPI/MonoBehaviours/Core/TrackedObject.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using MLAPI.Data;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MLAPI.MonoBehaviours.Core
|
||||
{
|
||||
//Based on: https://twotenpvp.github.io/lag-compensation-in-unity.html
|
||||
//Modified to be used with latency rather than fixed frames and subframes. Thus it will be less accrurate but more modular.
|
||||
public class TrackedObject : MonoBehaviour
|
||||
{
|
||||
internal Dictionary<float, TrackedPointData> FrameData = new Dictionary<float, TrackedPointData>();
|
||||
internal List<float> Framekeys = new List<float>() { 0 };
|
||||
private Vector3 savedPosition;
|
||||
private Quaternion savedRotation;
|
||||
|
||||
internal void ReverseTransform(float secondsAgo)
|
||||
{
|
||||
savedPosition = transform.position;
|
||||
savedRotation = transform.rotation;
|
||||
float currentTime = Time.time;
|
||||
float targetTime = Time.time - secondsAgo;
|
||||
float previousTime = 0;
|
||||
float nextTime = 0;
|
||||
for (int i = 1; i < Framekeys.Count - 1; i++)
|
||||
{
|
||||
if(Framekeys[i - 1] > targetTime && Framekeys[i] <= targetTime)
|
||||
{
|
||||
previousTime = Framekeys[i];
|
||||
nextTime = Framekeys[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float timeBetweenFrames = nextTime - previousTime;
|
||||
float timeAwayFromPrevious = currentTime - previousTime;
|
||||
float lerpProgress = timeAwayFromPrevious / timeBetweenFrames;
|
||||
transform.position = Vector3.Lerp(FrameData[previousTime].position, FrameData[nextTime].position, lerpProgress);
|
||||
transform.rotation = Quaternion.Slerp(FrameData[previousTime].rotation, FrameData[nextTime].rotation, lerpProgress);
|
||||
}
|
||||
|
||||
internal void ResetStateTransform()
|
||||
{
|
||||
transform.position = savedPosition;
|
||||
transform.rotation = savedRotation;
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
LagCompensationManager.SimulationObjects.Add(this);
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
LagCompensationManager.SimulationObjects.Remove(this);
|
||||
}
|
||||
|
||||
internal void AddFrame()
|
||||
{
|
||||
float currentTime = Time.time;
|
||||
for (int i = 0; i < Framekeys.Count; i++)
|
||||
{
|
||||
if (currentTime - Framekeys[i] <= NetworkingManager.singleton.NetworkConfig.SecondsHistory)
|
||||
{
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
FrameData.Remove(Framekeys[0]);
|
||||
//This is not good for performance. Other datatypes should be concidered.
|
||||
Framekeys.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
FrameData.Add(Time.time, new TrackedPointData()
|
||||
{
|
||||
position = transform.position,
|
||||
rotation = transform.rotation
|
||||
});
|
||||
Framekeys.Add(Time.frameCount);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user