Physics
Physics in Ambient is powered by Nvidia’s PhysX (user guide, PhysX API documentation).
Colliders
To get started with physics, you’ll need colliders - 3D shapes that represent objects, often with simplified geometry. Ambient provides a number of primitive colliders to assist with basic shapes; as an example, here is how you would create a cube collider:
#![allow(unused)] fn main() { Entity::new() .with_merge(Transformable::suggested()) .with(cube_collider(), Vec3::ONE) .spawn(); }
See the API docmentation for other colliders. Most commonly, you, or the prefab generated by the asset pipeline, will use collider_from_url
to load a collider from a file.
The code above will create a physics collider, but this collider will not be visible without a
visual representation. The cube
component can be used to attach a cube model to the entity:
#![allow(unused)] fn main() { Entity::new() .with_merge(Transformable::suggested()) .with(cube_collider(), Vec3::ONE) .with(cube(), ()) .spawn(); }
Dynamic objects
The above code will create static colliders; these can be collided with, but do not move.
This is ideal for level geometry, but not for moving objects. To create a dynamic object,
you’ll need a collider and the physics_controlled
and dynamic
components:
#![allow(unused)] fn main() { Entity::new() .with_merge(Transformable::suggested()) .with(cube_collider(), Vec3::ONE) .with(cube(), ()) .with(physics_controlled(), ()) .with(dynamic(), true) .spawn(); }
physics_controlled
is used to indicate that any changes to the physics representation of the object should be copied back to the ECS (including translation and rotation).dynamic
indicates it’s an object that can move.
Collision message
The Collision
message is sent when two or more objects collide with each other. It contains a list of the colliding entities:
#![allow(unused)] fn main() { Collision::subscribe(move |msg| { println!("Bonk! {:?} collided", msg.ids); }); }
Colliders from models
Model files can also be used as colliders (i.e. .gltf
and .fbx
files). Add this to your pipeline.toml
:
[[pipelines]]
type = "Models"
[pipelines.collider]
type = "FromModel"
Colliders will be made for the models, and then included as part of the associated prefab for the model. You can then use the prefab to create entities with colliders:
#![allow(unused)] fn main() { Entity::new() .with_merge(Transformable::suggested()) .with(prefab_from_url(), assets::url("shape.glb")) .spawn(); }
Examples
See the physics example.