Search code examples
rustbevy

Rust / Bevy - Keep track of target


I have a Struct Enemy as well as a Struct Turret. The goal is once a turret spots an enemy, It should keep track of it, attacking it until it is either dead or out of sight.

I have a query

fn update_turrets(mut enemy_query: Query<(&mut Enemy, Entity)>, mut turret_query: Query<(&mut Turret)>) {
...
}

where I can find possible targets for a Turret. As mentioned, once a target has been found, the tower should lock it. Coming from C++ I would have stored a pointer/reference of the Enemy as member in the Turret Struct, thus i tried doing that

pub struct Turret {
    pub target: *mut Enemy,
}

This gives me the following error: *mut Enemy cannot be sent between threads safely which makes sense to me. Furthermore it looks like there is no way to "ignore" that as bevy seems to demands it.

Afterwards I tried to save the entity id as u32 as member in Turret instead and building a Hashmap HashMap<u32, *mut Enemy> at the beginning of each iteration but this seems to be very inefficient because I would have to rebuild that hashmap on each iteration.

What is the "rust-way" of solving this efficiently?


Solution

  • Don't try to keep a reference to a component. Keep a handle on the entity:

    pub struct Turret {
        pub target: Option<Entity>,
    }
    

    Then, if you need to access the Enemy component, you can access it by passing the entity handle to .get() on an enemy query.