use new spawn api

This commit is contained in:
2025-04-29 19:55:40 +02:00
parent 11568d57ed
commit 5cc97da98b
8 changed files with 265 additions and 282 deletions

View File

@@ -100,8 +100,7 @@ fn on_trigger_gun(
let mut t = Transform::from_translation(state.pos).with_rotation(rotation); let mut t = Transform::from_translation(state.pos).with_rotation(rotation);
t.translation += t.forward().as_vec3() * 2.0; t.translation += t.forward().as_vec3() * 2.0;
commands commands.spawn((
.spawn((
Name::new("projectile-gun"), Name::new("projectile-gun"),
GunProjectile { GunProjectile {
time: time.elapsed_secs(), time: time.elapsed_secs(),
@@ -116,8 +115,7 @@ fn on_trigger_gun(
CollisionEventsEnabled, CollisionEventsEnabled,
Visibility::default(), Visibility::default(),
t, t,
)) Children::spawn(Spawn(Gizmo {
.with_child(Gizmo {
handle: gizmo_assets.add({ handle: gizmo_assets.add({
let mut g = GizmoAsset::default(); let mut g = GizmoAsset::default();
g.line(Vec3::Z * -2., Vec3::Z * 2., LinearRgba::rgb(0.9, 0.9, 0.)); g.line(Vec3::Z * -2., Vec3::Z * 2., LinearRgba::rgb(0.9, 0.9, 0.));
@@ -128,7 +126,8 @@ fn on_trigger_gun(
..default() ..default()
}, },
..default() ..default()
}); })),
));
} }
fn update(mut query: Query<&mut Transform, With<GunProjectile>>) { fn update(mut query: Query<&mut Transform, With<GunProjectile>>) {

View File

@@ -114,8 +114,7 @@ fn on_trigger_missile(
let mesh = assets.projectiles["missile.glb"].clone(); let mesh = assets.projectiles["missile.glb"].clone();
let asset = gltf_assets.get(&mesh).unwrap(); let asset = gltf_assets.get(&mesh).unwrap();
commands commands.spawn((
.spawn((
Name::new("projectile-missle"), Name::new("projectile-missle"),
MissileProjectile { MissileProjectile {
time: time.elapsed_secs(), time: time.elapsed_secs(),
@@ -130,13 +129,13 @@ fn on_trigger_missile(
CollisionEventsEnabled, CollisionEventsEnabled,
Visibility::default(), Visibility::default(),
t, t,
)) children![
.with_child(( (
Transform::from_rotation(Quat::from_rotation_x(PI / 2.).inverse()) Transform::from_rotation(Quat::from_rotation_x(PI / 2.).inverse())
.with_scale(Vec3::splat(0.04)), .with_scale(Vec3::splat(0.04)),
SceneRoot(asset.scenes[0].clone()), SceneRoot(asset.scenes[0].clone()),
)) ),
.with_child(( (
Trail::new(t.translation, LinearRgba::rgb(0.9, 0.9, 0.)), Trail::new(t.translation, LinearRgba::rgb(0.9, 0.9, 0.)),
Gizmo { Gizmo {
handle: gizmo_assets.add(GizmoAsset::default()), handle: gizmo_assets.add(GizmoAsset::default()),
@@ -146,6 +145,8 @@ fn on_trigger_missile(
}, },
..default() ..default()
}, },
)
],
)); ));
} }

View File

@@ -29,8 +29,7 @@ pub fn plugin(app: &mut App) {
} }
fn setup(mut commands: Commands, assets: Res<UIAssets>) { fn setup(mut commands: Commands, assets: Res<UIAssets>) {
commands commands.spawn((
.spawn((
Name::new("target-ui"), Name::new("target-ui"),
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
@@ -39,45 +38,37 @@ fn setup(mut commands: Commands, assets: Res<UIAssets>) {
height: Val::Px(74.0), height: Val::Px(74.0),
..default() ..default()
}, },
)) children![spawn_head_ui(
.with_children(|parent| {
spawn_head_ui(
parent,
assets.head_bg.clone(), assets.head_bg.clone(),
assets.head_regular.clone(), assets.head_regular.clone(),
assets.head_damage.clone(), assets.head_damage.clone(),
); )],
}); ));
commands.insert_resource(TargetUi::default()); commands.insert_resource(TargetUi::default());
} }
fn spawn_head_ui( fn spawn_head_ui(bg: Handle<Image>, regular: Handle<Image>, damage: Handle<Image>) -> impl Bundle {
parent: &mut ChildSpawnerCommands,
bg: Handle<Image>,
regular: Handle<Image>,
damage: Handle<Image>,
) {
const SIZE: f32 = 90.0; const SIZE: f32 = 90.0;
const DAMAGE_SIZE: f32 = 74.0; const DAMAGE_SIZE: f32 = 74.0;
parent (
.spawn((Node { Node {
position_type: PositionType::Relative, position_type: PositionType::Relative,
justify_content: JustifyContent::Center, justify_content: JustifyContent::Center,
align_items: AlignItems::Center, align_items: AlignItems::Center,
width: Val::Px(SIZE), width: Val::Px(SIZE),
..default() ..default()
},)) },
.with_children(|parent| { children![
parent.spawn(( (
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
..default() ..default()
}, },
ImageNode::new(bg), ImageNode::new(bg),
)); ),
parent.spawn(( (
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
..default() ..default()
@@ -85,23 +76,21 @@ fn spawn_head_ui(
ImageNode::default(), ImageNode::default(),
Visibility::Hidden, Visibility::Hidden,
HeadImage, HeadImage,
)); ),
parent.spawn(( (
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
..default() ..default()
}, },
ImageNode::new(regular), ImageNode::new(regular),
)); ),
parent (
.spawn((Node { Node {
height: Val::Px(DAMAGE_SIZE), height: Val::Px(DAMAGE_SIZE),
width: Val::Px(DAMAGE_SIZE), width: Val::Px(DAMAGE_SIZE),
..default() ..default()
},)) },
.with_children(|parent| { children![(
parent
.spawn((
HeadDamage, HeadDamage,
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
@@ -113,10 +102,11 @@ fn spawn_head_ui(
height: Val::Percent(25.), height: Val::Percent(25.),
..default() ..default()
}, },
)) children![ImageNode::new(damage)]
.with_child(ImageNode::new(damage)); )]
}); )
}); ],
)
} }
fn update( fn update(

View File

@@ -2,7 +2,7 @@ use super::{BackbackSwapEvent, Backpack, UiHeadState};
use crate::{ use crate::{
GameState, global_observer, heads::HeadsImages, loading_assets::UIAssets, sounds::PlaySound, GameState, global_observer, heads::HeadsImages, loading_assets::UIAssets, sounds::PlaySound,
}; };
use bevy::prelude::*; use bevy::{ecs::spawn::SpawnIter, prelude::*};
static HEAD_SLOTS: usize = 5; static HEAD_SLOTS: usize = 5;
@@ -57,8 +57,7 @@ pub fn plugin(app: &mut App) {
} }
fn setup(mut commands: Commands, assets: Res<UIAssets>) { fn setup(mut commands: Commands, assets: Res<UIAssets>) {
commands commands.spawn((
.spawn((
Name::new("backpack-ui"), Name::new("backpack-ui"),
BackpackMarker, BackpackMarker,
Visibility::Hidden, Visibility::Hidden,
@@ -69,19 +68,23 @@ fn setup(mut commands: Commands, assets: Res<UIAssets>) {
height: Val::Px(74.0), height: Val::Px(74.0),
..default() ..default()
}, },
)) Children::spawn(SpawnIter((0..HEAD_SLOTS).map({
.with_children(|parent| { let bg = assets.head_bg.clone();
for i in 0..HEAD_SLOTS { let regular = assets.head_regular.clone();
let selector = assets.head_selector.clone();
let damage = assets.head_damage.clone();
move |i| {
spawn_head_ui( spawn_head_ui(
parent, bg.clone(),
assets.head_bg.clone(), regular.clone(),
assets.head_regular.clone(), selector.clone(),
assets.head_selector.clone(), damage.clone(),
assets.head_damage.clone(),
i, i,
); )
} }
}); }))),
));
commands.spawn(( commands.spawn((
Name::new("backpack-head-count-ui"), Name::new("backpack-head-count-ui"),
@@ -105,26 +108,25 @@ fn setup(mut commands: Commands, assets: Res<UIAssets>) {
} }
fn spawn_head_ui( fn spawn_head_ui(
parent: &mut ChildSpawnerCommands,
bg: Handle<Image>, bg: Handle<Image>,
regular: Handle<Image>, regular: Handle<Image>,
selector: Handle<Image>, selector: Handle<Image>,
damage: Handle<Image>, damage: Handle<Image>,
head_slot: usize, head_slot: usize,
) { ) -> impl Bundle {
const SIZE: f32 = 90.0; const SIZE: f32 = 90.0;
const DAMAGE_SIZE: f32 = 74.0; const DAMAGE_SIZE: f32 = 74.0;
parent (
.spawn((Node { Node {
position_type: PositionType::Relative, position_type: PositionType::Relative,
justify_content: JustifyContent::Center, justify_content: JustifyContent::Center,
align_items: AlignItems::Center, align_items: AlignItems::Center,
width: Val::Px(SIZE), width: Val::Px(SIZE),
..default() ..default()
},)) },
.with_children(|parent| { children![
parent.spawn(( (
Name::new("selector"), Name::new("selector"),
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
@@ -134,16 +136,16 @@ fn spawn_head_ui(
Visibility::Hidden, Visibility::Hidden,
ImageNode::new(selector).with_flip_y(), ImageNode::new(selector).with_flip_y(),
HeadSelector(head_slot), HeadSelector(head_slot),
)); ),
parent.spawn(( (
Name::new("bg"), Name::new("bg"),
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
..default() ..default()
}, },
ImageNode::new(bg), ImageNode::new(bg),
)); ),
parent.spawn(( (
Name::new("head"), Name::new("head"),
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
@@ -152,27 +154,23 @@ fn spawn_head_ui(
ImageNode::default(), ImageNode::default(),
Visibility::Hidden, Visibility::Hidden,
HeadImage(head_slot), HeadImage(head_slot),
)); ),
parent.spawn(( (
Name::new("rings"), Name::new("rings"),
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
..default() ..default()
}, },
ImageNode::new(regular), ImageNode::new(regular),
)); ),
parent (
.spawn((
Name::new("health"), Name::new("health"),
Node { Node {
height: Val::Px(DAMAGE_SIZE), height: Val::Px(DAMAGE_SIZE),
width: Val::Px(DAMAGE_SIZE), width: Val::Px(DAMAGE_SIZE),
..default() ..default()
}, },
)) children![(
.with_children(|parent| {
parent
.spawn((
Name::new("damage_ring"), Name::new("damage_ring"),
HeadDamage(head_slot), HeadDamage(head_slot),
Node { Node {
@@ -185,10 +183,11 @@ fn spawn_head_ui(
height: Val::Percent(0.), height: Val::Percent(0.),
..default() ..default()
}, },
)) children![ImageNode::new(damage)]
.with_child(ImageNode::new(damage)); )]
}); )
}); ],
)
} }
fn update_visibility( fn update_visibility(

View File

@@ -82,8 +82,7 @@ fn update_ui(
let show_ui = cam_state.look_around || cam_state.cutscene; let show_ui = cam_state.look_around || cam_state.cutscene;
if show_ui { if show_ui {
commands commands.spawn((
.spawn((
CameraUi, CameraUi,
Node { Node {
margin: UiRect::top(Val::Px(20.)) margin: UiRect::top(Val::Px(20.))
@@ -92,14 +91,14 @@ fn update_ui(
justify_content: JustifyContent::Center, justify_content: JustifyContent::Center,
..default() ..default()
}, },
)) children![(
.with_child((
Node { Node {
display: Display::Block, display: Display::Block,
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
..default() ..default()
}, },
ImageNode::new(assets.camera.clone()), ImageNode::new(assets.camera.clone()),
)],
)); ));
} else { } else {
for entity in query.iter() { for entity in query.iter() {

View File

@@ -1,5 +1,5 @@
use crate::{GameState, backpack::UiHeadState, loading_assets::UIAssets, player::Player}; use crate::{GameState, backpack::UiHeadState, loading_assets::UIAssets, player::Player};
use bevy::prelude::*; use bevy::{ecs::spawn::SpawnIter, prelude::*};
use bevy_ui_gradients::{AngularColorStop, BackgroundGradient, ConicGradient, Gradient, Position}; use bevy_ui_gradients::{AngularColorStop, BackgroundGradient, ConicGradient, Gradient, Position};
use std::f32::consts::PI; use std::f32::consts::PI;
@@ -36,8 +36,7 @@ pub fn plugin(app: &mut App) {
} }
fn setup(mut commands: Commands, assets: Res<UIAssets>) { fn setup(mut commands: Commands, assets: Res<UIAssets>) {
commands commands.spawn((
.spawn((
Name::new("heads-ui"), Name::new("heads-ui"),
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
@@ -46,44 +45,47 @@ fn setup(mut commands: Commands, assets: Res<UIAssets>) {
height: Val::Px(74.0), height: Val::Px(74.0),
..default() ..default()
}, },
)) Children::spawn(SpawnIter((0..HEAD_SLOTS).map({
.with_children(|parent| { let bg = assets.head_bg.clone();
for i in 0..HEAD_SLOTS { let regular = assets.head_regular.clone();
let selector = assets.head_selector.clone();
let damage = assets.head_damage.clone();
move |i| {
spawn_head_ui( spawn_head_ui(
parent, bg.clone(),
assets.head_bg.clone(), regular.clone(),
assets.head_regular.clone(), selector.clone(),
assets.head_selector.clone(), damage.clone(),
assets.head_damage.clone(),
i, i,
); )
} }
}); }))),
));
commands.init_resource::<UiActiveHeads>(); commands.init_resource::<UiActiveHeads>();
} }
fn spawn_head_ui( fn spawn_head_ui(
parent: &mut ChildSpawnerCommands,
bg: Handle<Image>, bg: Handle<Image>,
regular: Handle<Image>, regular: Handle<Image>,
selector: Handle<Image>, selector: Handle<Image>,
damage: Handle<Image>, damage: Handle<Image>,
head_slot: usize, head_slot: usize,
) { ) -> impl Bundle {
const SIZE: f32 = 90.0; const SIZE: f32 = 90.0;
const DAMAGE_SIZE: f32 = 74.0; const DAMAGE_SIZE: f32 = 74.0;
parent (
.spawn((Node { Node {
position_type: PositionType::Relative, position_type: PositionType::Relative,
justify_content: JustifyContent::Center, justify_content: JustifyContent::Center,
align_items: AlignItems::Center, align_items: AlignItems::Center,
width: Val::Px(SIZE), width: Val::Px(SIZE),
..default() ..default()
},)) },
.with_children(|parent| { children![
parent.spawn(( (
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
top: Val::Px(-30.0), top: Val::Px(-30.0),
@@ -92,16 +94,15 @@ fn spawn_head_ui(
Visibility::Hidden, Visibility::Hidden,
ImageNode::new(selector), ImageNode::new(selector),
HeadSelector(head_slot), HeadSelector(head_slot),
)); ),
(
parent.spawn((
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
..default() ..default()
}, },
ImageNode::new(bg), ImageNode::new(bg),
)); ),
parent.spawn(( (
Name::new("head-icon"), Name::new("head-icon"),
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
@@ -120,23 +121,21 @@ fn spawn_head_ui(
ImageNode::default(), ImageNode::default(),
Visibility::Hidden, Visibility::Hidden,
HeadImage(head_slot), HeadImage(head_slot),
)); ),
parent.spawn(( (
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
..default() ..default()
}, },
ImageNode::new(regular), ImageNode::new(regular),
)); ),
parent (
.spawn((Node { Node {
height: Val::Px(DAMAGE_SIZE), height: Val::Px(DAMAGE_SIZE),
width: Val::Px(DAMAGE_SIZE), width: Val::Px(DAMAGE_SIZE),
..default() ..default()
},)) },
.with_children(|parent| { children![(
parent
.spawn((
HeadDamage(head_slot), HeadDamage(head_slot),
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
@@ -148,10 +147,11 @@ fn spawn_head_ui(
height: Val::Percent(25.), height: Val::Percent(25.),
..default() ..default()
}, },
)) children![ImageNode::new(damage)]
.with_child(ImageNode::new(damage)); )]
}); )
}); ],
)
} }
fn update( fn update(

View File

@@ -28,8 +28,7 @@ fn on_spawn_key(trigger: Trigger<KeySpawn>, mut commands: Commands, assets: Res<
let angle = rand::random::<f32>() * PI * 2.; let angle = rand::random::<f32>() * PI * 2.;
let spawn_dir = Quat::from_rotation_y(angle) * Vec3::new(0.5, 0.6, 0.).normalize(); let spawn_dir = Quat::from_rotation_y(angle) * Vec3::new(0.5, 0.6, 0.).normalize();
commands commands.spawn((
.spawn((
Name::new("key"), Name::new("key"),
Key(id.clone()), Key(id.clone()),
Transform::from_translation(*position), Transform::from_translation(*position),
@@ -40,11 +39,11 @@ fn on_spawn_key(trigger: Trigger<KeySpawn>, mut commands: Commands, assets: Res<
RigidBody::Dynamic, RigidBody::Dynamic,
CollisionEventsEnabled, CollisionEventsEnabled,
Restitution::new(0.6), Restitution::new(0.6),
)) Children::spawn(Spawn((
.with_child((
Billboard, Billboard,
SquishAnimation(2.6), SquishAnimation(2.6),
SceneRoot(assets.mesh_key.clone()), SceneRoot(assets.mesh_key.clone()),
))),
)); ));
} }

View File

@@ -64,8 +64,7 @@ fn spawn(
let gravity = Vector::NEG_Y * 40.0; let gravity = Vector::NEG_Y * 40.0;
let collider = Collider::capsule(0.9, 1.2); let collider = Collider::capsule(0.9, 1.2);
commands commands.spawn((
.spawn((
Name::from("player"), Name::from("player"),
Player, Player,
ActiveHead(0), ActiveHead(0),
@@ -83,18 +82,15 @@ fn spawn(
// LockedAxes::ROTATION_LOCKED, todo // LockedAxes::ROTATION_LOCKED, todo
CollisionLayers::new(LayerMask(GameLayer::Player.to_bits()), LayerMask::ALL), CollisionLayers::new(LayerMask(GameLayer::Player.to_bits()), LayerMask::ALL),
CharacterControllerBundle::new(collider, gravity), CharacterControllerBundle::new(collider, gravity),
)) children![(
.with_children(|parent| {
parent
.spawn((
Name::new("player-rig"), Name::new("player-rig"),
Transform::default(), Transform::default(),
Visibility::default(), Visibility::default(),
PlayerBodyMesh, PlayerBodyMesh,
CameraArmRotation, CameraArmRotation,
)) children![AnimatedCharacter(0)]
.with_child(AnimatedCharacter(0)); )],
}); ));
commands.spawn(( commands.spawn((
AudioPlayer::new(asset_server.load("sfx/heads/angry demonstrator.ogg")), AudioPlayer::new(asset_server.load("sfx/heads/angry demonstrator.ogg")),