Player can't move off of moving body

Godot Version

v4.2.2.stable.official on Linux Mint

Question

I’m working on a game that takes place on a moving train that frequently stops at stations for the player to interact with, so lots of physics objects that move around relative to the ground and the train. I’m running into a movement issue on the train, and created the simplest reproducible case I could. I also made a video demonstration.

I have a player on a moving platform representing a train, and another platform on top of the train that is an AnimatableBody3D, parented to the train, with Sync to Physics off to make the collider move with the train (for CollisionShape does not update moving AnimatableBody3D? · Issue #67257 · godotengine/godot · GitHub). Movement physics largely works, except when I try to move forward off the red platform in the direction the train is moving, the player gets stuck, jiggling at the edge. Similar behavior happens when trying to walk off the front edge of the train. I have similar behavior with both Jolt and Godot Physics (video and repo use Jolt).

I can see is_on_floor() toggling when the player is at the front lip of the platform, but it seems like in this case, the CharacterBody3D forgets it needs to add the velocity. I also have a hypothesis that for some reason, the falling character collides with the lip again because of gravity pulling it down, then the velocity applied is 0, but I’m not sure how to test this.

Any ideas or things I can try to debug/fix this behavior? Thanks!

It looks like it’s not something unique to having a separate AnimatableBody3D. If the CollisionShape3D is directly a child of the Train still has the same jittering when trying to move forward off the front. The following image shows this test case.

Update:
Sorry to triple post, but I might have fixed it, and it also simplifies some jumping code contortions I had. The fix is now in GitHub - superlou/train-physics.

It seems like in the CharacterBody3D platform_on_leave property, it never really was adding the last platform’s velocity. I noticed this by walking off the platform perpendicular to the direction of motion and seeing the character immediately stop moving horizontally relative to the ground before making contact.

I changed the code to explicitly add the velocity of the last platform the character was on:

var last_platform_vel := Vector3.ZERO

func _physics_process(delta):
	var speed = sprint_speed if Input.is_action_pressed("sprint") else walk_speed

	velocity = _walk(delta, speed) +_gravity(delta) + _jump(delta)
	if not is_on_floor():
		velocity += last_platform_vel

	move_and_slide()

	if is_on_floor():
		last_platform_vel = get_platform_velocity()

However, I can’t find an existing bug open for this, so maybe I’m missing something else. With this change, I can now walk forward off the platform in the direction the train is moving.

I think there is a property in the inspector that allows you to change how the character body works on moving platforms. It’s in the moving platform category.

Yes, that’s the platform_on_leave property. I think I’m just finding that property doesn’t work as expected. Of it is “Add Velocity,” I would expect it to automatically do something like the logic I’ve added above.