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.

animation curve-based trajectories butterflies
Creating Complex Paths for our butterflies

The code is also available on Github.