The PhysicsScene (PhysicsScene) manages all physics components in the scene and communicates with the physics backend, implementing global operations related to the PhysicsScene, such as updates and ray casting. In multi-scene projects, each Scene has its own PhysicsScene, and physics systems between Scenes are isolated and do not affect each other.
The PhysicsScene and rendering scene are independent but continuously synchronize their data during program execution. Therefore, like scripts, the timing of synchronization is also very important. The update frequency of the PhysicsScene differs from the rendering scene and is controlled by the following parameter:
/** The fixed update time step (seconds) of the PhysicsScene */
fixedTimeStep: number = 1 / 60;
fixedTimeStep
:
engine.time.maximumDeltaTime
fixedTimeStep
, it accumulates to the next frameFor physics component updates, you need to use a dedicated callback function in scripts:
export class Script extends Component {
/**
* Called before physics calculations, the number of calls depends on the physics update frequency
*/
onPhysicsUpdate(): void {}
}
The position of the physics update in the entire update process can be referred to in the figure below
The execution order when the PhysicsScene is updated:
onPhysicsUpdate
callColliderOnUpdate
synchronizes the modified Entity Transform
data to the physics collidercallColliderOnLateUpdate
synchronizes the updated positions of all colliders to the corresponding Entity
The PhysicsScene allows customization of gravity direction and magnitude. Gravity affects all dynamic colliders with gravity enabled in the scene.
// Get the gravity value of the PhysicsScene
const gravity = scene.physics.gravity;
// Modify gravity - set gravity to 0
scene.physics.gravity.set(0, 0, 0);
// Modify gravity - set to Earth's gravitational acceleration (default value)
scene.physics.gravity.set(0, -9.81, 0);
A ray can be understood as an infinite line emitted from a point in a certain direction in the 3D world. Raycasting is widely used in 3D applications:
To use raycasting, follow these steps:
raycast
method to detect collisions// Load the Raycast module
import { WebGLEngine, HitResult, Ray } from "@galacean/engine";
import { LitePhysics } from "@galacean/engine-physics-lite";
const engine = await WebGLEngine.create({
canvas: "canvas",
physics: new LitePhysics()
});
engine.canvas.resizeByClientSize();
const scene = engine.scenes[0];
// Convert screen input to Ray
document.getElementById("canvas").addEventListener("click", (e) => {
const ratio = window.devicePixelRatio;
let ray = new Ray();
camera.screenPointToRay(new Vector2(e.offsetX, e.offsetY).scale(ratio), ray);
const hit = new HitResult();
result = scene.physics.raycast(ray, Number.MAX_VALUE, Layer.Everything, hit);
if (result) {
console.log(hit.entity.name);
}
});