-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to get component/components from a particular entity? #283
Comments
More info. My current solution is to pass a callback that gets called with the component reference, I need all this for a little game engine I work on: Relevant files are pub fn with_component<T: Component, F: FnOnce(&T)>(&self, f: F) {
if let Ok(entry) = self.world.borrow_mut().entry_ref(self.entity) {
if let Ok(component) = entry.get_component::<T>() {
f(component);
}
}
}
pub fn with_component_mut<T: Component, F: FnOnce(&mut T)>(&mut self, f: F) {
if let Ok(mut entry) = self.world.borrow_mut().entry_mut(self.entity) {
if let Ok(component) = entry.get_component_mut::<T>() {
f(component);
}
}
} And I use it like this when I want to draw some kind of egui UI for the component: self.square_entity
.with_component_mut::<SpriteRendererComponent, _>(|comp| {
ui.horizontal(|ui| {
ui.label("Color:");
let mut new_color = [
(comp.color.x * 255.0) as u8,
(comp.color.y * 255.0) as u8,
(comp.color.z * 255.0) as u8,
(comp.color.w * 255.0) as u8,
];
ui.color_edit_button_srgba_unmultiplied(&mut new_color);
comp.color = glam::vec4(
new_color[0] as f32 / 255.0,
new_color[1] as f32 / 255.0,
new_color[2] as f32 / 255.0,
new_color[3] as f32 / 255.0,
);
});
ui.separator();
}); I can live with this, but I would try to avoid the need to design for my self an API where I need to provide callbacks. |
Hi @DrOptix, However, have you considered the option of making your engine less object-oriented and more ECS-driven, meaning that most of the logic is written in systems? #[legion::system]
fn manual_creator(#[state] current_editable_entity: &mut Option<Entity>,
#[resource] mouse: &Mouse,
#[resource] factory: &EntityFactory,
#[resource] mouse_button_pressed: &Events<MouseButtonPressed>,
#[resource] mouse_button_released: &Events<MouseButtonReleased>,
commands: &mut CommandBuffer,
world: &mut SubWorld,
_dummy: &mut Query<(&Position, &mut Mass)>)
{
// pressing left mouse button initiates new entity creation
{
let should_create_new_entity = mouse_button_pressed
.iter()
.find(|MouseButtonPressed { button, .. }| *button == MouseButton::Left)
.is_some();
if should_create_new_entity {
if let Some(CursorState::InsideWindow { x, y }) = mouse.get_cursor_state() {
*current_editable_entity = Some(factory.create_blank(x, y, commands));
}
return;
}
}
// releasing left mouse button finalizes entity creation
{
let should_finalize_creation = mouse_button_released
.iter()
.find(|MouseButtonReleased { button, .. }| *button == MouseButton::Left)
.is_some();
if should_finalize_creation {
factory.finalize_creation(current_editable_entity.take().unwrap(), commands, world);
return;
}
}
// moving the mouse cursor updates the mass for the current editable entity (if any)
if current_editable_entity.is_some() {
if let Some(CursorState::InsideWindow { x, y}) = mouse.get_cursor_state() {
let mut entry = world.entry_mut(*current_editable_entity.as_ref().unwrap()).unwrap();
let position = entry.get_component::<Position>().unwrap().clone();
let mass = entry.get_component_mut::<Mass>().unwrap();
let distance_from_center = (position.0 - Vec2::new(x, y)).magnitude();
*mass = radius_to_mass(distance_from_center);
}
}
} |
I browsed the docs, but I could not figure out for myself.
I know we have queries that will let us go trough all the components of type
C
from a world, but is there a way to get a component of type C from a particular entity?Actually I'm interested in getting references
&T
and&mut T
to the component attached to a particular entity.I tried to do something like:
but then it complained that the reference I return does not live long enough.
I want something like this because I just want
&T
or&mut T
to the component, why do we need to deal with thatentry
step? :-(Thank you!
The text was updated successfully, but these errors were encountered: