17个版本 (11个破坏性版本)
0.11.0 | 2024年1月11日 |
---|---|
0.10.3 | 2023年12月23日 |
0.9.2 | 2023年12月5日 |
0.8.0 | 2023年11月18日 |
#1542 在 游戏开发
每月26次下载
被 3 crates 使用
130KB
2K SLoC
ECS
ReactCommands
使注册和注销ECS钩子变得容易。当需要将信息(例如实体ID)传递到反应系统时,反应器最有用。
一旦检测到反应触发器,反应器将在第一次 apply_deferred
后运行。如果反应器触发其他反应器,它们将在初始反应器之后立即运行(直到整个反应树终止)。目前不支持递归反应。
注册反应器
使用 ReactCommands
注册反应器。您必须指定一个 '反应触发器'
fn setup(mut rcommands: ReactCommands)
{
rcommands.on(resource_mutation::<A>(),
|a: ReactRes<A>|
{
//...
}
);
}
可用的反应触发器有
- [
resource_mutation<R: ReactResource>()
] - [
insertion<C: ReactComponent>()
] - [
mutation<C: ReactComponent>()
] - [
removal<C: ReactComponent>()
] - [
entity_insertion<C: ReactComponent>(entity)
] - [
entity_mutation<C: ReactComponent>(entity)
] - [
entity_removal<C: ReactComponent>(entity)
] - [
event<E>()
]
反应堆可以与多个反应触发器相关联
fn setup(mut rcommands: ReactCommands)
{
rcommands.on((resource_mutation::<A>(), entity_insertion<B>(entity)),
move |a: ReactRes<A>, q: Query<&B>|
{
q.get(entity);
//...etc.
}
);
}
撤销反应堆
可以使用在注册时获得的 RevokeToken
来撤销反应堆。
let token = rcommands.on(resource_mutation::<A>(), || { todo!(); });
rcommands.revoke(token);
触发类型:资源突变
向您的应用添加反应性资源
#[derive(ReactResource)]
struct Counter(u32);
app.add_plugins(ReactPlugin)
.add_react_resource(Counter);
修改资源
fn increment(mut rcommands: ReactCommands, mut counter: ReactResMut<Counter>)
{
counter.get_mut(&mut rcommands).0 += 1;
}
对资源突变做出反应
fn setup(mut rcommands: ReactCommands)
{
rcommands.on(resource_mutation::<Counter>(),
|counter: ReactRes<Counter>|
{
println!("count: {}", counter.0);
}
);
}
触发类型:组件插入/修改/删除
#[derive(ReactComponent)]
struct Health(u16);
fn setup(mut rcommands: ReactCommands)
{
let entity = rcommands.commands().spawn_empty().id();
rcommands.insert(entity, Health(0u16));
rcommands.on(entity_mutation::<Health>(entity)
move |q: Query<&React<Health>>|
{
let health = q.get(entity).unwrap();
println!("health: {}", health.0);
}
);
}
fn add_health(mut rcommands: ReactCommands, mut q: Query<&mut React<Health>>)
{
for health in q.iter_mut()
{
health.get_mut(&mut rcommands).0 += 10;
}
}
实体无关的触发器(insertion<C>()
、mutation<C>()
、removal<C>()
)只能相互组合,因为它们的反应堆需要一个 In<Entity>
系统参数
#[derive(ReactComponent)]
struct A;
#[derive(ReactComponent)]
struct B;
rcommands.on((insertion::<A>(), removal::<B>()),
|In(entity): In<Entity>, a: Query<(Option<&React<A>>, Option<&React<B>>)>|
{
//...
}
);
触发类型:事件
注册一个反应事件
app.add_react_event::<u32>();
发送事件
rcommands.send(0u32);
使用 ReactEventReader
来访问事件数据并对事件做出反应
rcommands.on(event::<u32>(),
|mut events: ReactEventReader<u32>|
{
for event in events.iter()
{
println!("react u32: {}", event);
}
}
);
触发类型:销毁
使用 [ReactCommands::on_despawn()
] 方法对销毁做出反应
rcommands.on_despawn(entity, move || println!("entity despawned: {}", entity));
一次性反应堆
如果您只想让反应堆运行一次,请使用 [ReactCommands::once()
]。
let entity = rcommands.commands().spawn(Player);
rcommands.once(event::<ResetEverything>(),
move |world: &mut World|
{
world.despawn(entity);
}
);
依赖关系
~23MB
~417K SLoC