Latest commit d7a897d
资源
相关的官方文档:[ecs_guide]
资源可以存储某种数据类型的唯一全局实例,独立于实体(与实体无关)。
资源用于程序中真正的全局数据,例如配置、设置。
任何 Rust 类型(结构体或枚举)都可以成为资源。
类型必须是唯一的;给定类型只能有一个资源实例。
#![allow(unused)] fn main() { struct GoalsReached { main_goal: bool, bonus: bool, } }
可以用 Res 或 ResMut 在系统中访问资源。
资源初始化
给简单的资源实现 Default:
#![allow(unused)] fn main() { #[derive(Default)] struct StartingLevel(usize); }
复杂资源的初始化需要实现 FromWorld:
#![allow(unused)] fn main() { struct MyFancyResource { /* stuff */ } impl FromWorld for MyFancyResource { fn from_world(world: &mut World) -> Self { // 可以在这里完全地访问 ECS 中的任何内容 // 例如,可以可变地访问其他资源 let mut x = world.get_resource_mut::<MyOtherResource>().unwrap(); x.do_mut_stuff(); MyFancyResource { /* stuff */} } } }
可以在构建 [App] 时初始化资源:
fn main() { App::new() // ... // 如果资源实现了 `Default` 或 `Fromworld`: .init_resource::<MyFancyResource>() // 如果没有实现上面的特型,或者想要设置一个具体的值: .insert_resource(StartingLevel(3)) // ... .run(); }
或者从系统内部用 [Commands] 来创建/移除资源:
#![allow(unused)] fn main() { commands.insert_resource(GoalReached { main_goal: false, bonus: false}); commands.remove_resource::<MyResource>(); }
插入一个已存在的资源类型时,新值会覆盖旧值。
使用建议
是用“实体/组件”还是使用资源取决于你想如何访问数据:从任何地方(资源),或用 ECS 模式(实体/组件)。
即使游戏中某些东西只有一个(比如单机游戏中的玩家),用实体也比用资源更合适,因为实体由多个组件组成,而组件可以和其他实体通用。这可以使游戏逻辑更加灵活。例如,可以设计一个对玩家和敌人都有效的“生命值/伤害系统”。