Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Spawning Entities

Basic Entity Spawning

Spawn entities with spawn_entities, specifying component flags:

#![allow(unused)]
fn main() {
let entity = world.spawn_entities(
    LOCAL_TRANSFORM | GLOBAL_TRANSFORM | RENDER_MESH | MATERIAL_REF,
    1
)[0];
}

Then set component values:

#![allow(unused)]
fn main() {
world.core.set_local_transform(entity, LocalTransform {
    translation: Vec3::new(0.0, 1.0, 0.0),
    rotation: Quat::identity(),
    scale: Vec3::new(1.0, 1.0, 1.0),
});

world.core.set_render_mesh(entity, RenderMesh {
    name: "cube".to_string(),
    id: None,
});

world.core.set_material_ref(entity, MaterialRef::new("Default"));
}

Spawning Multiple Entities

Spawn multiple entities at once:

#![allow(unused)]
fn main() {
let entities = world.spawn_entities(LOCAL_TRANSFORM | GLOBAL_TRANSFORM, 100);

for (index, entity) in entities.iter().enumerate() {
    world.core.set_local_transform(*entity, LocalTransform {
        translation: Vec3::new(index as f32 * 2.0, 0.0, 0.0),
        ..Default::default()
    });
}
}

Helper Functions

Nightshade provides convenience functions for common entities. Primitive spawn helpers and fly_camera_system / escape_key_exit_system are available from the prelude.

Cameras

#![allow(unused)]
fn main() {
let camera = spawn_camera(world, Vec3::new(0.0, 5.0, 10.0), "Main Camera".to_string());
world.resources.active_camera = Some(camera);

let orbit_camera = spawn_pan_orbit_camera(
    world,
    Vec3::zeros(),
    10.0,
    0.5,
    0.4,
    "Orbit Camera".to_string(),
);
}

Lights

#![allow(unused)]
fn main() {
let sun = spawn_sun(world);
}

To create a point light, manually spawn an entity with the LIGHT flag and set the Light component with LightType::Point:

#![allow(unused)]
fn main() {
let light = world.spawn_entities(
    LOCAL_TRANSFORM | GLOBAL_TRANSFORM | LIGHT,
    1,
)[0];

world.core.set_local_transform(light, LocalTransform {
    translation: Vec3::new(0.0, 3.0, 0.0),
    ..Default::default()
});

world.core.set_light(light, Light {
    light_type: LightType::Point,
    color: Vec3::new(1.0, 0.8, 0.6),
    intensity: 5.0,
    range: 10.0,
    cast_shadows: true,
    shadow_bias: 0.005,
    inner_cone_angle: 0.0,
    outer_cone_angle: 0.0,
});
}

Primitives

All primitive spawn helpers are available from the prelude:

#![allow(unused)]
fn main() {
spawn_cube_at(world, Vec3::new(0.0, 1.0, 0.0));
spawn_sphere_at(world, Vec3::new(2.0, 1.0, 0.0));
spawn_plane_at(world, Vec3::zeros());
spawn_cylinder_at(world, Vec3::new(4.0, 1.0, 0.0));
spawn_cone_at(world, Vec3::new(6.0, 1.0, 0.0));
spawn_torus_at(world, Vec3::new(8.0, 1.0, 0.0));
}

Physics Objects

Physics spawn convenience functions are available in nightshade::ecs::physics::commands (not in the prelude):

#![allow(unused)]
fn main() {
use nightshade::ecs::physics::commands::*;

let dynamic_cube = spawn_dynamic_physics_cube_with_material(
    world,
    Vec3::new(0.0, 5.0, 0.0),
    Vec3::new(1.0, 1.0, 1.0),
    1.0,
    Material {
        base_color: [0.8, 0.2, 0.2, 1.0],
        ..Default::default()
    },
);

let floor = spawn_static_physics_cube_with_material(
    world,
    Vec3::new(0.0, -0.5, 0.0),
    Vec3::new(50.0, 1.0, 50.0),
    Material::default(),
);
}

Available helpers: spawn_static_physics_cube_with_material, spawn_dynamic_physics_cube_with_material, spawn_dynamic_physics_sphere_with_material, spawn_dynamic_physics_cylinder_with_material.

You can also create physics entities manually by combining the appropriate component flags:

#![allow(unused)]
fn main() {
let entity = world.spawn_entities(
    LOCAL_TRANSFORM | GLOBAL_TRANSFORM | LOCAL_TRANSFORM_DIRTY
    | RENDER_MESH | MATERIAL_REF | RIGID_BODY | COLLIDER,
    1,
)[0];

world.core.set_local_transform(entity, LocalTransform {
    translation: Vec3::new(0.0, 5.0, 0.0),
    ..Default::default()
});

world.core.set_render_mesh(entity, RenderMesh {
    name: "cube".to_string(),
    id: None,
});

world.core.set_material_ref(entity, MaterialRef::new("Default"));

world.core.set_rigid_body(entity, RigidBodyComponent {
    body_type: RigidBodyType::Dynamic,
    ..Default::default()
});
}

Character Controllers

#![allow(unused)]
fn main() {
let (player_entity, camera_entity) = spawn_first_person_player(world, Vec3::new(0.0, 2.0, 0.0));
}

spawn_first_person_player takes the world and position, and returns a tuple of (Entity, Entity) for the player entity and camera entity.

Loading Models

Load glTF/GLB models:

#![allow(unused)]
fn main() {
use nightshade::ecs::prefab::*;

let model_bytes = include_bytes!("../assets/character.glb");
let result = import_gltf_from_bytes(model_bytes)?;

for (name, (rgba_data, width, height)) in result.textures {
    world.queue_command(WorldCommand::LoadTexture {
        name,
        rgba_data,
        width,
        height,
    });
}

for (name, mesh) in result.meshes {
    mesh_cache_insert(&mut world.resources.mesh_cache, name, mesh);
}

for prefab in result.prefabs {
    let entity = spawn_prefab_with_animations(
        world,
        &prefab,
        &result.animations,
        Vec3::new(0.0, 0.0, 0.0),
    );
}
}

Adding Components After Spawn

Add component flags to an existing entity:

#![allow(unused)]
fn main() {
world.core.add_components(entity, AUDIO_SOURCE);
world.core.set_audio_source(entity, AudioSource::new("music").playing());
}

Despawning Entities

Remove entities from the world:

#![allow(unused)]
fn main() {
world.despawn_entities(&[entity]);

despawn_recursive_immediate(world, entity);
}

Entity with Parent

Spawn an entity as a child:

#![allow(unused)]
fn main() {
let parent = world.spawn_entities(LOCAL_TRANSFORM | GLOBAL_TRANSFORM, 1)[0];
let child = world.spawn_entities(LOCAL_TRANSFORM | GLOBAL_TRANSFORM | PARENT, 1)[0];

world.core.set_parent(child, Parent(Some(parent)));
world.core.set_local_transform(child, LocalTransform {
    translation: Vec3::new(0.0, 1.0, 0.0),
    ..Default::default()
});
}