Workshop II - Suspending a RigidBody, Part 2 (Mirror)


This post is a mirror of a message board post I wrote in 2020, reposted as-is. There are no errors I'm aware of, but it would be different if I wrote it all again. I'm copying it here for preservation and because it makes sense. 🙂

Suspending a RigidBody, Part 2

The last post is kind of an incomplete concept, so right away today I'm going to share the second piece to the puzzle that really helps the SpringArm-based shapecasting work. Instead of comparing the position of the SpringArm and RigidBody to locate the applied forces, I've added an extra node as a child of the SpringArm -- a plain RayCast.

Why a RayCast together with the SpringArm? Two important reasons -- the SpringArm (as of this writing) is unable to report anything about the surface it collided with, only how much it is compressed, and a wheel is (obviously) not a sphere. If we apply forces any time the sphere is in contact, rolling the car will usually result in a sudden spike in force when the SpringArm is suddenly compressed, with amusingly terrible results. 😆

By adding a RayCast as a child of the SpringArm, pointing straight out of the bottom of the sphere (make sure it doesn't point forward due to the SpringArm's rotation), you can make sure the bottom of the sphere is in contact before actually applying forces. I'm finding a single RayCast to work well enough. You can also collect the point of contact on the surface with "$RayCast.get_collision_point()", and find out what the wheel is rolling over with "$RayCast.get_collider()".

Lastly, it's a good idea to collect the normal vector of the collision with "$RayCast.get_collision_normal()". I've used this to orient the application of forces relative to the surface, instead of the orientation of the SpringArm or RigidBody.

I've basically done everything you would do with a raycast by itself, except for the suspension force, but with this combo I can take advantage of a round collision shape.

So. For just the suspension, I've applied the force calculated in part one (called "y_force") like this:

    var contact = $RayCast.get_collision_point() - car.global_transform.origin
    var normal = $RayCast.get_collision_normal()
    if $RayCast.is_colliding():  # Check helps eliminate force spikes when tumbling
        car.add_force(normal * y_force, contact)

I'm able to just write "car" because at the top of the script I defined that variable to represent the parent RigidBody of the SpringArm for readability:

onready var car = $'..'    # parent node

This is enough to drop a RigidBody over four SpringArms and watch the suspension work, similar to this point in the Space Dust Racing video.

⏭️ Rays Go Round - Lateral Force ⏭️

Get GDSim

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.