blob: 9a83fe063fcfddc959bab37df359e69bf9d841d1 (
plain)
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
using System.Collections;
using UnityEngine;
[DisallowMultipleComponent]
[DefaultExecutionOrder(ORDER_EXECUTION)]
public class InterpolationObjectController : MonoBehaviour
{
public const int ORDER_EXECUTION = InterpolationFactorController.ORDER_EXECUTION - 1;
private TransformData[] _transforms;
private int _index;
private void Awake()
{
StartCoroutine(WaitForEndOfFrame());
StartCoroutine(WaitForFixedUpdate());
}
private void OnEnable()
{
ResetTransforms();
}
private void BeforeFixedUpdate()
{
// Restoring actual transform for the FixedUpdate() cal where it could be change by the user.
RestoreActualTransform();
}
private void AfterFixedUpdate()
{
// Saving actual transform for being restored in the BeforeFixedUpdate() method.
SaveActualTransform();
}
private void Update()
{
// Set interpolated transform for being rendered.
SetInterpolatedTransform();
}
#region Helpers
private void RestoreActualTransform()
{
var latest = _transforms[_index];
transform.localPosition = latest.position;
transform.localScale = latest.scale;
transform.localRotation = latest.rotation;
}
private void SaveActualTransform()
{
_index = NextIndex();
_transforms[_index] = CurrentTransformData();
}
private void SetInterpolatedTransform()
{
var prev = _transforms[NextIndex()];
float factor = InterpolationFactorController.Factor;
transform.localPosition = Vector3.Lerp(prev.position, transform.localPosition, factor);
transform.localRotation = Quaternion.Slerp(prev.rotation, transform.localRotation, factor);
transform.localScale = Vector3.Lerp(prev.scale, transform.localScale, factor);
}
public void ResetTransforms()
{
_index = 0;
var td = CurrentTransformData();
_transforms = new TransformData[2] { td, td };
}
private TransformData CurrentTransformData()
{
return new TransformData(transform.localPosition, transform.localRotation, transform.localScale);
}
private int NextIndex()
{
return (_index == 0) ? 1 : 0;
}
private IEnumerator WaitForEndOfFrame()
{
while (true)
{
yield return new WaitForEndOfFrame();
BeforeFixedUpdate();
}
}
private IEnumerator WaitForFixedUpdate()
{
while (true)
{
yield return new WaitForFixedUpdate();
AfterFixedUpdate();
}
}
private struct TransformData
{
public Vector3 position;
public Quaternion rotation;
public Vector3 scale;
public TransformData(Vector3 position, Quaternion rotation, Vector3 scale)
{
this.position = position;
this.rotation = rotation;
this.scale = scale;
}
}
#endregion
}
|