[SOLVED] Raycast(+physics) not working in engine-only (v1.67.3)

I’ve been migrating my framework backbone from ThreeJS to PlayCanvas, and I’m encountering issues in implementing physics/raycast functionality. Specifically, raycast functions do not return any results ([]) when they visibly should, and gravity does not seem to be acting on dynamic/kinematic objects.

The following usual culprits have already been checked: Ammo is loaded and fetched from WasmModule before initializing the AppBase with the RigidBody/Collision component systems; the relevant entities definitely possess the components; and in the case of raycasting, the ray definitely passes through the object. Infact, the code is almost identical to the raycast code example provided by PlayCanvas, but simply does not work.

A live example can be found here (with sourcemap): https://slynch.xyz/playcanvas_physics/
The relevant file is PlayCanvasRaycastTestState.ts, as well as Engine.ts if you wish to inspect the AppBase initialization et al.

I’ll provide snippets on request, since as I said the ‘scene’ code is almost verbatim from the raycast example, and it’d be too nebulous to attach all the engine initialization code.

I’m convinced it’s something as simple as I’m not calling some physics update loop that is handled automatically in the editor version of PlayCanvas, but I can’t seem to find it myself nor in the documentation.

UPDATE: If anyone else has this issue, try ensuring that your AppBase.start() call occurs before creating physics objects.

Hi @Slynch and welcome!

Personally I have no engine-only experience, but perhaps the example page below can help you.

https://playcanvas.github.io/#/physics/raycast

Had a quick look. Not sure where the issue is, as it looks ok. The raycast definitely works in 1.67.3. The engine-only example in the repo is using that version.

The Editor doesn’t do anything about Ammo physics except importing it to your project. The physics world is stepped in the Rigidbody Component System, inside onUpdate method. The raycast would return nothing, if you’d never stepped the world. However, I do see the onUpdate runs every frame in your app, and the physics world is stepping fine. Must be something else.

Some notes:

  • When testing, don’t use a moving ray. Hardcode start and end positions at vertical 10 and -10, going through dead center. Place body in world center. All this moving is not necessary and making it harder to debug.
  • When adding components you are passing active property - it doesn’t do anything (unless you have your custom components). Also enabled is true by default, no need to pass it.
  • Make the ball dynamic, and make sure it falls down.
  • Use debug drawer to make sure the visual mesh is matching the rigidbody position:
    PlayCanvas 3D HTML5 Game Engine
2 Likes

Thanks for the reply. I tried hardcoding the ray with no movement and using your debug drawer code (works a charm!) but still the raycast function returns nothing. Additionally, setting the type to RIGIDBODY_TYPE_DYNAMIC does not cause the ball to fall (this was the main reason for my thinking that whatever physics step there is is not being called).

I’m going to clone the PlayCanvas repo and step-through the entire raycast example from start to finish; maybe I can see what I’m missing from that.

(P.S. the redundant active/enabled properties are a by-product of everything I try not working!)

You can step it here as well: PlayCanvas Examples

  • Add a debug line like I added on like 54 for example
  • reload it (with the button on top left of the code window)
  • in the chrome console, put breakpoint on the line printing log
  • reload again (using the same button) - and you get a breakpoint hit.

Found the issue! Apparently any physics objects created prior to calling AppBase.start() are (*almost-)entirely ignored. Calling it at the start of my onAwake function rather than at the end immediately fixed both raycast + gravity issues.

Not sure how to proceed from here; I’d suggest either updating the RigidBodyComponentSystem documentation to note this behaviour (if it’s intended) or investigating the issue if not.

2 Likes

Interesting find. If this is something that can be reproduced in the engine example I linked above, it’d be worth creating an engine issue - not that I’d expect it to be fixed quickly.

It smells like a bug to me … as typically engine objects can be created before the app stats. Not sure what the difference is here.

Glad the workaround is so easy though.

Funnily enough, moving the app.start() call in the raycast example to after the physics objects are created causes a runtime error when adding the Rigidbody component (as opposed to my issue of it failing silently).

1 Like

Make sure you are not initializing the application twice. Maybe you are creating the body in a different instance.

Not gonna lie, I balked at this at first, then thought “huh, actually…” :joy:

But fortunately not; I double-checked and- at least in the live example I provided in the OP- the first and only AppBase.start() call is in my state’s onAwake() function. Additionally the initialize function is definitely not called multiple times.

1 Like