using UnityEngine; [ExecuteInEditMode] public class PathFollow : MonoBehaviour { public float tangentDist = 0.01f; public float alpha; public float speed; public bool rot; public float time; public float ctime; public int curve; public MegaShape target; public float distance; public bool animate; public bool UseDistance = true; public bool addtwist; public Vector3 offset = Vector3.zero; public Vector3 rotate = Vector3.zero; public MegaRepeatMode loopmode; public void SetPos(float a) { if (!(target != null)) { return; } float twist = 0f; switch (loopmode) { case MegaRepeatMode.Clamp: a = Mathf.Clamp01(a); break; case MegaRepeatMode.Loop: a = Mathf.Repeat(a, 1f); break; case MegaRepeatMode.PingPong: a = Mathf.PingPong(a, 1f); break; } Vector3 vector = Vector3.zero; Vector3 vector2 = target.InterpCurve3D(curve, a, target.normalizedInterp, ref twist); if (rot) { float num = tangentDist / target.GetCurveLength(curve); Vector3 vector3 = target.InterpCurve3D(curve, a + num, target.normalizedInterp); Vector3 euler = rotate; Quaternion quaternion = Quaternion.Euler(0f, 0f, twist); Quaternion quaternion2 = Quaternion.Euler(euler); if (addtwist) { quaternion2 = quaternion * quaternion2; } Vector3 forward = vector3 - vector2; Quaternion quaternion3 = Quaternion.LookRotation(forward); vector = Matrix4x4.TRS(Vector3.zero, quaternion3 * quaternion2, Vector3.one).MultiplyPoint3x4(offset); base.transform.localRotation = quaternion3 * quaternion2; } base.transform.position = target.transform.TransformPoint(vector2 - vector); } public void SetPosFomDist(float dist) { if (!(target != null)) { return; } float num = dist / target.GetCurveLength(curve); float twist = 0f; switch (loopmode) { case MegaRepeatMode.Clamp: num = Mathf.Clamp01(num); break; case MegaRepeatMode.Loop: num = Mathf.Repeat(num, 1f); break; case MegaRepeatMode.PingPong: num = Mathf.PingPong(num, 1f); break; } Vector3 vector = Vector3.zero; Vector3 vector2 = target.InterpCurve3D(curve, num, target.normalizedInterp, ref twist); if (rot) { float num2 = tangentDist / target.GetCurveLength(curve); Vector3 vector3 = target.InterpCurve3D(curve, num + num2, target.normalizedInterp); Vector3 euler = rotate; Quaternion quaternion = Quaternion.Euler(0f, 0f, twist); Quaternion quaternion2 = Quaternion.Euler(euler); if (addtwist) { quaternion2 = quaternion * quaternion2; } Vector3 forward = vector3 - vector2; Quaternion quaternion3 = Quaternion.LookRotation(forward); vector = Matrix4x4.TRS(Vector3.zero, quaternion3 * quaternion2, Vector3.one).MultiplyPoint3x4(offset); base.transform.localRotation = quaternion3 * quaternion2; } base.transform.position = target.transform.TransformPoint(vector2 - vector); } public void Start() { ctime = 0f; curve = 0; } private void Update() { if (animate) { if (UseDistance) { distance += speed * Time.deltaTime; } else if (time > 0f) { ctime += Time.deltaTime; if (ctime > time) { ctime = 0f; } alpha = ctime / time * 100f; } else if (speed != 0f) { alpha += speed * Time.deltaTime; if (alpha > 100f) { alpha = 0f; } else if (alpha < 0f) { alpha = 100f; } } } if (UseDistance) { SetPosFomDist(distance); } else { SetPos(alpha * 0.01f); } } }