I was wondering, we can query different component etc... But is it possible to make query with implementation?
In my game, i try to make a solar system, so to recreate attraction etc... But doing it for every items is quite consuming. Isn't it possible to create a trait (like gravity trait), create a impl for each (which can be different obvisouly). And next call a system which would call all item with that trait, and calcul there gravity?
#Can we query impl?
28 messages · Page 1 of 1 (latest)
Yes, have you seen the derive for the WorldQuery (or SystemParam) trait?
Thx, i look into it
Hum i think it's the right thing, but i find it quite hard to understand:
struct LittleObject;
#[derive(Component, Default)]
struct Planet;
#[derive(Component, Default)]
struct Star;
#[derive(WorldQuery)]
#[world_query(derive(Debug))]
struct GravityQuery<T: Component + Gravity>{
graivity: T,
};
trait Gravity {
fn calcul_gravity(&self, big_pos:&Vec3, pos:&Vec3, mass:f32, big_mass:f32 ) -> Vec3{
let direction = *big_pos - *pos;
let distance_squared = pos.distance_squared(*big_pos);
return ((mass * big_mass ) /distance_squared) * direction;
}
}
impl Gravity for Star {
fn calcul_gravity(&self, big_pos:&Vec3, pos:&Vec3, mass:f32, big_mass:f32 ) -> Vec3 {
todo!();
}
}
impl Gravity for Planet {
fn calcul_gravity(&self, big_pos:&Vec3, pos:&Vec3, mass:f32, big_mass:f32 ) -> Vec3 {
todo!();
}
}
impl Gravity for LittleObject {
fn calcul_gravity(&self, big_pos:&Vec3, pos:&Vec3, mass:f32, big_mass:f32 ) -> Vec3 {
todo!();
}
}
In the sample above, you can see i've my gravity impl and i would like a query which retrieve all the object with Component with gravity. ( And if i could retrieve in the same time Transform and some other bevy component, it would be really cool)
But i don't really understand how i have to fill the struct (world_query) to do so?
hmmm
are calcul_gravity necessarily going to be different for each body (star, planet, little object)
it seems to me you are approaching the problem with a solution that isn't really suited for this one
have you seen this example for simulating bodies in space? https://github.com/bevyengine/bevy/blob/main/examples/ecs/iter_combinations.rs
here is the example proper
I'm going to look at that, it's definitely interesting yes. Maybe i'm not taking things correctly.
But in case i need it (one day), how should i fill my
struct GravityQuery to retrieve all entities which have a component that implement this?
currently you can't. this requires trait queries, which is a hotly debated topic in ecs-dev (afaik it's because it has few found use cases and has worse performance theoretically)
Ok that answer my question. I'm going to look at the example you send 🙂
turns out there is a crate (although very experimental) https://crates.io/crates/bevy-trait-query
imo you should just make Star, Planet, and LittleObject an enum, or a struct
https://bevyengine.org/examples/ecs/iter-combinations/ in this example, both interact_bodies and integrate have mutable access to acceleration. looks like they run in parallel. won't the two mutable queries in those systems conflict with each other? looks like it should run interact bodies first, accumulate acceleration, then integrate, no?
you should make a new help post instead of necroing 🙂
also they are not run in parallel because they have mutable access to acceleration. bevy ecs knows this and adjust accordingly
Sorry! I'm learning by reading all help posts as they come up. I followed the link above and got confused how it's supposed to work given that both systems are in a parallel set so it looks as if they run in parallel but that obviously is not the intention.
So if I have 2 systems that have mutable access to a component, they will always execute one after the other? Is the order undefined, or is it simply the order in which they were added?
The order is fully nondeterministic in that case
Thanks, I thought as much. But that means that in this example it's possible for the two systems execute out of order, resulting in a weird behaviour. Integrate executes first (does nothing since there's no acceleration), then interact bodies updates acceleration, then the frame ends; in the next frame, interact bodies happens to execute first, doubling the acceleration, then integrate runs and the bodies accelerate twice as fast as they should.
Is it idiomatic to simply specify .after(interact bodies) in this case?
Yep!
In fact, we should do this. Want to open a PR?