当前位置: 首页 > news >正文

Rust Bevy 0.13 到 0.14 升级踩坑指南

🚨 重要提醒

本文记录将一个 Bevy 0.13 的 2D 像素游戏升级到 0.14 版本的全过程踩坑记录。0.14 是作者在 macOS 上运行最稳定的版本(更高版本会出现黑屏问题),因此锁定此版本。升级后,还顺手将项目中从 Python 迁移过来的两个模块(调试控制台和剧本系统)进行了补充。

一、为什么是 0.14

  • macOS 兼容性:0.15 及以上版本在 macOS 上存在黑屏问题,0.14 是目前最稳定的选择。
  • 破坏性变更:0.13 → 0.14 存在破坏性 API 变更,不能仅仅修改 Cargo.toml 中的版本号。

二、Cargo.toml 的三处改动

1. 版本号

# before bevy = { version = "0.13", default-features = false, features = [...] } after bevy = { version = "0.14", default-features = false, features = [...] }

2. feature 名改了下划线大小写

# 0.13 用 hyphen-case "multi-threaded", 0.14 改成 snake_case "multi_threaded",

运行cargo fetch会直接报错:

package depends on `bevy` with feature `multi-threaded` but `bevy` does not have that feature. help: there is a feature `multi_threaded` with a similar name

按照提示修改即可。

3. 诊断插件 feature 改了名

# 0.13 "bevy_diagnostic", # ❌ 0.14 没这个 feature 0.14 "bevy_dev_tools", # ✅ FrameTimeDiagnosticsPlugin 跟着这个来

报错会列出全部可用 feature,从里面挑选即可。

4. 显式加 bevy_state / bevy_app 依赖

这是default-features = false项目的专属坑——详见下一节。

三、State API:最大的坑

症状

升级后一编译就刷出一屏幕错误:

error: cannot find derive macro `States` in this scope error[E0425]: cannot find type `NextState` in this scope error[E0425]: cannot find function `in_state` in this scope error[E0425]: cannot find `OnEnter` / `OnExit` error[E0599]: no method named `init_state` found for `&mut App` error[E0599]: no method named `enable_state` found for `&mut App`

根因

0.14 把 state 系统移出了bevy::prelude,迁移到了独立的 cratebevy_statebevy通过bevy_internal重命名 re-export:

// bevy_internal/src/lib.rs #[cfg(feature = "bevy_state")] pub use bevy_state as state;

所以bevy::state这条路径理论上还在,但需要开启bevy_statefeature。而我们使用了default-features = false,默认的 feature 集被砍掉了——0.13 时 state 跟着 prelude 走,0.14 必须显式开启。

解法(三步)

第一步:Cargo.toml 开 feature + 加依赖

