I'm trying to achieve the effect of a dog sled for a small prototype. All my attempts failed until now.
I have the following code (inspired from this)
using UnityEngine;
public class BlendFollower : MonoBehaviour
{
const int MAX_FPS = 30;
public Transform leader;
public float lagSeconds = 0.5f;
Vector3[] _positionBuffer;
Vector3[] _rotationBuffer;
float[] _timeBuffer;
int _oldestIndex;
int _newestIndex;
// Use this for initialization
void Start()
{
int bufferLength = Mathf.CeilToInt(lagSeconds * MAX_FPS);
_positionBuffer = new Vector3[bufferLength];
_rotationBuffer = new Vector3[bufferLength];
_timeBuffer = new float[bufferLength];
_positionBuffer[0] = _positionBuffer[1] = leader.position;
_rotationBuffer[0] = _rotationBuffer[1] = leader.transform.eulerAngles;
_timeBuffer[0] = _timeBuffer[1] = Time.time;
_oldestIndex = 0;
_newestIndex = 1;
}
void LateUpdate()
{
// Insert newest position into our cache.
// If the cache is full, overwrite the latest sample.
int newIndex = (_newestIndex + 1) % _positionBuffer.Length;
if (newIndex != _oldestIndex)
_newestIndex = newIndex;
_positionBuffer[_newestIndex] = leader.position;
_rotationBuffer[_newestIndex] = leader.transform.eulerAngles;
_timeBuffer[_newestIndex] = Time.time;
// Skip ahead in the buffer to the segment containing our target time.
float targetTime = Time.time - lagSeconds;
int nextIndex;
while (_timeBuffer[nextIndex = (_oldestIndex + 1) % _timeBuffer.Length] < targetTime)
_oldestIndex = nextIndex;
// Interpolate between the two samples on either side of our target time.
float span = _timeBuffer[nextIndex] - _timeBuffer[_oldestIndex];
float progress = 0f;
if (span > 0f)
{
progress = (targetTime - _timeBuffer[_oldestIndex]) / span;
}
transform.position = Vector3.Lerp(_positionBuffer[_oldestIndex], _positionBuffer[nextIndex], progress);
transform.rotation = Quaternion.Lerp(Quaternion.Euler(_positionBuffer[_oldestIndex]), Quaternion.Euler(_positionBuffer[nextIndex]), progress);
}
}
It's "okayish" for the follow; but at some point it will catch the leader; as for a 'sled dog' I don't want the followers to catch the leader but keep the same distance/time delay behind the leader.
I've tried every variation but still stuck with it. Is this even the best approach? How would you do it?
Thanks!