#action #bevy #sequence #command #gamedev

bevy-sequential-actions

一个用于按顺序执行各种动作的Bevy库

10次重大发布

0.11.0 2024年7月4日
0.10.0 2024年2月17日
0.9.0 2023年11月6日
0.8.0 2023年7月10日
0.3.0 2022年7月30日

#108游戏开发

Download history 2/week @ 2024-04-18 3/week @ 2024-04-25 15/week @ 2024-05-16 4/week @ 2024-05-23 3/week @ 2024-05-30 5/week @ 2024-06-06 5/week @ 2024-06-27 177/week @ 2024-07-04 4/week @ 2024-07-11 10/week @ 2024-07-25 339/week @ 2024-08-01

每月下载量368

MIT/Apache

35KB
434

Bevy Sequential Actions

crates.io docs.rs MIT/Apache 2.0

一个旨在以顺序方式执行各种动作队列的Bevy库。这通常意味着一次只运行一个动作,当一个动作完成后,下一个动作将开始,依此类推,直到队列为空。

https://user-images.githubusercontent.com/19198785/167969191-48258eb3-8acb-4f38-a326-f34e055a1b40.mp4

📜 入门指南

插件

开始的最快方法是向您的App添加SequentialActionsPlugin

use bevy_sequential_actions::*;

fn main() {
    App::new()
        .add_plugins(SequentialActionsPlugin)
        .run();
}

修改动作

动作是任何实现了Action特质的东西,并且可以添加到包含ActionsBundle的任何Entity中。具有动作的实体被称为agent。有关可用方法,请参阅ModifyActions特质。

fn setup(mut commands: Commands) {
    let agent = commands.spawn(ActionsBundle::new()).id();
    commands
        .actions(agent)
        .add(action_a)
        .add_many(actions![
            action_b,
            action_c
        ])
        .order(AddOrder::Front)
        .add(action_d)
        // ...
}

实现动作

Action特质包含3个必需的方法

  • is_finished,用于确定动作是否完成。
  • on_start,在动作开始时调用。
  • on_stop,在动作停止时调用。

此外,还有3个可选方法

  • on_add,在动作添加到队列时调用。
  • on_remove,在动作从队列中删除时调用。
  • on_drop,这是最后一个调用完全所有权的最后一个方法。

以下是一个简单的等待动作。

pub struct WaitAction {
    duration: f32, // Seconds
    current: Option<f32>, // None
}

impl Action for WaitAction {
    fn is_finished(&self, agent: Entity, world: &World) -> bool {
        // Determine if wait timer has reached zero.
        // By default, this method is called every frame in the Last schedule.
        world.get::<WaitTimer>(agent).unwrap().0 <= 0.0
    }

    fn on_start(&mut self, agent: Entity, world: &mut World) -> bool {
        // Take current time (if paused), or use full duration.
        let duration = self.current.take().unwrap_or(self.duration);

        // Run the wait timer system on the agent.
        world.entity_mut(agent).insert(WaitTimer(duration));

        // Is action already finished?
        // Returning true here will immediately advance the action queue.
        self.is_finished(agent, world)
    }

    fn on_stop(&mut self, agent: Entity, world: &mut World, reason: StopReason) {
        // Take the wait timer component from the agent.
        let wait_timer = world.entity_mut(agent).take::<WaitTimer>();

        // Store current time when paused.
        if reason == StopReason::Paused {
            self.current = Some(wait_timer.unwrap().0);
        }
    }
}

#[derive(Component)]
struct WaitTimer(f32);

fn wait_system(mut wait_timer_q: Query<&mut WaitTimer>, time: Res<Time>) {
    for mut wait_timer in &mut wait_timer_q {
        wait_timer.0 -= time.delta_seconds();
    }
}

⚠️ 警告

需要注意的一点是在Action特质内部使用World修改动作。为了在调用特质方法时传递对世界的可变引用,必须暂时从agent中移除动作。这意味着,根据您的操作,动作队列的推进逻辑可能不会正常工作。

通常,在动作特质内部修改agent的动作时有两条规则

  • 在添加新动作时,您应该将start属性设置为false,或者直接推送到ActionQueue组件。
  • 不应使用executenext方法。

📎 示例

请参阅示例以获取更多使用信息。每个示例都可以通过以下命令运行:cargo run --example <example>

示例 描述
基本 展示了库的基本用法。
暂停 展示了如何暂停和恢复动作。
重复 展示了如何创建重复的动作。
并行 展示了如何创建并行运行的动作。
序列 展示了如何创建包含一系列动作的动作。
调度 展示了如何使用两个不同的调度器与插件配合使用。
自定义 展示了如何使用自定义系统来推进动作队列。
销毁 展示了如何正确销毁一个agent

📌 兼容性

bevy bevy-sequential-actions
0.14 0.11
0.13 0.10
0.12 0.9
0.11 0.8
0.10 0.7
0.9 0.6
0.8 0.3 – 0.5
0.7 0.1 – 0.2

🔖 许可证

bevy-sequential-actions可以根据您的选择采用以下任一许可证:

任选其一。

依赖项

~17MB
~287K SLoC