System to get data from one entity to modify data on another entity #9813
-
I'm not understanding how to get data from a related entity. I have Actors and Ships. Actors have a goal (Vec3) which is where they want to go. Ships have a destination (Vec3) which is where they are going.
I basically need to compare ship.destination and ship.pilot.goal, but I can't because Ship and Pilot are separate entities. I have other issues with the code below, so it doesn't run, but here's what I have so far. use bevy::prelude::*;
#[derive(Component)]
struct Actor {
name: String,
goal: Vec3
}
#[derive(Component)]
struct Ship {
name: String,
pilot: Option<Entity>,
location: Vec3,
destination: Vec3,
speed: usize
}
// build_universe does the following:
// 1. Spawn an actor and captures the entity ID to a variable
// 2. Spawn a ship
// 3. Add Piloted to Ship with the actor as the Entity
fn build_universe(mut commands: Commands) {
let actor = commands.spawn((
Actor {
name: "Actor".to_string(),
goal: Vec3::new(10.0, 0.0, 0.0)
},
Transform::default(),
GlobalTransform::default()
)).id();
commands.spawn((
Ship {
name: "Ship".to_string(),
pilot: Some(actor),
location: Vec3::new(-10.0, 0.0, 0.0),
destination: Vec3::new(-10.0, 0.0, 0.0),
speed: 1
},
Transform::default(),
GlobalTransform::default()
));
}
// control_ship function to query list of Ship with Piloted, and check if Actor.goal is different from
// Ship.destination. If so, update Ship.destination to Actor.goal
fn control_ship(mut query: Query<&mut Ship>){
for (mut ship) in query.iter_mut() {
if let Some(pilot) = ship.pilot {
// get Actor component of pilot
let pilot = query.get_mut(pilot).unwrap();
if ship.destination != pilot.Actor.goal {
ship.destination = pilot.goal;
}
}
}
}
// function to move Ship.location towards Ship.destination at Ship.speed.
fn move_ship(
time: Res<Time>,
mut query: Query<(&mut Ship, &mut Transform)>,
) {
for (mut ship, piloted, actor) in query.iter_mut() {
let mut delta = ship.destination - ship.location;
delta = delta.normalize();
delta = delta * ship.speed as f32;
ship.location = ship.location + delta;
// print ship location to console
println!("Ship location: {:?}", ship.location);
}
}
fn update_goal(){}
fn main() {
App::new()
// Bevy itself:
.add_plugins(DefaultPlugins)
// systems to run once at startup:
.add_systems(Startup, build_universe)
// systems to run each frame:
.add_systems(Update, (
bevy::window::close_on_esc,
control_ship,
move_ship, //TODO, run once per second
update_goal
))
// launch the app!
.run();
}``` |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
I think you may be missing that your systems can have multiple queries. fn control_ship(mut query: Query<&mut Ship>, mut actor_query: Query<&Actor>) {
for mut ship in query.iter_mut() {
if let Some(pilot) = ship.pilot {
let pilot = actor_query.get_mut(pilot).unwrap();
if ship.destination != pilot.goal {
ship.destination = pilot.goal;
}
}
}
} Side note: to get your code formatted properly, enclose it in triple backticks (you can optionally specify a language for syntax highlighting).
|
Beta Was this translation helpful? Give feedback.
I think you may be missing that your systems can have multiple queries.
Side note: to get your code formatted properly, enclose it in triple backticks (you can optionally specify a language for syntax highlighting).