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.