Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections.Generic;
- using UnityEngine;
- /// <summary>
- /// Sets the position and the rotation of this game object's transform to be the position and rotation of another object some amount of time in the past.
- /// </summary>
- public class DelayedFollow : MonoBehaviour
- {
- [Tooltip("The time in seconds that the position and rotation will be delayed by.")]
- public float Delay = 1f;
- [Tooltip("The target that this transform will follow.")]
- public Transform Target;
- [Tooltip("How you want it to follow.")]
- public DelayedFollowMode Mode = DelayedFollowMode.PositionAndRotation;
- [Tooltip("The position and rotation of this GameObject will snap initialize to the position and rotation of the target.")]
- public bool SnapInitialize = true;
- /// <summary>
- /// Stores information on the past rotation and position data.
- /// </summary>
- private readonly Queue<PositionAndRotation> _positionRotationData = new Queue<PositionAndRotation>();
- /// <summary>
- /// Used for lerping between the time frame in the past, vs the Peek() which will be in the future
- /// [_current.AtTime] -> [Time.time] -> [_positionRotationData.Peek().AtTime]
- /// </summary>
- private PositionAndRotation _current;
- void Start ()
- {
- if (Target == null)
- {
- Debug.LogError("There is no target on this DelayedFollow. [Object: " + name + "]");
- this.enabled = false;
- return;
- }
- _current = new PositionAndRotation(Target);
- if (SnapInitialize)
- {
- switch (Mode)
- {
- case DelayedFollowMode.PositionOnly:
- this.transform.position = Target.position;
- break;
- case DelayedFollowMode.RotationOnly:
- this.transform.rotation = Target.rotation;
- break;
- case DelayedFollowMode.PositionAndRotation:
- this.transform.position = Target.position;
- this.transform.rotation = Target.rotation;
- break;
- }
- }
- }
- // Update is called once per frame
- void Update ()
- {
- _positionRotationData.Enqueue(new PositionAndRotation(Target));
- // Don't let the Delay be negative
- if (Delay < 0)
- {
- Delay = -Delay;
- }
- // This is our adjusted time, we want the positional data for this time frame
- float delayedTime = Time.time - Delay;
- while (_positionRotationData.Peek().AtTime < delayedTime)
- {
- _current = _positionRotationData.Dequeue();
- }
- // We are still at the beginning before the delay has initially past.
- if (_current.AtTime > delayedTime)
- {
- switch (Mode)
- {
- case DelayedFollowMode.PositionOnly:
- this.transform.position = _current.Position;
- break;
- case DelayedFollowMode.RotationOnly:
- this.transform.rotation = _current.Rotation;
- break;
- case DelayedFollowMode.PositionAndRotation:
- this.transform.position = _current.Position;
- this.transform.rotation = _current.Rotation;
- break;
- }
- }
- else
- {
- PositionAndRotation peek = _positionRotationData.Peek();
- float t = (Time.time - _current.AtTime) / (peek.AtTime - _current.AtTime);
- switch (Mode)
- {
- case DelayedFollowMode.PositionOnly:
- this.transform.position = Vector3.Lerp(_current.Position, peek.Position, t);
- break;
- case DelayedFollowMode.RotationOnly:
- this.transform.rotation = Quaternion.Lerp(_current.Rotation, peek.Rotation, t);
- break;
- case DelayedFollowMode.PositionAndRotation:
- this.transform.position = Vector3.Lerp(_current.Position, peek.Position, t);
- this.transform.rotation = Quaternion.Lerp(_current.Rotation, peek.Rotation, t);
- break;
- }
- }
- }
- /// <summary>
- /// Represents the position and rotation of a transform at a given time.
- /// </summary>
- private class PositionAndRotation
- {
- /// <summary>
- /// The position at the given time.
- /// </summary>
- public readonly Vector3 Position;
- /// <summary>
- /// The rotation at the given time.
- /// </summary>
- public readonly Quaternion Rotation;
- /// <summary>
- /// The time that this position and rotation occured at.
- /// </summary>
- public readonly float AtTime;
- public PositionAndRotation(Transform transform)
- {
- Position = transform.position;
- Rotation = transform.rotation;
- AtTime = Time.time;
- }
- }
- /// <summary>
- /// How you want it to follow
- /// </summary>
- public enum DelayedFollowMode
- {
- PositionAndRotation,
- PositionOnly,
- RotationOnly
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment