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() }); }