Skip to content

Instantly share code, notes, and snippets.

@majikayogames
Last active May 12, 2025 14:10
Show Gist options
  • Save majikayogames/cf013c3091e9a313e322889332eca109 to your computer and use it in GitHub Desktop.
Save majikayogames/cf013c3091e9a313e322889332eca109 to your computer and use it in GitHub Desktop.
Godot 4 CharacterBody3D to RigidBody3D Push Interaction Script
# CC0/public domain/use for whatever you want no need to credit
# Call this function directly before move_and_slide() on your CharacterBody3D script
func _push_away_rigid_bodies():
for i in get_slide_collision_count():
var c := get_slide_collision(i)
if c.get_collider() is RigidBody3D:
var push_dir = -c.get_normal()
# How much velocity the object needs to increase to match player velocity in the push direction
var velocity_diff_in_push_dir = self.velocity.dot(push_dir) - c.get_collider().linear_velocity.dot(push_dir)
# Only count velocity towards push dir, away from character
velocity_diff_in_push_dir = max(0., velocity_diff_in_push_dir)
# Objects with more mass than us should be harder to push. But doesn't really make sense to push faster than we are going
const MY_APPROX_MASS_KG = 80.0
var mass_ratio = min(1., MY_APPROX_MASS_KG / c.get_collider().mass)
# Optional add: Don't push object at all if it's 4x heavier or more
if mass_ratio < 0.25:
continue
# Don't push object from above/below
push_dir.y = 0
# 5.0 is a magic number, adjust to your needs
var push_force = mass_ratio * 5.0
c.get_collider().apply_impulse(push_dir * velocity_diff_in_push_dir * push_force, c.get_position() - c.get_collider().global_position)
@t0qen
Copy link

t0qen commented Apr 7, 2025

Thank you !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment