Kinematic Physics

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By babyblueboxers

I’m killing myself trying to figure out how to code for kinematic body physics2D reactions. I’ve been trying all week and hitting dead-ends.

Ordinarily I’d just use RigidBody2D, but there’s a bug right now that prevents bouncy bodies under the influence of stronger-than-average gravity from coming to a rest. I was hoping to manually code a solution.

This is the behavior I seek:

  1. Objects must have configurable bounciness on a scale from 0 (no bounce) to 1 (will bounce forever, never losing inertia, think: flubber).
  2. Objects with bounciness <1 should eventually come to rest (see bug above).
  3. Objects that have come to rest on a slope should slide to a stop based on a friction value with range 0 (slides forever) to 1 (won’t slide at all).
  4. There should be a way to control what degrees an object will slide on; we’ll call it: angle tolerance. This could be tied to friction value. On a scale of 0 to 1, 0.5 will eventually come to rest on 45 degree slopes, but will slide off anything steeper. A value of 1 will stick to even near-vertical walls.

So for example, an object with a bounciness of .5 will lose half it’s inertia per bounce and stop bouncing after just a few iterations. If it stops bouncing on a 45 degree slope and it’s angle-tolerance is .5 or higher, it will slide down the slope but eventually stop before reaching the bottom (provided the distance of the slope is great enough to allow it time to do so), slowing by the factor of it’s friction value. If it’s angle-tolerance were less than .5, it would slide down the slope entirely. Similar to the bounciness, the friction value would control how quickly it comes to a stop on the slope or on a flat surface.

I’ve tried so many iterations for the past week that I’m about ready to pull my hair out. All the links on my google search are “purple” from being clicked on.

I’ve tried move_and_slide, move_and_collide, getting collision normals, lerp’ing the values…heck I even tried combining move_and_slide + collide. No dice. I’m at my wits end and I’m begging for an expert’s help!

This is the closest I got recently, by cobbling together some bits from http://kidscancode.org/. But you’ll notice objects don’t always bounce when they should. Some bounce disproportionately, and flat surface objects don’t bounce at all. There’s also no discreet angle tolerance.

var velocity = Vector2(0,0)
const gravity = 750
const elas = 1
const fric = .25

func _physics_process(delta):


var collision = move_and_collide(velocity * delta)
if collision:
	var motion = collision.remainder.bounce(collision.normal)
	velocity = velocity.bounce(collision.normal)
	velocity.x = lerp(velocity.x, 0, fric)
	velocity.y = lerp(velocity.x, 0, fric)
	move_and_collide(motion)
else:
	velocity += Vector2(0, delta * gravity)