bevy = { version = "0.14", default-features = false, features = [ ..., "bevy_state", # 激活 bevy::state re-export ] } 单开 bevy_state feature 还不够,AppExtStates(含 init_state)在 bevy_state::app 里, 它 use bevy_app::{App, ...}。所以要把 bevy_app 也拉进依赖图。 bevy_state = "0.14" bevy_app = "0.14"

第二步:import 路径全部改走bevy_state

// ❌ 0.13:靠 prelude 自动可用 #[derive(States, Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] pub enum GameState { ... } .add_systems(OnEnter(GameState::Playing), ...) .add_systems(Update, foo.run_if(in_state(GameState::Playing))) .next_state.set(GameState::GameOver);
// ✅ 0.14:全部 explicit import use bevy_state::app::AppExtStates; // 含 init_state use bevy_state::state::{OnEnter, OnExit, States, NextState}; use bevy_state::condition::in_state;

每个用到NextState的文件都要加一行:

use bevy_state::state::NextState;

第三步:删掉enable_state调用

// ❌ 0.13 写法 .init_state::<GameState>() .enable_state::<GameState>() // 0.14 砍了这方法
// ✅ 0.14:init_state 单独够用(内部已 setup transitions) .init_state::<GameState>()

验证路径是否正确的最小用例

升级时我先在/tmp里创建一个小的 cargo 项目验证 import 路径,再回主项目修改:

use bevy::prelude::*; use bevy_state::app::AppExtStates; use bevy_state::state::{OnEnter, OnExit, States, NextState}; use bevy_state::condition::in_state; #[derive(States, Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] pub enum S { #[default] A, B } fn main() { App::new() .init_state::<S>() .add_systems(OnEnter(S::A), || {}) .add_systems(OnExit(S::A), || {}) .add_systems(Update, (|| {}).run_if(in_state(S::A))) .run(); }

运行cargo check通过后再回主项目批量修改——比直接在主项目里试错快得多。

AppExtStates 的可用方法(0.14)

enable_state被砍掉之后,我查阅了bevy_state::app::AppExtStates的完整方法表,确认 0.14 只剩这些:

方法用途
init_state::<S>()初始化一个 State(取代 0.13 的 init_state + enable_state 组合)
insert_state::<S>(state)初始化并设初值
add_computed_state::<S>()计算状态
add_sub_state::<S>()子状态
enable_state_scoped_entities::<S>()state scoped entity 自动清理

四、Mesh::from(shape::Circle) 的 shape 模块消失

症状

error[E0433]: cannot find module or crate `shape` in this scope

根因

0.13 的bevy::sprite::shape::Circle { radius, vertices }在 0.14 被移走了。0.14 把几何图元迁移到了bevy_math::primitives,且Circle结构体砍掉了vertices字段,只剩radius

// bevy_math 0.14 pub struct Circle { pub radius: f32, }

解法

// ❌ 0.13 use bevy::prelude::*; // shape 跟着 prelude 走 let mesh = meshes.add(Mesh::from(shape::Circle { radius: 32.0, vertices: 32 })); // ✅ 0.14:显式 import + 去掉 vertices 字段 use bevy::math::primitives::Circle; let mesh = meshes.add(Mesh::from(Circle { radius: 32.0 })); // From<Circle> for Mesh 仍存在,默认 32 分辨率

如果想要自定义分辨率,用 builder 链:

use bevy::math::primitives::Circle; use bevy::render::mesh:: primitives::Meshable; // trait .mesh() let mesh = meshes.add(Circle { radius: 32.0 }.mesh().resolution(64).build());

五、Color 分量访问:.r() .g() .b() .a() 全砍

症状

error[E0599]: no method named `r` found for struct `Color` in the current scope error[E0599]: no method named `g` found for struct `Color` in the current scope error[E0599]: no method named `b` found for struct `Color` in the current scope error[E0599]: no method named `a` found for struct `Color` in the current scope

根因

0.13 的Color提供了.r(),.g(),.b(),.a()等 getter 方法。0.14 将这些方法全部移除,改为直接访问结构体字段。

解法

// ❌ 0.13 let color = Color::rgb(0.5, 0.2, 0.8); let red = color.r(); let alpha = color.a(); // ✅ 0.14:直接访问字段 let color = Color::rgb(0.5, 0.2, 0.8); let red = color.r; let alpha = color.a;

注意:Color的字段是公开的,可以直接读写。

六、其他常见变更与修复

1. 输入系统:KeyCode 枚举成员重命名

部分KeyCode枚举成员在 0.14 中被重命名,以符合更标准的命名约定。

// ❌ 0.13 KeyCode::LControl KeyCode::RControl // ✅ 0.14 KeyCode::ControlLeft KeyCode::ControlRight

类似的重命名也适用于其他修饰键(Shift, Alt, Meta/Command)。编译器会给出明确的错误提示,按照提示修改即可。

2. 精灵图集(TextureAtlas)布局 API 变更

创建TextureAtlas的 API 有所调整。

// ❌ 0.13 let atlas = TextureAtlas::from_grid( texture_handle, Vec2::new(16.0, 16.0), 4, 4, None, None, ); // ✅ 0.14 let atlas = TextureAtlas::from_grid( texture_handle, Vec2::new(16.0, 16.0), 4, 4, None, None, false, // 新增参数:是否填充空白区域 );

3. 相机投影(CameraProjection)相关变更

如果使用了自定义相机投影,可能需要更新 trait 实现。

// ❌ 0.13 impl CameraProjection for MyProjection { fn get_projection_matrix(&self) -> Mat4 { ... } fn update(&mut self, width: f32, height: f32) { ... } fn far(&self) -> f32 { ... } // ... } // ✅ 0.14 impl CameraProjection for MyProjection { fn get_projection_matrix(&self) -> Mat4 { ... } fn update(&mut self, width: f32, height: f32) { ... } // far 等方法可能已被移除或移至其他 trait,请查阅最新文档。 }

七、升级后补充模块:调试控制台与剧本系统

在成功升级到 Bevy 0.14 后,我顺手将项目中从 Python 原型迁移过来的两个核心模块进行了 Rust 重写和集成。

1. 调试控制台(Debug Console)

一个简单的内嵌式命令行界面,用于在游戏运行时执行命令、修改变量、打印状态。

// 主要功能 // - 按 ` 键呼出/隐藏控制台 // - 支持基本命令:spawn, teleport, godmode, fps // - 命令历史与自动补全 // - 输出日志滚动显示

2. 剧本系统(Script System)

一个基于事件的轻量级叙事与任务系统,用于驱动游戏剧情和角色对话。

// 核心组件 #[derive(Component)] pub struct Script { pub id: String, pub triggers: Vec<Trigger>, pub actions: Vec<Action>, } // 事件驱动 pub struct ScriptEvent { pub script_id: String, pub params: HashMap<String, String>, }

这两个模块的加入显著提升了项目的可调试性和内容创作灵活性。

八、总结

从 Bevy 0.13 升级到 0.14 主要挑战在于 State API 的抽离和一系列破坏性命名变更。关键步骤总结如下:

  1. 修改 Cargo.toml:更新版本号,修正 feature 名称(如multi_threaded),并显式添加bevy_statebevy_app依赖。
  2. 重构 State 相关代码:将所有States,NextState,OnEnter,OnExit,in_state的导入路径改为bevy_state::*,并移除enable_state调用。
  3. 更新几何图元:将shape::Circle等替换为bevy::math::primitives::Circle,注意字段变化。
  4. 修正 Color 访问:将.r()等方法调用改为直接字段访问.r
  5. 处理其他 API 变更:如KeyCode重命名、TextureAtlasAPI 变更等。

升级过程虽然繁琐,但 0.14 在 macOS 上的稳定性提升是值得的。建议在升级前,在一个独立的小项目中验证关键变更,再回到主项目进行系统性的修改。

http://www.jsqmd.com/news/1151618/

相关文章:

  • 变分推断 vs MCMC:3 大维度对比与贝叶斯计算选型指南
  • 从零构建Claude-MCP协同工作流:企业DevOps团队必须掌握的4层认证与审计规范
  • 2026 上海嘉定企业 GEO 优化服务商深度测评:本地制造企业优选企优托一网推罗琪
  • 游戏画面撕裂原理解析:从帧率、垂直同步到G-Sync/FreeSync 3种解决方案对比
  • 一盏灯里的“中国制造”——从代工到品牌
  • F12 Overrides/Sources 页面应用:5分钟实现JS文件本地替换与调试
  • AIGC 全流程解析:从剧本到视频的完整创作指南
  • 告别风扇噪音!Windows终极风扇控制软件FanControl完全指南 [特殊字符]️
  • 隧道照明新标准2025-2026全解析:GB37478、GB/T32481合规指南
  • 终极解决方案:如何彻底解决Windows运行库缺失问题
  • OBS背景音乐插件_新手教程篇
  • 2026年必尝:健康美味的苦荞全麦片企业推荐
  • AI短剧不是梦!一个人一台电脑月入过万,完整制作全链路拆解
  • RK3568平台开发系列讲解(以太网篇)PHY芯片寄存器说明
  • Java 竟能调用 R 搞数据,R 强大功能让 Java 数据处理如虎添翼
  • 2026年透明胶带制造厂大盘点,这些知名厂家你知道几个?
  • 3个核心功能:全面掌握暗黑破坏神2存档编辑器d2s-editor
  • 动态规划完整讲解
  • 终极指南:三分钟在Audacity中部署OpenVINO AI音频插件
  • 西安同城货运平台开发系统,整车货源智能分发技术讲解
  • AIGC Agent技术架构解析与开发实战:从原理到企业级应用
  • 茶叶商城销售系统
  • MPW与Full Mask流片决策:3大成本模型与5个量产风险评估要点
  • PS报“暂存盘已满“先别慌!这3步清出30G,草稿一张都没丢
  • 3个月实战总结:顺德鱼生选油秘籍,轻松去腥味
  • Scaling Laws 实战:3步利用小模型预测GPT-4级大模型性能
  • 西安预约打车小程序搭建,订单超时自动取消逻辑实现
  • 【2026最新】MySQL安装教程:超详细图文讲解(附MySQL安装包)
  • 6.30-取消TMC消息通知4
  • 使用Vue自定义指令