-
Notifications
You must be signed in to change notification settings - Fork 461
Expand file tree
/
Copy pathTrackedObject.cs
More file actions
98 lines (80 loc) · 3.7 KB
/
TrackedObject.cs
File metadata and controls
98 lines (80 loc) · 3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
using System.Collections.Generic;
using MLAPI.Collections;
using UnityEngine;
namespace MLAPI.LagCompensation
{
//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.
/// <summary>
/// A component used for lag compensation. Each object with this component will get tracked
/// </summary>
[AddComponentMenu("MLAPI/TrackedObject", -98)]
public class TrackedObject : MonoBehaviour
{
internal Dictionary<float, TrackedPointData> FrameData = new Dictionary<float, TrackedPointData>();
internal FixedQueue<float> Framekeys;
private Vector3 m_SavedPosition;
private Quaternion m_SavedRotation;
/// <summary>
/// Gets the total amount of points stored in the component
/// </summary>
public int TotalPoints => Framekeys?.Count ?? 0;
/// <summary>
/// Gets the average amount of time between the points in miliseconds
/// </summary>
public float AvgTimeBetweenPointsMs => Framekeys == null || Framekeys.Count == 0 ? 0 : ((Framekeys.ElementAt(Framekeys.Count - 1) - Framekeys.ElementAt(0)) / Framekeys.Count) * 1000f;
/// <summary>
/// Gets the total time history we have for this object
/// </summary>
public float TotalTimeHistory => Framekeys == null ? 0 : Framekeys.ElementAt(Framekeys.Count - 1) - Framekeys.ElementAt(0);
private int m_MaxPoints => (int)(NetworkManager.Singleton.NetworkConfig.SecondsHistory / (1f / NetworkManager.Singleton.NetworkConfig.EventTickrate));
internal void ReverseTransform(float secondsAgo)
{
m_SavedPosition = transform.position;
m_SavedRotation = transform.rotation;
float currentTime = NetworkManager.Singleton.NetworkTime;
float targetTime = currentTime - secondsAgo;
float previousTime = 0f;
float nextTime = 0f;
for (int i = 0; i < Framekeys.Count; i++)
{
if (previousTime <= targetTime && Framekeys.ElementAt(i) >= targetTime)
{
nextTime = Framekeys.ElementAt(i);
break;
}
previousTime = Framekeys.ElementAt(i);
}
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 = m_SavedPosition;
transform.rotation = m_SavedRotation;
}
private void Start()
{
Framekeys = new FixedQueue<float>(m_MaxPoints);
Framekeys.Enqueue(0);
LagCompensationManager.SimulationObjects.Add(this);
}
private void OnDestroy()
{
LagCompensationManager.SimulationObjects.Remove(this);
}
internal void AddFrame()
{
if (Framekeys.Count == m_MaxPoints) FrameData.Remove(Framekeys.Dequeue());
FrameData.Add(NetworkManager.Singleton.NetworkTime, new TrackedPointData()
{
Position = transform.position,
Rotation = transform.rotation
});
Framekeys.Enqueue(NetworkManager.Singleton.NetworkTime);
}
}
}