Bezier Path considering external forces

I’m currently trying to make an AI spacecraft (2D project) move through a bezier curve. But I would also like to have external forces actuate to that spacecraft (i.e. a black hole).

My first thought was to simply set the .position/.velocity, but then I quickly learn how that overrides all external forces acting upon the spaceship.

My second idea was to make an invisible GO going through that path and attach it to the spacecraft with a spring joint. However, this yields some unpleasant rotation of the spacecraft, since the spring is free to rotate as it wishes.

My last idea was to create to two bezier curves, parallel to each other, on which two anchors will travel. I’ve put the spacecraft in the middle and attach it to the anchors with the spring joints.

It seems extremely functional and exactly what I wished. However, I do feel I’m “reinventing the wheel” and having two springs per spacecraft should be a considerable resource drain for physical calculations for a single spacecraft, specially when I intend to have dozens of them in the screen at the same time.

Does anyone have any good idea to approach this problem? Am I missing something simple and overcomplicating the solution?

Thank you very much!

Try modelling the problem with attract forces. Imagine a target position moving along the bezier curve is really just like a black hole attractor. With this model, multiple attractors (even with different strengths and proximity) create a compound force and therefore movement. The nice thing is that this is closest to the underlying Physics model.

Proximity to an attractor can affect the strength of the force, just like local gravity. See Add Gravitational Attraction to RigidBody2D and Creating Local Gravity To Attract Specific GameObjects

You may also find some inspiration from a similar concept of compound forces, but a slightly different model: Path Following steering behavior from the seminal work of Craig Reynolds - Steering Behaviors For Autonomous Characters (He coined the term ‘boids’). This approach has been developed into a Unity toolkit: UnitySteer

void FixedUpdate()
{
_time += Time.fixedDeltaTime / 5;
var target = _bezierPath.GetPosition(_time);
ApplyForce(target);
}

    private void ApplyForce(Vector2 target)
    {
        Vector2 offset = target - (Vector2)transform.position;
        const float strenght = 10f;
        var magsqr = Vector2.SqrMagnitude(offset);
        var force = (offset*strenght*magsqr*magsqr);
        _rigidbody2D.AddForce(force - _previousForce*GetPreviousForceGain(magsqr), ForceMode2D.Force);
        _previousForce = force;
    }

    private float GetPreviousForceGain(float magsqr)
    {
        const int magsqrThreshold = 1;
        const float maxGain = 0.5f;

        return Mathf.Clamp(magsqr/magsqrThreshold, 0, maxGain);
    }