Latest commit d7a897d

资源

相关的官方文档:[ecs_guide]


资源可以存储某种数据类型的唯一全局实例,独立于实体(与实体无关)。

资源用于程序中真正的全局数据,例如配置、设置。

任何 Rust 类型(结构体或枚举)都可以成为资源。

类型必须是唯一的;给定类型只能有一个资源实例。

#![allow(unused)]
fn main() {
struct GoalsReached {
    main_goal: bool,
    bonus: bool,
}
}

可以用 ResResMut 在系统中访问资源。

资源初始化

给简单的资源实现 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 模式(实体/组件)。

即使游戏中某些东西只有一个(比如单机游戏中的玩家),用实体也比用资源更合适,因为实体由多个组件组成,而组件可以和其他实体通用。这可以使游戏逻辑更加灵活。例如,可以设计一个对玩家和敌人都有效的“生命值/伤害系统”。