You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've got a question about how to properly and logically create, manage, and interact with object structures in Bevy.
The idea I tried to implement is to create simple Components responsible for simple tasks. These components know how they should look like. When added to the world, they automatically add all the necessary components.
But, it didn't quite work out. Here's a simple code example:
#[derive(Debug,Component)]pubstructStrengthBar{pubmax_strength:u32,pubcurrent_strength:u32,}// Initialization of UIpubfnsetup_ui(mutcommands:Commands,asset_server:Res<AssetServer>){
...parent.spawn((StrengthBar{max_strength:10,current_strength:8,},
...));
...}// After spawn, create UI for StrengthBarpubfnon_create_strength_bar(query:Query<(Entity,&StrengthBar),Added<StrengthBar>>,mutcommands:Commands,){for(entity, strength_bar)in query.iter(){letmut parent = commands.entity(entity);
parent
.insert(NodeBundle{style:Style{width:Val::Auto,height:Val::Auto,flex_direction:FlexDirection::Row,column_gap:Val::Px(4.0),padding:UiRect::all(Val::Px(2.0)),border:UiRect::all(Val::Px(1.0)),
..default()},background_color:BackgroundColor(...),border_color:BorderColor(...),border_radius:BorderRadius::all(Val::Px(8.0)),
..default()}).with_children(|parent| {for i in0..strength_bar.max_strength{// we spawn StrengthIndicator whom will create NodeBundle by itself
parent.spawn(StrengthIndicator{visible: i < strength_bar.current_strength});}});}}// After change, we just update indicator parameters, without access to its Visibilitypubfnon_change_strength_bar(query:Query<(&StrengthBar,&Children),Changed<StrengthBar>>,mutquery_indicators:Query<&mutStrengthIndicator>,){for(strength_bar, child_indicator)in&mut query.iter(){letmut strength = strength_bar.current_strength;for child_i in child_indicator.iter(){ifletOk(mut child_indicator) = query_indicators.get_mut(*child_i){
child_indicator.visible = strength > 0;
strength = strength.saturating_sub(1);}}}}
I'm trying to work with the indicators in a similar way:
#[derive(Debug,Component)]pubstructStrengthIndicator{pubvisible:bool,}pubfnon_create_strength_indicator(query:Query<(Entity,&StrengthIndicator),Added<StrengthIndicator>>,mutcommands:Commands,){// Length of the indicatorfor(entity, indicator)in query.iter(){letmut parent = commands.entity(entity);
parent
.insert(NodeBundle{style:Style{width:Val::Px(28.0),height:Val::Px(28.0),border:UiRect::all(Val::Px(2.0)),
..default()},border_color:BorderColor(...),border_radius:BorderRadius::all(Val::Px(5.5)),background_color:BackgroundColor(...),visibility:if indicator.visible{Visibility::Visible}else{Visibility::Hidden},
..default()});}}pubfnon_change_strength_indicator(mutquery:Query<(&StrengthIndicator,&mutVisibility),Changed<StrengthIndicator>,>,){for(indicator,mut visibility)in&mut query.iter_mut(){*visibility = if indicator.visible{Visibility::Visible}else{Visibility::Hidden};}}
The main idea of this approach is that the component is responsible for rendering itself. It monitors its state and only changes its appearance when it's updated. Other components only change this component's parameters. The component itself modifies how it looks on the screen based on its parameters.
The real issues start when I try to find the right sequence for .add_systems.
The first problem I encountered is that an object doesn't always trigger Added or Changed.
For example, when running in parallel, Added<StrengthIndicator> doesn't trigger at all (probably disappears by the frame's end):
Is it possible that I'm heading in the wrong direction since I'm a beginner? Can you suggest a better approach?
I understand that it's possible to specify dependencies for each component using .before(). In a large project, there could be a lot of such dependencies, and you might end up with a recursive dependency, which would not end well. Manually specifying each dependency is also quite tedious.
In general, I would like a reliable system for tracking Added and Changed. Perhaps I just have lack of experience...
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I've got a question about how to properly and logically create, manage, and interact with object structures in Bevy.
The idea I tried to implement is to create simple Components responsible for simple tasks. These components know how they should look like. When added to the world, they automatically add all the necessary components.
But, it didn't quite work out. Here's a simple code example:
I'm trying to work with the indicators in a similar way:
The main idea of this approach is that the component is responsible for rendering itself. It monitors its state and only changes its appearance when it's updated. Other components only change this component's parameters. The component itself modifies how it looks on the screen based on its parameters.
The real issues start when I try to find the right sequence for
.add_systems
.The first problem I encountered is that an object doesn't always trigger
Added
orChanged
.For example, when running in parallel,
Added<StrengthIndicator>
doesn't trigger at all (probably disappears by the frame's end):It's necessary to specify
.chain()
, for example, in this example:Only then everything renders correctly.
A few questions come to mind:
.before()
. In a large project, there could be a lot of such dependencies, and you might end up with a recursive dependency, which would not end well. Manually specifying each dependency is also quite tedious.Added
andChanged
. Perhaps I just have lack of experience...Beta Was this translation helpful? Give feedback.
All reactions