用途
本技能用于在 Bevy 引擎的 ECS 架构下实现背包/物品栏系统,核心场景是物品堆叠(stack)在容器(container)之间移动。当堆叠需要在容器间转移时加载本技能。UI 网格布局仍由 bevy-ui-layout 负责,经济价格仍由 bevy-economy-system 负责。
主要能力
- 定义物品 ID 与堆叠数量组件。
- 以实体(entity)表示拥有堆叠的容器。
- 通过消息(MoveStack)发起移动请求,使单个系统能够同时可变借用两个背包。
- 提供装备(Equip)标记组件;属性变化交由 bevy-rpg-stats 处理。
- 提供添加堆叠、转移堆叠、装备首个物品、生成背包等示例代码。
ECS 结构
- 组件(Components):由使用者定义的物品 ID 与堆叠数量。
- 资源(Resources):运行期全局表存放在资源中(bevy-data-resources)。
- 系统(Systems):在 Update 或固定时间步(fixed timestep)上修改这些组件;当伤害必须先于死亡结算时使用 .chain()。
- 消息(Messages):一次性事实(命中、拾取、任务推进)通过 bevy-events-messaging 传递;本文件不新增事件类型名称。
所有权划分
- 堆叠(Stack):组件上的物品 ID 加数量,或资源背包内部。
- 容器(Container):拥有堆叠的实体。
- 装备(Equip):一个标记组件;属性变化走 bevy-rpg-stats。
范围
物品 ID、堆叠数量与容器都是组件。移动请求是消息,因此一个系统即可写入两个背包。槽位控件留在 bevy-ui-layout,价格留在 bevy-economy-system。
使用方式(示例代码)
依赖声明:
[package]
name = "inventory"
version = "0.1.0"
edition = "2021"
[dependencies]
bevy = "0.20"
堆叠存放在容器实体上,移动通过消息实现,使单个查询能同时可变借用两个背包:
#[derive(Clone, Copy, PartialEq, Eq)]
struct ItemId(u32);
#[derive(Clone, Copy)]
struct Stack {
item: ItemId,
count: u32,
}
#[derive(Component, Default)]
struct Inventory {
slots: Vec<Stack>,
}
#[derive(Message)]
struct MoveStack {
from: Entity,
to: Entity,
slot: usize,
count: u32,
}
fn add_stack(inv: &mut Inventory, item: ItemId, mut count: u32) {
for stack in &mut inv.slots {
if stack.item == item {
stack.count += count;
return;
}
}
if count > 0 {
inv.slots.push(Stack { item, count });
}
}
fn transfer(mut requests: MessageReader<MoveStack>, mut bags: Query<&mut Inventory>) {
for req in requests.read() {
if req.from == req.to || req.count == 0 {
continue;
}
let Ok([mut from, mut to]) = bags.get_many_mut([req.from, req.to]) else {
continue;
};
let Some(stack) = from.slots.get_mut(req.slot) else {
continue;
};
if stack.count < req.count {
continue;
}
let item = stack.item;
stack.count -= req.count;
let moved = req.count;
if stack.count == 0 {
from.slots.remove(req.slot);
}
add_stack(&mut to, item, moved);
}
}
pub struct InventoryPlugin;
impl Plugin for InventoryPlugin {
fn build(&self, app: &mut App) {
app.add_message::<MoveStack>()
.add_systems(Update, transfer);
}
}
装备会将堆叠复制到标记上,剩余部分留在背包中;属性变化仍由 bevy-rpg-stats 负责:
#[derive(Clone, Copy, PartialEq, Eq)]
struct ItemId(u32);
#[derive(Component)]
struct Equipped {
item: ItemId,
}
#[derive(Component, Default)]
struct Inventory {
slots: Vec<(ItemId, u32)>,
}
fn equip_first(mut commands: Commands, actors: Query<(Entity, &Inventory), Without<Equipped>>) {
for (entity, bag) in &actors {
let Some((item, count)) = bag.slots.first().copied() else {
continue;
};
if count == 0 {
continue;
}
commands.entity(entity).insert(Equipped { item });
}
}
生成一个箱子和一个带有初始堆叠的玩家背包:
#[derive(Clone, Copy, PartialEq, Eq)]
struct ItemId(u32);
#[derive(Clone, Copy)]
struct Stack {
item: ItemId,
count: u32,
}
#[derive(Component)]
struct Inventory {
slots: Vec<Stack>,
}
fn spawn_bags(mut commands: Commands) {
commands.spawn(Inventory {
slots: vec![Stack {
item: ItemId(1),
count: 8,
}],
});
commands.spawn(Inventory { slots: Vec::new() });
}
专家知识要点
目标版本:Bevy 0.20+。
核心 ECS 类型:Component、Resource、Query、Commands、Startup、Update、Fixed / FixedMain(bevy::time)、.chain()、Plugin、DefaultPlugins、MinimalPlugins。消息与观察者属于所有权槽位,其 API 参见 bevy-events-messaging。除非用 .chain() 对冲突系统排序,否则系统并行运行。
状态所有权:
- 单个实体上的数据:组件,由单个系统通过 Query 修改,运行于 Update 或 FixedMain。
- 整个应用的一个值:资源,由单个系统修改,Startup 插入,随后由读取它的调度使用。
- 生成:Commands,由生成系统负责;初始世界用 Startup,运行时生成用后续调度。
- 不可竞态的顺序:.chain(),仅作用于被链式连接的系统,同一调度内。
- 插件边界:Plugin,build 注册系统与资源,在应用运行前。
借用规则:两个都可变查询同一组件的系统必须排序(.chain())或拆分,使只有一个写入。无关系统保持并行。
决策表:
- 需要逐实体数据:用组件 + Query,不要用组件之外的字段。
- 需要应用级配置或时钟:用资源,不要复制到每个实体。
- 需要稳定模拟步长:用 FixedMain 与 Fixed 时钟,不要把模拟绑定到原始帧 Update。
- 需要启动生成:在 Startup 中用 Commands,不要从渲染系统生成。
- 需要非共享状态的跨系统通知:用 bevy-events-messaging 中的消息或观察者槽位,不要在本文件中新造事件类型。
- 需要堆叠与移动:用 Inventory 加 MoveStack 消息,不要让两个系统各写一个背包。
限制与禁止事项
- 不要在文档 URL 中固定 /0.20.0/;链接保持指向最新版,0.20 目标只在正文中说明一次。
- 不要从两个未排序的系统可变查询同一组件,因为除非用 .chain() 排序,调度会并行运行系统。
- 不要在此发明物理、导航、网络或 XR crate,本技能只命名有文档的 Bevy crate 与模块。
- 不要在 Bevy 代码中使用其他引擎的类型。
- 不要发明 API 或把未命名的第三方 crate 作为选定求解器。
适用场景
适用于 Bevy 0.20+ 游戏中需要在容器之间转移物品堆叠、管理背包槽位、实现装备标记的场景。
相关技能
前置:bevy-master(枢纽与调度)、bevy-ecs-composition(组件与系统)、bevy-rpg-stats(装备加成)、bevy-ui-layout(槽位布局)、bevy-data-resources(表与定义)、bevy-events-messaging(一次性事实)。
互补:bevy-state-machines(模式标志)。
下游/消费者:暂无。
主技能:bevy-master(Bevy 路由)。