5个版本 (稳定)
1.2.0 | 2024年7月20日 |
---|---|
1.1.1 | 2024年7月9日 |
1.1.0 | 2024年7月5日 |
1.0.0 | 2024年6月29日 |
0.8.0 | 2024年6月26日 |
#440 in 游戏开发
每月197次下载
18KB
266 行
简介
扩展了Bevy提供的Interaction
组件,通过跟踪更多状态以及这些状态是否刚刚进入或退出。这些状态都打包在BButtonBundle
组件中,可以通过查询这些组件或监听它们生成的事件来使用。
该库通过根据放置在旁边的Interaction
组件更新额外的按钮组件来工作,这确保了与Bevy本身的按钮行为保持一致。
只需将BButtonPlugin
添加到您的项目中,并使用BButtonBundle
而不是Bevy的ButtonBundle
即可开始。
教程
1. 设置
创建一个新的二进制crate,将bevy作为依赖项添加,并将以下代码复制到您的main.rs
use bevy::prelude::*;
use bevy::color::palettes::css::*;
fn main() {
App::new()
.add_plugins(
(
DefaultPlugins,
)
)
.add_systems(
Startup,
(
spawn_camera,
),
)
.run();
}
fn spawn_camera(mut commands: Commands) {
commands.spawn(
Camera3dBundle {
..default()
}
);
}
2. 添加BButtonPlugin
导入better_button
预处理器并添加BButtonPlugin
use bevy::prelude::*;
use bevy::color::palettes::css::*;
use better_button::prelude::*; // <------- Import the `better_button` prelude.
fn main() {
App::new()
.add_plugins(
(
DefaultPlugins,
BButtonPlugin // <------- Add the `BButtonPlugin` to the app.
)
)
.run();
}
这将为您的应用程序添加必要的系统,并注册按钮事件。
3. 创建BButtonBundle
BButtonBundle
包含Bevy的ButtonBundle
以及由better_button
crate提供的按钮组件。
创建一个新的系统来生成您的第一个BButtonBundle
fn spawn_button(mut commands: Commands) {
commands.spawn(BButtonBundle::new(
ButtonBundle {
style: Style
{
width: Val::Px(125.0),
height: Val::Px(125.0),
align_self: AlignSelf::Center,
justify_self: JustifySelf::Center,
..default()
},
background_color: BackgroundColor(WHITE.into()),
..default()
}
));
}
将其添加到您的Bevy应用程序中
fn main() {
App::new()
.add_plugins(
(
DefaultPlugins,
)
)
.add_systems(
Startup,
(
spawn_camera,
spawn_button // <------- Add the `spawn_button` system to the `Startup` schedule.
),
)
.run();
}
4. 在Update
中响应按钮按下
创建一个新的系统,当按钮被按下时改变其颜色
fn respond_to_button_state(
mut query: Query<(&BPressState, &mut BackgroundColor)>
) {
for (state, mut background_color) in &mut query {
if state.just_entered {
background_color.0 = YELLOW_GREEN.into();
}
if state.just_exited {
background_color.0 = WHITE.into();
}
}
}
该系统查询BPressState
组件,这是我们之前使用的BButtonBundle
的一部分。
现在将此系统添加到您的应用程序中,但请确保指定它应该在BButtonUpdateSet
之前或之后运行。这确保了您的系统在连续运行之间至少运行一次,因为Bevy中系统集和系统的运行顺序可能会从帧到帧发生变化。
fn main() {
App::new()
.add_plugins(
(
DefaultPlugins,
BButtonPlugin
)
)
.add_systems(
Startup,
(
spawn_camera,
spawn_button
),
)
.add_systems(
Update, // <------- Make sure it's in the `Update` schedule. The reason will be explained later.
respond_to_button_state.after(BButtonUpdateSet) // <------- Add the system, and set it to run after the `BButtonUpdateSet`.
)
.run();
}
4. 通过读取事件响应按钮按下
由于我们创建的按钮的状态组件在使用 BButtonPlugin
时在 Update
调度中更新,因此我们不能从 FixedUpdate
调度中的按钮组件查询中可靠地读取按钮按下。这是因为 BPressState
组件的 just_entered
和 just_exited
属性仅在 Update
调度中设置一次 true
。而且,由于在大多数情况下 Update
调度在每个 FixedUpdate
中运行多次,因此 just_entered
和 just_exited
属性可能在两个 FixedUpdate
帧之间设置为 true
然后再次设置为 false
。
这就是使用事件的时候,因为 Bevy 确保在事件消失之前,所有在 Update
和 FixedUpdate
中运行的系统都恰好接收到一次生成的任何事件。
创建一个新的系统,当鼠标悬停在按钮上时更改按钮的颜色,这次使用事件
fn respond_to_button_events(
mut query: Query<&mut BackgroundColor, With<BHoverState>>,
mut event_reader: EventReader<BHoverEvent>,
) {
for event in event_reader.read() {
match event {
BHoverEvent::JustEntered { entity } => {
if let Ok(mut background_color) = query.get_mut(*entity) {
background_color.0 = YELLOW_GREEN.into();
}
}
BHoverEvent::JustExited { entity } => {
if let Ok(mut background_color) = query.get_mut(*entity) {
background_color.0 = WHITE.into();
}
}
}
}
}
注释掉之前的系统,并将最新的系统添加到你的 Bevy 应用中的 FixedUpdate
调度中
fn main() {
App::new()
.add_plugins(
(
DefaultPlugins,
BButtonPlugin
)
)
.add_systems(
Startup,
(
spawn_camera,
spawn_button
),
)
// .add_systems(
// Update,
// respond_to_button_state.after(BButtonUpdateSet)
// )
.add_systems(
FixedUpdate,
respond_to_button_events, // <------- Add the `respond_to_button_events` system to `FixedUpdate`.
)
.run();
}
正如你可能已经注意到的,我们不需要指定新系统是在 BButtonUpdateSet
之前还是之后运行。如前所述,Bevy 确保所有系统恰好一次接收到它们读取的事件。因此,即使我们没有使用 .after(BButtonUpdateSet)
将我们的新系统添加到 Update
调度中,我们也可以确信它不会错过任何内容。
5. 结论
是否使用带有事件的 better_button
crate 或直接查询组件取决于你。这两种技术都有其优缺点。
一般来说,当在 Update
调度中工作时,与非游戏逻辑一起工作时直接查询按钮组件通常更容易。例如,更新按钮的视觉。另一方面,在 FixedUpdate
中工作时,使用事件是必要的。例如,使用按钮按下在移动设备上使角色跳跃。
接下来是什么?
请查看 Wiki 了解有关此库的更多信息。
依赖项
~23MB
~427K SLoC