Vortex/Black Hole Physics

So before I start, I did try googling this a bit. And there’s really nothing that gets the effect right. Unless there’s an extra step I’m missing.
This is meant as a 2D game, but I’m using 3D physics with an orthographic camera.
Basically, I have this vortex on the screen. Just a sphere for now. When objects get near it, I want them to be pulled towards the center. The strength of the pulling force should be strongest near the center of the vortex and slowly decrease as you extend out.
If an object is moving fast enough, it should be able to avoid being sucked into the vortex (depending on how close it is to the center), but may have its path altered by the force of the pull.
It is possible to shoot another object through the center of the vortex with enough speed to potentially knock out the objects that are trapped in its center.

my code on my vortex is:

void FixedUpdate()
    {
        Vector3 explosionPos = thisTransform.position;
        Collider[] colliders = Physics.OverlapSphere(explosionPos, radius);
        foreach(Collider hit in colliders)
        {
            if(hit && hit.transform != thisTransform && hit.rigidbody)
            {
                Vector3 difference = hit.transform.position - thisTransform.position;
                hit.rigidbody.AddForce(difference.normalized * power, ForceMode.Force);
            }
        }
    }

My objects are spheres with sphere colliders and rigidbodies. They are initially launched by setting rigidbody.velocity.
My vortex is a sphere with a sphere collider set as a trigger (to avoid actual objects colliding with the vortex itself)
This almost works… but it causes more of an orbit type of effect, that eventually launches the objects out on its own. I’m assuming the amount of force that gets added ends up pushing the object passed the center, causing the opposite force to apply on the next check, making it sort of ping pong back and forth.

Any ideas?

Try squaring the force, basically. Right now your force is just a linear relationship to distance. A big factor of gravitational effects is the exponential increase of force as you get closer (2x closer is 4x the force, 4x closer is 16x the force, etc).

I think my problem is still that AddForce is pushing the object passed the target’s center.
I added an extra trigger to the center of the vortex that will stop velocity and disable gravity on enter. Then re-enable gravity on exit. That seems to get it working for the most part

This is how you calculate gravitational acceleration:

/// <summary>
    /// The Newton's constant, an empirical physical constant involved in the calculation(s) of gravitational force between two bodies.
    /// </summary>
    private const float gravitationalConstant = 6.672e-11f;

    /// <summary>
    /// Calculates gravitational acceleration for a Rigidbody under the influence of a large "mass" point at a "position".
    /// Use this in each FixedUpdate(): rigidbody.velocity += GAcceleration(planetPosition, planetMass, rigidbody);
    /// </summary>
    /// <returns>The acceleration.</returns>
    /// <param name="position">Position of the planet's center of mass.</param>
    /// <param name="mass">Mass of the planet (kg). Use large values. </param>
    /// <param name="r">The Rigidbody to accelerate.</param>
    public static Vector3 GAcceleration(Vector3 position, float mass, Rigidbody r) {
        Vector3 direction = position - r.position;

        float gravityForce = gravitationalConstant * ((mass * r.mass) / direction.sqrMagnitude);
        gravityForce /= r.mass;

        return direction.normalized * gravityForce * Time.fixedDeltaTime;
    }

Note that mass is in kg so it needs to be a very large value.

That is standard gravitation that will make your spaceship orbit around the black hole. If you need it to be sucked in like a vortex, all you need to do is add a bit of drag to the Rigidbody. Slowing down will gradually lower it’s orbit which will simultaneously speed it up the closer it gets to the centre like in a real vortex.

Cheers,
Pärtel

1 Like