# RayCast Collision Still Detects Standing Position After Lying Down Animation

**URL:** https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677
**Category:** Physics and Collisions
**Created:** [February 10, 2025, 9:09pm UTC](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677 "2025-02-10T21:09:31Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![hal09](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/h/e9c0ed/32.png) [@hal09](https://forum.castle-engine.io/u/hal09)
#### Post date: [February 10, 2025, 9:09pm UTC](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677/1 "2025-02-10T21:09:32Z")

</div>

Hi everyone,

I have an issue where my **player plays an animation from standing to lying down** , but when I use **PhysicsRayCast** to detect collisions, it behaves as if the player is still standing. The raycast seems to ignore the animation state and detects collisions as if the player hasn’t changed position.

Has anyone faced this before? Do I need to manually update the bounding box or physics after playing an animation?

Thanks in advance for any help!

---

<div class="post-metadata">

### Author: ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)
#### Post date: [February 10, 2025, 9:16pm UTC](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677/2 "2025-02-10T21:16:14Z")

</div>

`PhysicsRayCast` (whether you mean [the one at Viewport.Items.RayCast](https://castle-engine.io/apidoc/html/CastleTransform.TCastleAbstractRootTransform.html#PhysicsRayCast-TVector3-TVector3-Single-TCastleRigidBody-) or the [TCastleRigidBody.PhysicsRayCast](https://castle-engine.io/apidoc/html/CastleTransform.TCastleRigidBody.html#PhysicsRayCast-TVector3-TVector3-Single-) ) takes a position from which to shoot the ray. ( The documentation linked above clarify the coordinate system of this position – either world or parent coordinate system. ) In neither case does the animation or bounding box of the scene matter.

IOW, playing animation doesn’t change the player position, i.e. `TCastleScene.Translation` stays the same.

---

<div class="post-metadata">

### Author: ![hal09](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/h/e9c0ed/32.png) [@hal09](https://forum.castle-engine.io/u/hal09)
#### Post date: [February 10, 2025, 10:10pm UTC](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677/3 "2025-02-10T22:10:34Z")

</div>

## i use TCastleScene.World.PhysicsRayCast

When the player who was shot is in a standing position. Here everything is good. But if he crawls on the ground here the function returns the results as if the player was in a standing position.  
The player who was shot does not change his place, he only changes his animation, for example, standing. croshing. Crawling on the ground.

I found the solution :  
You must execute TCastleMeshCollider.MeshChanged after play new animation  
especially from standing animation to croshing or Crawling on the ground.

```auto
    { Update the collider triangles to reflect current @link(Mesh) shape.
      This is necessary for physics engine to reflect the @link(Mesh).

      We do it automatically in some circumstances (like when you change
      collider properties, like @link(Mesh) or @link(DoubleSided),
      or when you change @link(TCastleSceneCore.Url)) but we don't try to keep
      the physics mesh follow the triangles every frame (as you really shouldn't
      change physics mesh so often, it's supposed to be a static collider). }
    procedure MeshChanged;

```

now i play animation like this :

```auto
procedure TPlayer.PlayAnimation(forward, Loop: Boolean; TransitionDuration: Single; Name: string);
var
  CastleMeshCollider: TCastleMeshCollider;
  Params: TPlayAnimationParameters;
begin
  if FScene <> nil then
  begin
    Params := TPlayAnimationParameters.Create;
    try
      Params.Name := Name;
      Params.forward := forward;
      Params.Loop := Loop;
      Params.TransitionDuration := TransitionDuration;
      Params.StopNotification := OnAnimationStopped;
      FScene.PlayAnimation(Params);

      TTask.Run(procedure
      begin
        // Wait for the animation to reach the new position before updating the collider
        TTask.CurrentTask.Wait(Round(TransitionDuration * 1000) + UpdateMeshAfterAnimationStartDelay {100}); //-> Wait for transition + 100ms
        TThread.Queue(nil, procedure
        begin
          // Update Mesh after the animation transition completes
          CastleMeshCollider := (Scene.FindBehavior(TCastleMeshCollider) as TCastleMeshCollider);
          if CastleMeshCollider <> nil then
          begin
            CastleMeshCollider.InternalAutoSize;
            CastleMeshCollider.MeshChanged;
          end;
        end);
      end);

      FIsPlayingAnimation := True;
      FAnimationPlayedName := Name;
    finally
      FreeAndNil(Params);
    end;
  end;
end;

```

---

<div class="post-metadata">

### Author: ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)
#### Post date: [February 10, 2025, 10:39pm UTC](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677/4 "2025-02-10T22:39:20Z")

</div>

> [@hal09](#):
>
> TCastleMeshCollider

Ah, got it! OK, I understand now what you do better – you want `TCastleMeshCollider` to reflect the new animation state. Indeed, this does not happen automatically, because the `MeshChanged` call takes some time (it’s not something you want to do every frame) and it “forgets” all collisions with previous mesh.

But in your case, I guess this is acceptable. Calling it just once, after changing the animation, may be acceptable. And you don’t care that it “forgets” current collisions, you want the new calls to `PhysicsRayCast` to account for it OK.

So, overall, your solution is OK… except you really don’t need `TTask.Run`, `TTask.CurrentTask.Wait`, `TThread.Queue` 🙂 That’s a bit complicated. See [PlayAnimation](https://castle-engine.io/apidoc/html/CastleSceneCore.TCastleSceneCore.html#PlayAnimation-TPlayAnimationParameters-) docs, in particular:

> Calling this method _does not change the scene immediately_.  
> …  
> If you really need to change the scene immediately (for example, because you don’t want to show user the initial scene state), simply call [ForceInitialAnimationPose](https://castle-engine.io/apidoc/html/CastleSceneCore.TCastleSceneCore.html#ForceInitialAnimationPose) right after [PlayAnimation](https://castle-engine.io/apidoc/html/CastleSceneCore.TCastleSceneCore.html#PlayAnimation-String-boolean-boolean-).

So, right after `FScene.PlayAnimation(Params);`, it should be enough to call `FScene.ForceInitialAnimationPose` and then do your calls

```delphi
// Update Mesh after the animation transition completes
CastleMeshCollider := (Scene.FindBehavior(TCastleMeshCollider) as TCastleMeshCollider);
if CastleMeshCollider <> nil then
begin
  CastleMeshCollider.InternalAutoSize;
  CastleMeshCollider.MeshChanged;
end;

```

No need for threads, no need to wait 🙂

Hopefully this helps, in the end you found the solution yourself, but I hope my suggestion above helps to make it even simpler 🙂

P.S. See also [Threads | Manual | Castle Game Engine](https://castle-engine.io/threads) - _" All access to the Castle Game Engine API must happen from one and the same thread."_.

---

<div class="post-metadata">

### Author: ![hal09](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/h/e9c0ed/32.png) [@hal09](https://forum.castle-engine.io/u/hal09)
#### Post date: [February 11, 2025, 6:47am UTC](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677/5 "2025-02-11T06:47:26Z")

</div>

**Thank you so much, Michalis!**

Your explanation was really helpful. I didn’t realize that ForceInitialAnimationPose could simplify things that much! Now the collider updates perfectly without the need for threads, and everything works smoothly.

I really appreciate your support and the time you take to help us. Castle Game Engine keeps getting more fun to work with thanks to your guidance!

---

<div class="post-metadata">

### Author: ![hal09](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/h/e9c0ed/32.png) [@hal09](https://forum.castle-engine.io/u/hal09)
#### Post date: [March 8, 2025, 10:21pm UTC](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677/6 "2025-03-08T22:21:42Z")

</div>

After many attempts, I reached this conclusion.

### \*\*🔹 Optimal Collision Detection Method for a Shooter Game

After extensive testing and analysis, I have found an **efficient and optimized** way to handle collision detection in a shooter game.

### **✅ Final Conclusion: The Best Collision Detection Approach**

1️⃣ **Use TCastleScene for Each Player Bone** ✅

- Every **bone** should have its own **scene without a collider (MeshCollider) or RigidBody**.
- This ensures that every part of the player’s body can be targeted accurately.

2️⃣ **Use RayCast Instead of Traditional Physics Colliders** ✅

- **RayCast can detect collisions accurately without updating the mesh collider**.
- When a bullet is fired, a **RayCast is sent from the bullet** to check for collisions with the player’s bones.
- This method ensures **real-time, accurate hit detection** , even when the player is crouching, prone, or moving dynamically.

3️⃣ **Avoid Using MeshCollider or RigidBody for the Main Player** ✅

- **MeshCollider is very CPU-intensive** because it requires continuous updates during animations.
- **RigidBody and Physics Colliders should only be used for static objects** like _ **buildings, walls, and roads** _.

4️⃣ **Use Physics RayCast Only for Static Objects** ✅

- When detecting collisions with **the environment, buildings, terrain** , **Physics RayCast is useful**.
- **For moving players, use traditional RayCast instead** to ensure real-time accuracy.

* * *

### **🎯 Key Advantages of This Method:**

✔ **Reduces CPU Load** → No need to constantly update Mesh Colliders.  
✔ **Increases Collision Accuracy** → Every body part can be hit precisely.  
✔ **Avoids Issues with Player Animation (Crouching, Prone, etc.)**.  
✔ **Easier to Implement Bullet Penetration & Damage Calculation**.

* * *

### **💡 Final Takeaway:**

**✅ Use RayCast with bone-based scenes (without physical colliders) for player hit detection, and use Physics RayCast only for static objects like buildings and terrain.**

🚀 **This method provides the best performance and accuracy for modern shooter games!**

---

<div class="post-metadata">

### Author: ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)
#### Post date: [March 9, 2025, 7:02am UTC](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677/7 "2025-03-09T07:02:36Z")

</div>

IMO, that’s not exactly the right conclusion. Here’s my approach:

- Indeed, you are right that “mesh collider” is supposed to be used for static objects only. Rebuilding mesh collider (by `CastleMeshCollider.MeshChanged`) is a time-consuming operation, not something you should do often.

- But it doesn’t mean that non-physical `RayCast` is the way to go. It doesn’t actually give you more efficiency. In fact, eventually the non-physical `RayCast` will disappear and we will rely on `PhysicsRayCast` for all collision detection (see _" 13. Old system for collisions and gravity"_ section on [Physics | Manual | Castle Game Engine](https://castle-engine.io/physics#_old_system_for_collisions_and_gravity) ).

- The efficient way to have precise collisions in FPS game (and this is true for both Castle Game Engine and other engines, e.g. I used this with Unity games too long time ago) is to attach TCastleRigodBody and colliders (but not static mesh colliders!) to every bone. So you add e.g. TCastleSphereCollider for the player’s head, then 2 TCastleBoxCollider for player’s 2 arms etc. Use our [ExposeTransforms](https://castle-engine.io/expose) mechanism to attach things, like colliders, to bones of your model.

- And then you can use `PhysicsRayCast` with everything.

- Additional benefit: if you define joints on your rigid bodies, then you should be able to do “rag-doll” on your models, e.g. let the enemies’ bodies fly into walls with realistic physics when they are dead.

- TODO: I’m aware I should make a demo of everything here :), to show how it should be done. It should come!

---

<div class="post-metadata">

### Author: ![hal09](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/h/e9c0ed/32.png) [@hal09](https://forum.castle-engine.io/u/hal09)
#### Post date: [March 9, 2025, 8:07pm UTC](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677/8 "2025-03-09T20:07:14Z")

</div>

> [@michalis](#):
>
> TODO: I’m aware I should make a demo of everything here :), to show how it should be done. It should come!

Thank you very much

* * *

Actually, I thought about this approach,  
but then I wondered—if there are many players, say 30, and each bone has its own collider and rigid body, maybe this would be too taxing on the CPU.

So, I asked ChatGPT, and it told me, “You’re right!” 🙂  
So I abandoned the idea and instead used a **scene for each bone** with **WorldRay**.

The result, I think, was quite good:

- **No bullets skipped**
- **All collisions detected**

But I’ll still try **PhysicsRayCast** with **colliders + rigid bodies** to see how it compares.

---

<div class="post-metadata">

### Author: ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)
#### Post date: [March 10, 2025, 5:20am UTC](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677/9 "2025-03-10T05:20:23Z")

</div>

> [@hal09](#):
>
> So, I asked ChatGPT, and it told me, “You’re right!” 🙂

**Please don’t trust ChatGPT for such conclusions 🙂**

ChatGPT is guessing. It will tell you anything to please you. It hallucinates. It will agree to anything you ask, when you ask in the right way, it will agree that 2+2=5. It knows Castle Game Engine (and everything else) only on a very superficial level from scanning the Internet and it’s guessing a lot when the answer didn’t exactly appear on the Internet already.

To be clear, using AI for development is useful, but you need to “be in charge” and be able to verify everything it tells you. Answers to high-level questions, like “how do I do something”, may be completely wrong, unless the exact same question have been already asked before and the answer was on the Internet. Answers to details (like “why does this not compile”) are sometimes better, _when you provide it enough context_.

To be clear, I use Copilot for coding, and I value it. It’s useful. AI is useful. But you need to be ready to reject a lot of the things it says, because it’s very often just wrong.

Your past message in this thread ( [RayCast Collision Still Detects Standing Position After Lying Down Animation - #6 by hal09](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677/6) ) did suggest it comes from ChatGPT. Please don’t do this. You will arrive at very wrong conclusions by listening to ChatGPT.

> [@hal09](#):
>
> but then I wondered—if there are many players, say 30, and each bone has its own collider and rigid body, maybe this would be too taxing on the CPU.

It is taxing indeed, but the other solution you outlined – no colliders and just using non-physics ray casting – is also taxing 🙂 See [13. Old system for collisions and gravity](https://castle-engine.io/physics#_old_system_for_collisions_and_gravity) – our old system just assumes a box for each scene. So it also has a lot of “colliders”, they are just not visible as explicit components.

That said, having a hierarchy of colliders (with proper parameters for colliders – you will want [TCastleRigidBody.Animated](https://castle-engine.io/apidoc/html/CastleTransform.TCastleRigidBody.html#Animated) = true and [TCastleRigidBody.Dynamic](https://castle-engine.io/apidoc/html/CastleTransform.TCastleRigidBody.html#Dynamic) = false when animating the skeleton; change them only when the creature is dead and you want to use ragdoll) → should be fast enough. That’s in general what FPS games do.

Of course, testing this in practice is definitely wise, please report if it doesn’t work like I describe.

And I know – I should prepare a demo using it too. I have added this to my TODO.

Regards!

---

<div class="post-metadata">

### Author: ![hal09](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/h/e9c0ed/32.png) [@hal09](https://forum.castle-engine.io/u/hal09)
#### Post date: [March 10, 2025, 10:06am UTC](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677/10 "2025-03-10T10:06:24Z")

</div>

Yes the method works perfectly .

---

<div class="post-metadata">

### Author: ![hal09](https://forum.castle-engine.io/letter_avatar_proxy/v4/letter/h/e9c0ed/32.png) [@hal09](https://forum.castle-engine.io/u/hal09)
#### Post date: [March 10, 2025, 6:46pm UTC](https://forum.castle-engine.io/t/raycast-collision-still-detects-standing-position-after-lying-down-animation/1677/11 "2025-03-10T18:46:21Z")

</div>

hello  
Something like that

[https://www.youtube.com/watch?v=AqSg\_Dyj1OE](https://www.youtube.com/watch?v=AqSg_Dyj1OE)
