17个版本 (9个重大更新)
| 10.0.0 | 2024年2月19日 |
|---|---|
| 9.0.0 | 2023年11月4日 |
| 8.0.0 | 2023年8月30日 |
| 7.0.0 | 2023年7月9日 |
| 1.2.0 | 2022年3月22日 |
#421 在 游戏开发
每月183 次下载
用于 6 个crate(直接使用2个)
39KB
197 行
Bevy Scene hook
在Bevy游戏引擎中,向通过场景(例如gltf文件)创建的实体中(例如)即时添加组件的示例。
如果你不介意在代码中添加这样的小型依赖项而不是将代码作为模块粘贴,你可以在crates.io中获取它。
用法
- 将crate添加到依赖项中
[dependencies]
bevy-scene-hook = "10.0.0"
- 添加插件
.add_plugins(HookPlugin)
示例
use bevy::prelude::*;
use bevy_scene_hook::{SceneHook, HookedSceneBundle};
enum PileType { Drawing }
#[derive(Component)]
struct Pile(PileType);
#[derive(Component)]
struct Card;
fn load_scene(mut cmds: Commands, asset_server: Res<AssetServer>) {
cmds.spawn(HookedSceneBundle {
scene: SceneBundle { scene: asset_server.load("scene.glb#Scene0"), ..default() },
hook: SceneHook::new(|entity, cmds| {
match entity.get::<Name>().map(|t|t.as_str()) {
Some("Pile") => cmds.insert(Pile(PileType::Drawing)),
Some("Card") => cmds.insert(Card),
_ => cmds,
};
}),
});
}
在游戏开始时加载scene.glb文件。当场景完全加载后,将向场景中每个实体传递到SceneHook::new中的闭包。我们将一个Pile组件添加到具有Name组件值为"Pile"的实体。
在blender中,您可以使用Outliner窗口(右上角的树形视图)双击对象名称来在glb场景中命名对象。
请注意,SceneHook钩子一次只能访问一个EntityRef和EntityCommands,并忽略资源重新加载。
考虑使用此crate的reload::Hook来处理更复杂的用例。
实现
bevy-scene-hook是一个小巧的crate,以下是你可以直接在项目中使用的可粘贴代码
use bevy::{
prelude::*,
scene::SceneInstance,
ecs::{world::EntityRef, system::EntityCommands},
};
#[derive(Component, Debug)]
pub struct SceneHooked;
#[derive(Component)]
pub struct SceneHook {
hook: Box<dyn Fn(&EntityRef, &mut EntityCommands) + Send + Sync + 'static>,
}
impl SceneHook {
pub fn new<F: Fn(&EntityRef, &mut EntityCommands) + Send + Sync + 'static>(hook: F) -> Self {
Self { hook: Box::new(hook) }
}
}
pub fn run_hooks(
unloaded_instances: Query<(Entity, &SceneInstance, &SceneHook), Without<SceneHooked>>,
scene_manager: Res<SceneSpawner>,
world: &World,
mut cmds: Commands,
) {
for (entity, instance, hooked) in unloaded_instances.iter() {
if scene_manager.instance_is_ready(**instance) {
cmds.entity(entity).insert(SceneHooked);
}
let entities = scene_manager
.iter_instance_entities(**instance)
.chain(std::iter::once(entity));
for entity_ref in entities.filter_map(|e| world.get_entity(e)) {
let mut cmd = cmds.entity(entity_ref.id());
(hooked.hook)(&entity_ref, &mut cmd);
}
}
}
pub struct HookPlugin;
impl Plugin for HookPlugin {
fn build(&self, app: &mut App) { app.add_systems(Update, run_hooks); }
}
请注意,bevy-scene-hook还定义了一些用于用户方便的项
HookedSceneBundleHookedSceneStateis_scene_hooked
这些额外的项都在lib.rs中定义。
变更日志
1.1.0:向SceneInstance添加is_loaded方法1.2.0:添加包含具有独占世界访问权限的SceneHook特质的world模块。如果您想访问资源,例如,这很有用。2.0.0:破坏性更改:将 bevy 版本提升到0.7(您应该能够在不更改代码的情况下从1.2.0升级)3.0.0:破坏性更改:完全重构了 crate。- 移除了
world模块,因为基本钩子方法变得非常强大。 - 将
SceneHook重命名为Hook,现在Hook有一个独特的实现方法。 - 现在您不需要自己添加任何系统,您需要将
HookPlugin插件添加到您的应用程序中。 - 将 API 独家移动到新的
SystemParam:HookingSceneSpawner。请使用该参数添加和删除包含钩子的场景。(如果您不小心将其拼写为HonkingSceneSpawner两次以上,请告诉我 🦆) - 将
when_spawned运行条件移动到 crate 根处的is_scene_hooked函数、HookedSceneState系统参数或SceneLoaded组件。请使用这三个中的任何一个而不是when_spawned。 - 现在支持将闭包作为钩子传递,而不是每次都要定义一个特质。
- 现在支持添加多个相同的场景!不处理热重载,但这没关系,因为 bevy 的场景热重载目前是损坏的 :D
- 移除了
3.1.0:将run_hooks系统公开,以便您可以将其添加到您想要添加的任何阶段,与任何其他系统相关联。4.0.0:破坏性更改:将 bevy 版本提升到0.8- 使用新的场景包系统
- 将
SceneLoaded重命名为SceneHooked。 - 移除了
Hook特质,现在SceneHook::new接受闭包。 - 而不是使用
HookingSceneSpawner,使用HookedSceneBundle并将其实例化到实体中。
4.1.0:添加HookedDynamicSceneBundle以与DynamicScene一起使用。感谢 Shatur (https://github.com/nicopap/bevy-scene-hook/pull/3)5.0.0:破坏性更改:将 bevy 版本提升到0.95.1.1:我的失误,不小心发布到了版本5.1.0,而不是5.0.05.1.2:修复了由于缺少检查而导致场景从未触发钩子的问题。感谢 sdfgeoff (#5) 如果你将bevy-scene-hook作为 cargo 依赖项,必须运行cargo update以获取此修复。5.2.0:添加了reload模块,定义了reload::Hook,它是SceneHook的一个变体,可以优雅地处理重新加载和卸载。6.0.0:破坏性更改:将 bevy 版本提升到0.107.0.0:破坏性更改:将 bevy 版本提升到0.118.0.0:将场景的根实体添加到遍历场景实体列表中。- 如果你将组件批量添加到实体中并且依赖于根不包含它们,则可能会破坏。
- 还可能是在添加组件时测试根的属性。
- 感谢 ickk (https://github.com/nicopap/bevy-scene-hook/pull/7)
9.0.0:破坏性更改:将 bevy 版本提升到0.12- 将
hook函数移动到SpawnScene调度中
- 将
10.0.0:破坏性更改:将 bevy 版本提升到0.13- 移除
file_pathreload::Hook字段,转而使用Handle::path方法。 - 添加示例并测试 Readme。
- 移除
版本矩阵
| bevy | 最新支持的版本 |
|---|---|
| 0.13 | 10.0.0 |
| 0.12 | 9.0.0 |
| 0.11 | 8.0.0 |
| 0.10 | 6.0.0 |
| 0.9 | 5.2.0 |
| 0.8 | 4.1.0 |
| 0.7 | 3.1.0 |
| 0.6 | 1.2.0 |
许可证
本库采用 Apache 2.0 许可。
依赖项
~22–56MB
~1M SLoC