This repository has been archived on 2025-04-28. You can view files and clone it, but cannot push or open issues or pull requests.
ARPlusSystem/ARPlusSystem-250418/Assets/ARLocation/Scripts/Utils/SmoothMove.cs

102 lines
2.9 KiB
C#
Raw Normal View History

using System;
using System.Collections;
using UnityEngine;
namespace ARLocation.Utils
{
public class SmoothMove : MonoBehaviour
{
public enum Mode
{
Horizontal,
Full
}
[Tooltip("The smoothing factor."), Range(0, 1)]
public float Epsilon = 0.5f;
[Tooltip("The Precision."), Range(0, 0.1f)]
public float Precision = 0.05f;
public Vector3 Target
{
get { return target; }
set
{
target = value;
if (co != null)
{
StopCoroutine(co);
}
co = MoveTo(target);
StartCoroutine(MoveTo(target));
}
}
[Tooltip("The mode. If set to 'Horizontal', will leave the y component unchanged. Full means the object will move in all 3D coordinates.")]
public Mode SmoothMoveMode = Mode.Full;
private Vector3 target;
private Action onTargetReached;
private IEnumerator co;
public void Move(Vector3 to, Action callback = null)
{
onTargetReached = callback;
Target = to;
}
private IEnumerator MoveTo(Vector3 pTarget)
{
if (SmoothMoveMode == Mode.Horizontal)
{
Vector2 horizontalPosition = MathUtils.HorizontalVector(transform.position);
Vector2 horizontalTarget = MathUtils.HorizontalVector(pTarget);
while (Vector2.Distance(horizontalPosition, horizontalTarget) > Precision)
{
float t = 1.0f - Mathf.Pow(Epsilon, Time.deltaTime);
horizontalPosition = Vector3.Lerp(horizontalPosition, horizontalTarget, t);
transform.position = MathUtils.HorizontalVectorToVector3(horizontalPosition, transform.position.y);
yield return null;
}
transform.position = MathUtils.HorizontalVectorToVector3(horizontalTarget, transform.position.y);
onTargetReached?.Invoke();
onTargetReached = null;
}
else
{
while (Vector3.Distance(transform.position, pTarget) > Precision)
{
float t = 1.0f - Mathf.Pow(Epsilon, Time.deltaTime);
transform.position = Vector3.Lerp(transform.position, pTarget, t);
yield return null;
}
transform.position = pTarget;
onTargetReached?.Invoke();
onTargetReached = null;
}
}
public static SmoothMove AddSmoothMove(GameObject go, float epsilon)
{
var smoothMove = go.AddComponent<SmoothMove>();
smoothMove.Epsilon = epsilon;
return smoothMove;
}
}
}