没有多按钮系统的多按钮?
Multiple buttons without multiple button systems?
我对 rust 和 bevy 都比较陌生。我意识到现在还处于早期阶段,并且非常喜欢 bevy,但坦率地说,我发现示例和文档有点缺乏。
我使用 /examples/ui/button.rs
作为起点。我想添加一堆按钮而不是一个。
我正在寻找一种方法来区分单击了哪个按钮。
我知道我可以为每个按钮添加一个系统,但这在任何语言中都不是正确的方法。
所以,我开始添加标记(就像 bevy-cheatsheet 所建议的那样)。
commands
.spawn(ButtonComponents { /* cut for brevity */ })
.with_children(|parent| {
parent
.spawn(TextComponents { /* cut for brevity */ })
.with(Marker1);
});
但是我该如何检查生成按钮的标记?
fn button_system(
button_materials: Res<ButtonMaterials>,
mut interaction_query: Query<(
&Button,
Mutated<Interaction>,
&mut Handle<ColorMaterial>,
&Children,
)>,
text_query: Query<&mut Text>,
) {
for (_button, interaction, mut material, children) in &mut interaction_query.iter() {
let mut text = text_query.get_mut::<Text>(children[0]).unwrap();
match *interaction {
Interaction::Clicked => {
// This obviously doesn't work, just to illustrate what I'm looking for.
match text.spawned_with {
Marker1 => doSomething(),
Marker2 => doBarrelRoll(),
_ => unreachable!()
}
}
Interaction::Hovered => {
text.value = "Hover".to_string();
*material = button_materials.hovered.clone();
}
Interaction::None => {
text.value = "Button".to_string();
*material = button_materials.normal.clone();
}
}
}
}
欢迎任何提示,谢谢!
编辑:现在我很困惑,因为这实际上适用于按钮 1,(但会使按钮 2 崩溃):
Interaction::Clicked => {
let marker = text_query.get::<_>(children[0]).unwrap();
match *marker {
Marker1 => println!("marker 1"),
_ => unreachable!(),
}
}
但这甚至无法构建:
let marker = text_query.get::<_>(children[0]).unwrap();
match *marker {
Marker1 => println!("marker 1"),
Marker2 => println!("marker 2"),
_ => unreachable!(),
}
这是错误:
| expected struct `Marker1`, found struct `Marker2`
| `Marker2` is interpreted as a unit struct, not a new binding
| help: introduce a new binding instead: `other_marker2`
好的,我找到了答案,但如果您有更优雅的答案,我很乐意学习并改成正确答案!
Interaction::Clicked => {
if let Ok(_) = text_query.get::<Marker1>(children[0]) {
println!("marker 1")
}
if let Ok(_) = text_query.get::<Marker2>(children[0]) {
println!("marker 2")
}
if let Ok(_) = text_query.get::<Marker3>(children[0]) {
doBarrelRoll()
}
...
}
在 daniel kullmans 的评论之后,我得到了这样的结果:
#[derive(PartialEq)] // needed for comparison
pub enum Buttons {
MyFirstButton,
MySecondButton,
}
struct MyButton {
target: Buttons,
}
还有...
commands
.spawn(ButtonComponents { /* cut for brevity */ })
.with_children(|parent| {
parent
.spawn(TextComponents { /* cut for brevity */ })
.with(MyButton { target: Buttons });
});
还有...
Interaction::Clicked => {
if let Ok(btn) = text_query.get_mut::<MyButton>(children[0]) {
match btn.target {
Buttons::MyFirstButton => {
...
},
Buttons::MySecondButton => {
...
},
_ => unreachable!(),
}
}
}
我对 rust 和 bevy 都比较陌生。我意识到现在还处于早期阶段,并且非常喜欢 bevy,但坦率地说,我发现示例和文档有点缺乏。
我使用 /examples/ui/button.rs
作为起点。我想添加一堆按钮而不是一个。
我正在寻找一种方法来区分单击了哪个按钮。
我知道我可以为每个按钮添加一个系统,但这在任何语言中都不是正确的方法。
所以,我开始添加标记(就像 bevy-cheatsheet 所建议的那样)。
commands
.spawn(ButtonComponents { /* cut for brevity */ })
.with_children(|parent| {
parent
.spawn(TextComponents { /* cut for brevity */ })
.with(Marker1);
});
但是我该如何检查生成按钮的标记?
fn button_system(
button_materials: Res<ButtonMaterials>,
mut interaction_query: Query<(
&Button,
Mutated<Interaction>,
&mut Handle<ColorMaterial>,
&Children,
)>,
text_query: Query<&mut Text>,
) {
for (_button, interaction, mut material, children) in &mut interaction_query.iter() {
let mut text = text_query.get_mut::<Text>(children[0]).unwrap();
match *interaction {
Interaction::Clicked => {
// This obviously doesn't work, just to illustrate what I'm looking for.
match text.spawned_with {
Marker1 => doSomething(),
Marker2 => doBarrelRoll(),
_ => unreachable!()
}
}
Interaction::Hovered => {
text.value = "Hover".to_string();
*material = button_materials.hovered.clone();
}
Interaction::None => {
text.value = "Button".to_string();
*material = button_materials.normal.clone();
}
}
}
}
欢迎任何提示,谢谢!
编辑:现在我很困惑,因为这实际上适用于按钮 1,(但会使按钮 2 崩溃):
Interaction::Clicked => {
let marker = text_query.get::<_>(children[0]).unwrap();
match *marker {
Marker1 => println!("marker 1"),
_ => unreachable!(),
}
}
但这甚至无法构建:
let marker = text_query.get::<_>(children[0]).unwrap();
match *marker {
Marker1 => println!("marker 1"),
Marker2 => println!("marker 2"),
_ => unreachable!(),
}
这是错误:
| expected struct `Marker1`, found struct `Marker2`
| `Marker2` is interpreted as a unit struct, not a new binding
| help: introduce a new binding instead: `other_marker2`
好的,我找到了答案,但如果您有更优雅的答案,我很乐意学习并改成正确答案!
Interaction::Clicked => {
if let Ok(_) = text_query.get::<Marker1>(children[0]) {
println!("marker 1")
}
if let Ok(_) = text_query.get::<Marker2>(children[0]) {
println!("marker 2")
}
if let Ok(_) = text_query.get::<Marker3>(children[0]) {
doBarrelRoll()
}
...
}
在 daniel kullmans 的评论之后,我得到了这样的结果:
#[derive(PartialEq)] // needed for comparison
pub enum Buttons {
MyFirstButton,
MySecondButton,
}
struct MyButton {
target: Buttons,
}
还有...
commands
.spawn(ButtonComponents { /* cut for brevity */ })
.with_children(|parent| {
parent
.spawn(TextComponents { /* cut for brevity */ })
.with(MyButton { target: Buttons });
});
还有...
Interaction::Clicked => {
if let Ok(btn) = text_query.get_mut::<MyButton>(children[0]) {
match btn.target {
Buttons::MyFirstButton => {
...
},
Buttons::MySecondButton => {
...
},
_ => unreachable!(),
}
}
}