godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.16k stars 21.2k forks source link

Physical Bones that aren't simulating don't get detected by RayCasts #51929

Closed giabeni closed 4 months ago

giabeni commented 3 years ago

Godot version

3.4.beta4

System information

Windows 10, GLES3, Intel UHD 620

Issue description

Hello guys! I'm making some tests with ragdolls and they started pretty promising. But, now I'm struggling with something that I'm very convinced to be a bug...

VIDEO DEMO: https://youtu.be/YWCvQ84bPNw

What I want:

Apply an impulse to the bone clicked by the mouse.

How am I doing:

  1. I'm using intersect_ray() from the camera to the mouse position
  2. Then I place a pink sphere in the result position (just for debugging). This part is working nicely!
  3. If the collider of the raycast result is a Physical Bone, I'm starting the simulation of this bone, and applying the impulse to it. This is also working fine.

Code:

#Man.gd

func _physics_process(delta):

    if Input.is_action_just_pressed("click"):
        var mouse_position = get_viewport().get_mouse_position()
        var ray_length = 100
        var ray_origin = camera.project_ray_origin(mouse_position)
        var ray_to = ray_origin + camera.project_ray_normal(mouse_position) * ray_length
        # Raycasting excluding self Kinematic Body
        var ray_test = get_world().direct_space_state.intersect_ray(ray_origin, ray_to, [self], 0b101)

        if not ray_test.empty(): 
            Debug.add_marker(ray_test.position)

            if ray_test.collider is PhysicalBone:
                var bone: PhysicalBone = ray_test.collider
                var bone_simulating = bone.is_simulating_physics()
                if not bone_simulating:
                    var bone_name = bone.get("bone_name")
                    skeleton.physical_bones_start_simulation([bone_name])
                    bone.gravity_scale = 1

                var impulse_dir = camera.global_transform.origin.direction_to(ray_test.position)
                bone.apply_impulse(bone.to_local(ray_test.position), impulse_dir * 0.5)

What's the problem?

Take a look at the video! There are 2 problems:

  1. The Physical Bones don't follow the bones transforms (animations and move_and_slide) until I call skeleton.physical_bones_start_simulation([...]). So, to detect the bone, I have to first click "outside" the mesh, where the Physical Bones got frozen. P.S. Maybe, it shows that #24359 and #34313 may not be fully resolved by PR #36008), from @AndreaCatania .

  2. After I start the simulation of at least one bone, the Physical Bones transforms begins to follow the bones (and the animations). However, no other bone gets detected by the raycasts, no more. Only those that I've started simulating (and its children).

You can see that after I hit the character's hand, the bones capsules start moving but I can't detect other bones except the hand (the pink ball is always placed in the floor).

If I simulate all bones, though, It works. But obviously the character falls as a proper ragdoll...(watch the end of the first simulation)

Summaryzing:

In the beginning, no bone has started simulation, and I can detect any bone with the raycast. Then, when I start the simulation of one, no longer can I detect other bones except this one.

What have I checked:

  1. Collision Masks and Layers are ok, since they work before I start simulating.
  2. It happens even with no animation playing
  3. I've set the physical bones as NOT toplevel, so they don't get frozen even though the Kinematic Body is moving. However, they still don't follow the animations until I start one simulation.
  4. If I start the simulation and then stop it again, the problem persists. I can just detect the bones' bodies if I reload the scene.
  5. The same happens in 3.3.stable;

Thanks in advance!

Steps to reproduce

  1. Open the project;
  2. Enable Debug Collisions;
  3. Run the TestRagdoll.tscn scene;
  4. Left Click the terrain to test the raycast detections (pink balls will appear in the hitpoints)
  5. Try to left click the character's foot (in the mesh). It should not detect the character
  6. Try to left click the same foot collision shape. It should apply an impulse to the character's foot.
  7. The Physical Bones should now be following the armature.
  8. Try to hit any other bone. Nothing will happen. (The pink balls appear in the terrain)
  9. Try to hit the foot again, it will apply a new impulse
  10. Press space to start simulating all bones. Now everything will respond to clicks.
  11. Press space again to reload the scene.

Controls:

WASD: moves player Arrow keys: move camera Middle-Click + Mouse motion: rotates camera Space: Start simulation for all bones Space again: Restart scene

Minimal reproduction project

ragdoll-tests.zip

WilliamTambellini commented 3 years ago

Tks @giabeni Same issue with 3.3.3.

Zireael07 commented 2 years ago

I seem to be having the same issue. My ragdoll is only switched on when the AI is dead, and I just discovered that the physical bones are otherwise stuck at the origin, where I instanced the AI, and are invisible but perfectly collidable.