This is a nice trick if you want an object to move in a smooth, but seemingly random way, around a point of interest, while allowing easy customization.

You can define a maximum distance for this movement, and define a position on each axis at which the object should be when it reaches a given point in its movement cycle by acting on the shape of the Animation curves.

The next step is then to define the duration of a “cycle”, and use it in a periodic function along with the elapsed time to know a which point of the cycle we are. The formula is the following: sin(2 * pi * elapsed / cycleDuration). Here we use 2 * pi to handle frequency in seconds (the angular frequency of the sine function).

Finally, we evaluate the Animation Curve and modify the local position of our object accordingly.

```
public class MovementAnimationCurves : MonoBehaviour
{
[Header("Cycle Durations (Seconds)")]
public float mCycleDurationX;
public float mCycleDurationY;
public float mCycleDurationZ;
[Header("Animation Curves")]
public AnimationCurve mCurveX;
public AnimationCurve mCurveY;
public AnimationCurve mCurveZ;
private float _mElapsed = 0f;
private Vector3 _mTempPosition;
private void Awake()
{
_kReferencePosition = transform.localPosition;
}
private void LateUpdate()
{
_mElapsed += Time.deltaTime;
_mTempPosition = _kReferencePosition;
_mTempPosition.x += mCurveX.Evaluate(mCycleDurationX);
_mTempPosition.y += mCurveX.Evaluate(mCycleDurationY);
_mTempPosition.z += mCurveX.Evaluate(mCycleDurationZ);
transform.localPosition = _mTempPosition;
}
private float Evaluate(float cycleDuration)
{
return Mathf.Sin(2f * Mathf.PI * _mElapsed * (1f / cycleDuration));
}
}
```

I put above the simplified version, here are some potential improvements:

- Ensure cycle durations are non-zero
- Rotate the object along its path
- Freeze some axis of rotation
- Replicate in VFX if you don’t need a moving GameObject

Anyways, I think the result is pretty nice, and the movement curves can be easily adjusted to allow for differing trajectories.