godot icon indicating copy to clipboard operation
godot copied to clipboard

CharacterBody3D with skeleton and root motion animations gets stuck against other physics objects

Open proggen-com opened this issue 1 year ago • 2 comments

Tested versions

  • Reproducible in v4.3.dev.custom_build [0c6b5efab]

System information

Godot v4.3.dev (0c6b5efab) - Windows 10.0.22631 - Vulkan (Forward+)

Issue description

When running against another physics object with CharacterBody3D with a skeleton and root motion animations the body gets stuck against other physics objects. Using a capsule as the main physics collider.

Looking into this a bit more it seems there are three places in move_and_slide() that can cause the horizontal velocities set to zero.


@@ -178,11 +178,11 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
 					if (motion_vertical_velocity.dot(up_direction) > 0 || ceiling_vertical_velocity.length_squared() > motion_vertical_velocity.length_squared()) {
 						velocity = ceiling_vertical_velocity + velocity.slide(up_direction);
 					}
 				}
 			}
-
+			// HERE (the velocity vector is cleared a bit lower, but the < 0.01 seems a bit arbitrary)
 			if (collision_state.floor && floor_stop_on_slope && (velocity.normalized() + up_direction).length() < 0.01) {
 				Transform3D gt = get_global_transform();
 				if (result.travel.length() <= margin + CMP_EPSILON) {
 					gt.origin -= result.travel;
 				}
@@ -250,10 +250,11 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
 						if (vel_dir_facing_up) {
 							Vector3 slide_motion = velocity.slide(result.collisions[0].normal);
 							// Keeps the vertical motion from velocity and add the horizontal motion of the projection.
 							velocity = up_direction * up_direction.dot(velocity) + slide_motion.slide(up_direction);
 						} else {
+							// HERE (this cancels out the movement sometimes, perhaps a rotation issue)
 							velocity = velocity.slide(forward);
 						}
 
 						// Allow only lateral motion along previous floor when already on floor.
 						// Fixes slowing down when moving in diagonal against an inclined wall.
@@ -291,10 +292,11 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
 				if (p_was_on_floor && (wall_min_slide_angle > 0.0) && result_state.wall) {
 					Vector3 horizontal_normal = wall_normal.slide(up_direction).normalized();
 					real_t motion_angle = Math::abs(Math::acos(-horizontal_normal.dot(motion_slide_up.normalized())));
 					if (motion_angle < wall_min_slide_angle) {
 						motion = up_direction * motion.dot(up_direction);
+						// HERE (this cancels the movement sometimes, perhaps a rotation issue)
 						velocity = up_direction * velocity.dot(up_direction);
 
 						apply_default_sliding = false;
 					}
 				}

Removing these velocity assignments on those lines will fix the getting stuck. But the character will slip and slide.

Steps to reproduce

Run the test project and walk against the cylinder wall for some time.

Minimal reproduction project (MRP)

stuck.zip

https://github.com/godotengine/godot/assets/91064515/b66fef75-3144-4d61-822f-4b89d1a1cc9c

proggen-com avatar Apr 08 '24 19:04 proggen-com

@TokageItLab Is this related to the root motion in animations problem?

fire avatar Apr 08 '24 21:04 fire

@fire No, it is not relevant animation as the root motion is just a value. I do not know how the authors of the issue apply the root motion, but this is a physical area issue as long as it is applied as follows as I have wrote in the document:

func _process(delta):
    if Input.is_action_just_pressed("animate"):
        state_machine.travel("Animate")
    set_quaternion(get_quaternion() * animation_tree.get_root_motion_rotation())
    var velocity: Vector3 = (animation_tree.get_root_motion_rotation_accumulator().inverse() * get_quaternion()) * animation_tree.get_root_motion_position() / delta
    set_velocity(velocity)
    move_and_slide()

If the root motion is being added directly to the coordinate values, then the script is wrong.

TokageItLab avatar Apr 09 '24 02:04 TokageItLab