engine
engine copied to clipboard
Raycast returns always null on first frame [AMMO]
Reproduced
var Main = pc.createScript('main');
// initialize code called once per entity
Main.prototype.initialize = function() {
this._box = this.app.assets.find("Box", "template").resource.instantiate();
};
Main.prototype.postInitialize = function(){
this.box1 = this._box.clone();
this.app.root.addChild(this.box1);
this.box1.setPosition(0, 0.5, 0);
this.box2 = this._box.clone();
this.app.root.addChild(this.box2);
this.box2.setPosition(3, 0.5, 0);
const from = this.box1.getPosition();
const to = this.box2.getPosition();
console.log(this.app.systems.rigidbody.raycastFirst(from, to));
};
Simple project that reproduces the issue:
https://playcanvas.com/project/923018/overview/test-raycasting
- Expected outcome: raycast works and returns a RaycastResult.
- Right now: returns null.
It seems that the dynamic world needs to update at least once to put all bodies in place / initialize colliders. Temp fix:
this.app.systems.rigidbody.onUpdate(0);
console.log(this.app.systems.rigidbody.raycastFirst(from, to));
Is this first frame of the app or first frame the the entity is created in?
Looking at the event lifecycle (PR https://github.com/playcanvas/developer.playcanvas.com/pull/374), you would be able to do the raycast in postUpdate of the script as that's after the physics system update.
Not sure if there's much we can do here if there's a dependency on the Ammo update to run for raycasting to work 🤔
No It happens on the first frame of the game (dt=0).
Thinking about this, should we run/initialize the physics world before the very first script update with a dt of 0?
But often you set up positions and create physics elements in the first update.
Hmm, the positions and physics elements are set on body initialization, which often takes place on script initialization. I don't think creating a physics body in update method is a common practice. I think you need to step the world at least once, after adding a body to it in order to be able to query it, e.g. hit it with a raycast.
I did encounter issues caused by dt being zero a couple of times. It is not obvious, but debugging shows it immediately and it is easy to avoid. Being aware of the first frame delta time being zero, I simply ignore the update frame if dt === 0
when my update method depends on dt or I need a query. You can still interact with bodies normally on the first frame, like applying forces and such, even with dt being zero. This is mostly happening on some test scenes, where I do a raycast immediately for some feature test. In real apps, the physics interaction usually happens way later into the app lifecycle.
We can probably just document that caveat.