- 0.7 至 0.8
- 相机驱动渲染
- 可见性继承、通用 ComputedVisibility 和 RenderLayers 支持
- 使用 Affine3A 作为 GlobalTransform 以允许任何仿射变换
- 添加 SceneBundle 以生成场景
- 使 ScalingMode 更灵活
- 允许在运行时关闭窗口
- 使 RunOnce 成为非手动系统实现
- 将 system_param 获取结构体移动到匿名作用域以避免命名冲突
- Task 不实现 Component
- 将时间功能拆分为 bevy_time
- 将 float_ord 从 bevy_core 移动到 bevy_utils
- 将 Rect 移动到 bevy_ui 并将其重命名为 UiRect
- 将 ElementState 重命名为 ButtonState
- 改进 RawWindowHandle 功能的文档和命名
- 从 crevice 迁移到 encase
- 使用 ShaderType 而不是 AsStd140 和 AsStd430
- 使暂停的计时器在 tick 时更新 just_finished
- 将默认的 Image FilterMode 更改为 Linear
- 移除 .system()
- 将 gamepad.rs 元组更改为普通结构体
- 移除 EntityMut::get_unchecked
- 用 ReadOnlyWorldQuery 替换 ReadOnlyFetch
- 修复 Or/AnyOf/Option 组件访问的 unsoundness
- 从 par_for_each(_mut) 中移除 task_pool 参数
- 在 16 位平台上无法编译
- 强制使用 Assets::get 的类型安全
- 允许高阶系统
- 向 TextureAtlas::from_grid_with_padding 添加了 offset 参数
- 拆分网格着色器文件
- 相机驱动视窗
- 诊断:当图形节点输入数量错误时,显示有意义的错误
- 使 Reflect 安全地实现
- 将 ECS 存储中的可变 API 标记为 pub(crate)
- 为所有新的 TaskPools 添加全局初始化和获取访问器
- 简化 *Labels 的设计
- 将 get_short_name 工具方法从 bevy_reflect 移动到 bevy_utils
- 移除已废弃的 SystemLabelMarker 结构体
- 添加资源的反射
- 使 reflect_partial_eq 返回更准确的结果
- 使 RenderStage::Extract 在渲染世界中运行
- 改进 Gamepad DPad 按钮检测
- 将窗口位置类型从元组更改为向量
- bevy_asset 的完整文档
- 层次结构命令化
- 移除对泛型类型上的 Reflect 的通用 Serialize + Deserialize 要求
- 更轻量级的无默认功能
- 改进创建文本元素的可用性和减少样板代码
- 添加 QueryState::get_single_unchecked_manual 及其系列
- tracing-tracy 从 0.8.0 更新到 0.10.0
迁移指南:0.7 至 0.8
在迁移之前,请确保运行 rustup update
Bevy 严重依赖 Rust 语言和编译器的改进。因此,最低支持的 Rust 版本 (MSRV) 为 Rust 的“最新稳定版本”。
相机驱动渲染 #
这是一个非常复杂的更改,建议阅读链接的 PR 以获取更多详细信息
// old 3d perspective camera
commands.spawn_bundle(PerspectiveCameraBundle::default())
// new 3d perspective camera
commands.spawn_bundle(Camera3dBundle::default())
// old 2d orthographic camera
commands.spawn_bundle(OrthographicCameraBundle::new_2d())
// new 2d orthographic camera
commands.spawn_bundle(Camera2dBundle::default())
// old 3d orthographic camera
commands.spawn_bundle(OrthographicCameraBundle::new_3d())
// new 3d orthographic camera
commands.spawn_bundle(Camera3dBundle {
projection: OrthographicProjection {
scale: 3.0,
scaling_mode: ScalingMode::FixedVertical(5.0),
..default()
}.into(),
..default()
})
UI 不再需要专用的相机。UiCameraBundle 已被移除。Camera2dBundle 和 Camera3dBundle 现在都默认将 UI 渲染为其自身渲染图的一部分。要禁用相机的 UI 渲染,请使用 UiCameraConfig 组件禁用它
commands
.spawn_bundle(Camera3dBundle::default())
.insert(UiCameraConfig {
show_ui: false,
..default()
})
// 0.7
camera.world_to_screen(transform, world_position);
// 0.8
camera.world_to_viewport(transform, world_position);
可见性继承、通用 ComputedVisibility 和 RenderLayers 支持 #
Visibility 现在以类似于 Transform 的方式传播到子元素中。层次结构的根元素现在必须包含 Visibility 和 ComputedVisibility 才能使可见性传播起作用。
SpatialBundle 和 VisibilityBundle 已被添加以方便使用。如果您之前使用的是 TransformBundle,现在您应该使用 SpatialBundle。
如果您之前将 Visibility::is_visible 作为精灵或灯光等的“实际可见性”读取,请改用 ComputedVisibility::is_visible()
// 0.7
fn system(query: Query<&Visibility>) {
for visibility in query.iter() {
if visibility.is_visible {
info!("found visible entity");
}
}
}
// 0.8
fn system(query: Query<&ComputedVisibility>) {
for visibility in query.iter() {
if visibility.is_visible() {
info!("found visible entity");
}
}
}
使用 Affine3A 作为 GlobalTransform 以允许任何仿射变换 #
GlobalTransform 字段已更改
- 用
global_transform.translation()替换global_transform.translation(对于其他字段,请使用compute_transform方法) GlobalTransform不再支持非线性缩放,如果您觉得不方便,请告诉我们- 如果您需要
scale、rotation或translation属性,您现在可以使用global_transform.to_scale_rotation_translation()
// 0.7
let transform = Transform::from(*global_transform);
transform.scale
transform.rotation
transform.translation
// 0.8
let (scale, rotation, translation) = global_transform.to_scale_rotation_translation();
添加 SceneBundle 以生成场景 #
// 0.7
commands.spawn_scene(asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"));
// 0.8
commands.spawn_bundle(SceneBundle {
scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
..Default::default()
});
场景将作为具有 SceneBundle 的实体的子元素生成
使 ScalingMode 更灵活 #
添加了为 WindowSize 指定缩放系数的功能,为 FixedVertical 和 FixedHorizontal 指定固定轴的大小,以及一种新的 ScalingMode,它是 FixedVertical 和 FixedHorizontal 的混合。
允许在运行时关闭窗口 #
bevy::input::system::exit_on_esc_system 已被移除。改用 bevy::window::close_on_esc。
CloseWindow 已被移除。改用 Window::close。Close 变体已添加到 WindowCommand 中。通过关闭相关窗口来处理它。
使 RunOnce 成为非手动系统实现 #
运行标准 RunOnce,它将使受控系统只运行一次,已被新的运行标准函数 ShouldRun::once 替换。将所有 RunOnce 实例替换为 ShouldRun::once。
将 system_param 获取结构体移动到匿名作用域以避免命名冲突 #
对于使用系统参数获取结构体的代码,例如 EventReader 的 EventReaderState,现在可以通过 SystemParam 特性关联类型 Fetch 来识别获取结构体,例如对于 EventReader<T>,可以将其识别为 <EventReader<'static, 'static, T> as SystemParam>::Fetch
Task 不实现 Component #
如果您需要 Task 成为 Component,则应使用包装类型。
// 0.7
fn system(mut commands: Commands, thread_pool: Res<AsyncComputeTaskPool>) {
let task = thread_pool.spawn(async move {
// Complicated async work
Vec2::ZERO
});
commands.spawn().insert(task);
}
// 0.8
#[derive(Component)]
struct ComputeVec2(Task<Vec2>);
fn system(mut commands: Commands) {
let thread_pool = AsyncComputeTaskPool::get();
let task = thread_pool.spawn(async move {
// Complicated async work
Vec2::ZERO
});
commands.spawn().insert(ComputeVec2(task));
}
将时间功能拆分为 bevy_time #
- 与时间相关的类型(例如
Time、Timer、Stopwatch、FixedTimestep等)应从bevy::time::*而不是bevy::core::*中导入。 - 如果您之前手动添加了
CorePlugin,您还需要从bevy::time添加TimePlugin。 bevy::core::CorePlugin::Time系统标签已被bevy::time::TimeSystem替换。
将 float_ord 从 bevy_core 移动到 bevy_utils #
将 bevy::core::FloatOrd 的导入替换为 bevy::utils::FloatOrd。
将 Rect 移动到 bevy_ui 并将其重命名为 UiRect #
Rect 类型已重命名为 UiRect。
将 ElementState 重命名为 ButtonState #
ElementState 类型已重命名为 ButtonState。
改进 RawWindowHandle 功能的文档和命名 #
将 HasRawWindowHandleWrapper 重命名为 ThreadLockedRawWindowHandleWrapper。
从 crevice 迁移到 encase #
使用 ShaderType 而不是 AsStd140 和 AsStd430 #
// old
#[derive(AsStd140)]
struct Foo {
a: Vec4,
b: Mat4,
}
// new
#[derive(ShaderType)]
struct Foo {
a: Vec4,
b: Mat4,
}
StorageBuffer #
- 移除
set_body()、values()、values_mut()、clear()、push()、append() - 添加
set()、get()、get_mut()
UniformVec -> UniformBuffer #
- 将
uniform_buffer()重命名为buffer() - 移除
len()、is_empty()、capacity()、push()、reserve()、clear()、values() - 添加
set()、get()
DynamicUniformVec -> DynamicUniformBuffer #
- 将
uniform_buffer()重命名为buffer() - 移除
capacity()、reserve()
使暂停的计时器在 tick 时更新 just_finished #
Timer::times_finished 已被重命名为 Timer::times_finished_this_tick 以提高清晰度。
将默认的 Image FilterMode 更改为 Linear #
默认的 Image 过滤从 Nearest 更改为 Linear。
// 0.7
// Nothing, nearest was the default
// 0.8
App::new()
.insert_resource(ImageSettings::default_nearest())
Image.sampler_descriptor 已更改为使用 ImageSampler 而不是 SamplerDescriptor。
// 0.7
texture.sampler_descriptor = SamplerDescriptor {
address_mode_u: AddressMode::Repeat,
address_mode_v: AddressMode::Repeat,
..default()
};
// 0.8
texture.sampler_descriptor = ImageSampler::Descriptor(SamplerDescriptor {
address_mode_u: AddressMode::Repeat,
address_mode_v: AddressMode::Repeat,
..default()
});
移除 .system() #
您不再可以使用 .system()。它在 0.7.0 中已被弃用。您可以直接移除方法调用。
如果您在测试中需要此功能,您可以改用 bevy_ecs::system::assert_is_system。
将 gamepad.rs 元组更改为普通结构体 #
Gamepad、GamepadButton、GamepadAxis、GamepadEvent 和 GamepadEventRaw 类型现在是普通结构体,而不是元组结构体,并且具有 new 函数。要进行迁移,请将所有实例化更改为使用 new() 函数,并使用相应的字段名称,而不是 .0 和 .1。
移除 EntityMut::get_unchecked #
将对 EntityMut::get_unchecked 的调用替换为对 EntityMut::get 的调用。
用 ReadOnlyWorldQuery 替换 ReadOnlyFetch #
ReadOnlyFetch 特性已被 ReadOnlyWorldQuery 替换,WorldQueryGats::ReadOnlyFetch 关联类型也被 <WorldQuery::ReadOnly as WorldQueryGats>::Fetch 替换
ReadOnlyFetch 特性已被 ReadOnlyWorldQuery 替换,WorldQueryGats::ReadOnlyFetch 关联类型也被 <WorldQuery::ReadOnly as WorldQueryGats>::Fetch 替换
- 任何诸如
QueryFetch<Q>: ReadOnlyFetch的 where 子句都应替换为Q: ReadOnlyWorldQuery。 - 任何自定义世界查询实现都应实现
ReadOnlyWorldQuery,而不是ReadOnlyFetch
函数 update_component_access 和 update_archetype_component_access 已从 FetchState 特性移动到 WorldQuery
- 任何调用者现在应调用
Q::update_component_access(state而不是state.update_component_access(以及update_archetype_component_access)。 - 任何自定义世界查询实现都应该将函数从
FetchState实现移到WorldQuery实现中。
WorldQuery已被设为unsafe trait,FetchState已被设为安全的trait。(我认为这应该是它一直以来的方式,但无论如何,现在这两个函数已经移到WorldQuery中,这绝对是必要的。)
- 如果您有自定义的
FetchState实现,请将其设为普通的impl,而不是unsafe impl。 - 如果您有自定义的
WorldQuery实现,请将其设为unsafe impl,如果您的代码之前是健全的,它将继续保持健全。
修复了使用Or/AnyOf/Option组件访问的健全性问题 #
已修复Or/AnyOf/Option的查询冲突,并使其更加严格,以避免未定义的行为。如果由于此更改导致新的查询冲突,则必须重构您的系统;考虑使用ParamSet。
从par_for_each(_mut)中删除task_pool参数 #
Query(State)::par_for_each(_mut)的task_pool参数已删除。从对这些函数的所有调用中删除这些参数。
// 0.7
fn parallel_system(
task_pool: Res<ComputeTaskPool>,
query: Query<&MyComponent>,
) {
query.par_for_each(&task_pool, 32, |comp| {
// ...
});
}
// 0.8
fn parallel_system(query: Query<&MyComponent>) {
query.par_for_each(32, |comp| {
// ...
});
}
如果在调度器运行的系统之外使用Query或QueryState,则可能需要在World中手动配置和初始化ComputeTaskPool作为资源。
在16位平台上无法编译 #
bevy_ecs现在将在16位平台上明确无法编译,因为它在这些平台上由于各种内部假设而无法正常工作。
目前没有替代方案,但我们欢迎添加支持。请提交问题以帮助详细说明您的用例。
强制使用Assets::get的类型安全用法 #
Assets::<T>::get和Assets::<T>::get_mut现在要求传递的句柄是Handle<T>,从而提高了句柄的类型安全性。如果您之前传递的是
HandleId,请改用&Handle::weak(id)来创建弱句柄。您可能已经能够存储一个类型安全的Handle。HandleUntyped,请使用&handle_untyped.typed_weak()来创建指定类型的弱句柄。这在使用load_folder时最有可能有用。&str或任何以前未提及的内容:assets.get(&assets.get_handle("asset/path.ron"))Handle<U>的不同类型,请考虑这是否是要存储的正确句柄类型。如果是(即,同一个句柄 ID 用于多个不同的资产类型),请使用Handle::weak(handle.id)来转换为不同的类型。
允许使用高阶系统 #
SystemParamFunction已更改。它之前不是公共 API 的一部分,因此不提供迁移说明。(它现在已包含在公共 API 中,但您仍然不应该为自己的类型实现此特征)。
如果可能,任何自定义System实现都应该迁移到使用高阶系统,高阶系统要显著地更不容易出错。
需要研究才能让它适用于更多情况。
在TextureAtlas::from_grid_with_padding中添加了offset参数 #
对TextureAtlas::from_grid_with_padding的调用应该修改为包含一个新参数,该参数可以设置为Vec2::ZERO以保留旧的行为。
// 0.7
from_grid_with_padding(texture, tile_size, columns, rows, padding)
// 0.8
from_grid_with_padding(texture, tile_size, columns, rows, padding, Vec2::ZERO)
拆分网格着色器文件 #
在用于 3D 网格的着色器中
#import bevy_pbr::mesh_view_bind_group->#import bevy_pbr::mesh_view_bindings#import bevy_pbr::mesh_struct->#import bevy_pbr::mesh_types- 注意:如果您在绑定组索引 2 处使用网格绑定组,您可以在着色器中删除这些绑定语句,只需使用
#import bevy_pbr::mesh_bindings,它本身会导入绑定所需的网格类型。
- 注意:如果您在绑定组索引 2 处使用网格绑定组,您可以在着色器中删除这些绑定语句,只需使用
在用于 2D 网格的着色器中
#import bevy_sprite::mesh2d_view_bind_group->#import bevy_sprite::mesh2d_view_bindings#import bevy_sprite::mesh2d_struct->#import bevy_sprite::mesh2d_types- 注意:如果您在绑定组索引 2 处使用 mesh2d 绑定组,您可以在着色器中删除这些绑定语句,只需使用
#import bevy_sprite::mesh2d_bindings,它本身会导入绑定所需的 mesh2d 类型。
- 注意:如果您在绑定组索引 2 处使用 mesh2d 绑定组,您可以在着色器中删除这些绑定语句,只需使用
相机驱动的视口 #
Camera::projection_matrix不再是公共字段。请改用新的Camera::projection_matrix()方法。
// 0.7
let projection = camera.projection_matrix;
// 0.8
let projection = camera.projection_matrix();
诊断:当图节点的输入数量错误时,显示有意义的错误 #
对RenderGraphRunnerError的穷尽匹配需要添加一个分支来处理新的MismatchedInputCount变体。
使Reflect安全地实现 #
- Reflect推导不应该需要更改任何内容。
- 手动反射实现需要删除
unsafe关键字,添加any()实现,并将旧的any和any_mut重命名为as_any和as_mut_any。 - 对
any/any_mut的调用必须更改为as_any/as_mut_any。
将ECS存储下的可变API标记为pub(crate) #
如果您遇到此更改导致的任何问题,请创建一个问题,详细说明您使用这些 API 的方式。
为所有新类型化的TaskPools添加全局初始化和获取访问器 #
线程池不再需要存储在资源中,因为它们现在存储在全局范围内。您现在可以使用get()来访问它。
// 0.7
fn spawn_tasks(thread_pool: Res<AsyncComputeTaskPool>) {
// Do something with thread_pool
}
// 0.8
fn spawn_tasks() {
let thread_pool = AsyncComputeTaskPool::get();
// Do something with thread_pool
}
简化*Labels的设计 #
- 任何之前对
Box<dyn SystemLabel>的使用都应该替换为SystemLabelId。 AsSystemLabel特征已修改。- 不再有输出泛型。
- 方法
as_system_label现在返回SystemLabelId,删除了不必要的间接级别。
- 如果您*需要*在运行时确定的标签,可以使用
Box::leak。不建议这样做。
将get_short_name实用程序方法从bevy_reflect移到bevy_utils #
- 添加了bevy_utils::get_short_name,它可以从类型名称中剥离路径,以方便显示。
- 删除了TypeRegistry::get_short_name方法。请改用bevy_utils中的函数。
删除已死的SystemLabelMarker结构体 #
此结构体在内部没有使用、文档或可直观理解的外部使用。
它已被删除。
为资源添加反射 #
将ReflectComponent::add_component重命名为ReflectComponent::insert_component。
使reflect_partial_eq返回更准确的结果 #
之前,所有reflect_***_partial_eq帮助器方法在无法执行比较时返回Some(false),这具有误导性。它们现在在无法执行比较时返回None。
使RenderStage::Extract在渲染世界中运行 #
ExtractRenderStage现在在渲染世界中运行(而不是像以前那样在主世界中运行)。您必须使用ExtractSystemParam才能在提取阶段访问主世界。Extract接受一个类型参数,该参数是任何系统参数(例如Res、Query等)。它将从主世界中提取此参数。请注意,Commands在Extract中不会正常工作 - 它目前会静默地不执行任何操作。
// 0.7
fn extract_clouds(mut commands: Commands, clouds: Query<Entity, With<Cloud>>) {
for cloud in clouds.iter() {
commands.get_or_spawn(cloud).insert(Cloud);
}
}
// 0.8
fn extract_clouds(mut commands: Commands, mut clouds: Extract<Query<Entity, With<Cloud>>>) {
for cloud in clouds.iter() {
commands.get_or_spawn(cloud).insert(Cloud);
}
}
您现在还可以使用正常的系统参数在Extract期间访问渲染世界的资源。
fn extract_assets(mut render_assets: ResMut<MyAssets>, source_assets: Extract<Res<MyAssets>>) {
*render_assets = source_assets.clone();
}
由于提取现在在渲染世界中运行,因此主世界中的Res<RenderWorld>的使用应该替换为渲染世界中的Res<MainWorld>的使用。
请注意,所有现有的提取系统都需要更新以匹配这种新的样式;即使它们当前可以编译,它们也不会按预期运行。如果未满足此要求,则会尽力发出警告。
改进游戏手柄方向键按钮检测 #
方向键输入不再可以作为轴访问。请改用游戏手柄按钮来访问它们。
将窗口位置类型从元组更改为向量 #
更改了以下字段
WindowCommand::SetWindowMode.resolution从(u32, u32)更改为UVec2WindowCommand::SetResolution.logical_resolution从(f32, f32)更改为Vec2
bevy_asset的完整文档 #
将FileAssetIo::get_root_path重命名为FileAssetIo::get_base_path
FileAssetIo::root_path()是root_path字段的获取器,而FileAssetIo::get_root_path返回资产根路径的父目录,该目录是可执行文件的目录,除非设置了CARGO_MANIFEST_DIR。此更改解决了这两个方法之间的歧义。
层次结构命令化 #
Parent和Children组件字段现在是私有的。
- 将
parent.0替换为parent.get() - 将
children.0替换为*children - 您不能再构造
Children或Parent组件,您可以将其用作权宜之计,这可能会引入一帧延迟。
#[derive(Component)]
pub struct MakeChildOf(pub Entity);
fn add_parent(
mut commands: Commands,
orphans: Query<(Entity, &MakeChildOf)>,
) {
for (child, MakeChildOf(parent)) in &orphans {
commands.entity(*parent).add_child(child);
commands.entity(child).remove::<MakeChildOf>();
}
}
删除泛型类型上Reflect的通用Serialize + Deserialize要求 #
对于Option<T>、Vec<T>、HashMap<K, V>等泛型类型,.register_type将不再插入ReflectSerialize和ReflectDeserialize类型数据。相反,您需要像这样为具体的泛型类型单独注册它们
.register_type::<Option<String>>()
.register_type_data::<Option<String>, ReflectSerialize>()
.register_type_data::<Option<String>, ReflectDeserialize>()
更轻量的无默认功能 #
在对bevy依赖项使用no-default-features时,bevy_asset和bevy_scene不再启用。
- 使用
no-default-features的 Bevy 箱子如果依赖于这些功能,则需要手动添加这些功能。
bevy = { version = "0.8", default-features = false, features = [
"bevy_asset",
"bevy_scene",
] }
改进创建文本元素的可用性和减少样板代码 #
Text::with_section已重命名为Text::from_section,不再接受TextAlignment作为参数。请改用with_alignment来设置对齐方式。
添加QueryState::get_single_unchecked_manual及其家族 #
将system::QuerySingleError更改为query::QuerySingleError
tracing-tracy 已从 0.8.0 更新至 0.10.0 #
使用 trace-tracy 功能时,现在需要 0.8.1 版本的 tracy。