#scripting-language #bevy #scripting #rhai #gamedev #game-engine

bevy_scriptum

Bevy引擎的插件,允许您使用脚本语言编写部分游戏逻辑

8个版本 (5个重大更新)

0.6.0 2024年7月5日
0.5.0 2024年6月16日
0.4.0 2024年4月10日
0.3.0 2024年4月10日
0.1.0 2023年6月21日

游戏开发 中排名 87

每月下载 41

MIT/Apache

5MB
1K SLoC

bevy_scriptum 📜

bevy_scriptum 是 Bevy 引擎的插件,允许您使用脚本语言编写部分游戏逻辑。目前支持 RhaiLua,未来可能会添加更多语言。

有关如何开始使用此库的所有信息,请参阅 bevy_scriptum 书籍

API 文档可在 docs.rs 中找到

bevy_scriptum 的主要优势包括

  • 低模板代码
  • 易于使用
  • 基于 Promise 的异步 API
  • 灵活性
  • 热重载

脚本作为独立的文件,可以在运行时热重载。这允许您快速迭代游戏逻辑,而无需重新编译游戏。

您只需在您的 Bevy 应用程序上注册回调,例如

use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;

App::new()
    .add_plugins(DefaultPlugins)
    .add_scripting::<LuaRuntime>(|runtime| {
         runtime.add_function(String::from("hello_bevy"), || {
           println!("hello bevy, called from script");
         });
    })
    .run();

然后您可以在脚本中调用它们,例如

hello_bevy()

您暴露给脚本语言的每个回调函数都是一个 Bevy 系统,因此您可以像在常规 Bevy 系统中那样轻松查询和修改 ECS 组件和资源

use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;

#[derive(Component)]
struct Player;

App::new()
    .add_plugins(DefaultPlugins)
    .add_scripting::<LuaRuntime>(|runtime| {
        runtime.add_function(
            String::from("print_player_names"),
            |players: Query<&Name, With<Player>>| {
                for player in &players {
                    println!("player name: {}", player);
                }
            },
        );
    })
    .run();

您还可以向回调函数传递参数,就像在常规 Bevy 系统中那样 - 使用 In 结构体与元组

use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;

App::new()
    .add_plugins(DefaultPlugins)
    .add_scripting::<LuaRuntime>(|runtime| {
        runtime.add_function(
            String::from("fun_with_string_param"),
            |In((x,)): In<(String,)>| {
                println!("called with string: '{}'", x);
            },
        );
    })
    .run();

然后在您的脚本中调用它们,例如

fun_with_string_param("Hello world!")

用法

将以下内容添加到您的 Cargo.toml

[dependencies]
bevy_scriptum = { version = "0.5", features = ["lua"] }

或在您的项目目录中执行 cargo add bevy_scriptum --features lua

现在,您可以开始向脚本语言公开函数。例如,您可以公开一个将消息打印到控制台的函数

use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;

App::new()
    .add_plugins(DefaultPlugins)
    .add_scripting::<LuaRuntime>(|runtime| {
       runtime.add_function(
           String::from("my_print"),
           |In((x,)): In<(String,)>| {
               println!("my_print: '{}'", x);
           },
       );
    })
    .run();

然后,您可以在 assets 目录中创建一个名为 script.lua 的脚本文件,该文件调用此函数

my_print("Hello world!")

创建一个带有附加的 Script 组件的实体,并指向脚本源文件的手柄

use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;

App::new()
    .add_plugins(DefaultPlugins)
    .add_scripting::<LuaRuntime>(|runtime| {
       runtime.add_function(
           String::from("my_print"),
           |In((x,)): In<(String,)>| {
               println!("my_print: '{}'", x);
           },
       );
    })
    .add_systems(Startup,|mut commands: Commands, asset_server: Res<AssetServer>| {
        commands.spawn(Script::<LuaScript>::new(asset_server.load("script.lua")));
    })
    .run();

然后你应该能在你的控制台中看到 my_print: 'Hello world!' 被打印出来。

示例

demo

提供的示例

您也可以通过克隆此存储库并运行以下命令来尝试运行提供的示例:cargo run --example <example_name>_<language_name>。例如

cargo run --example hello_world_lua

示例位于 examples 目录中,它们对应的脚本位于存储库中的 assets/examples 目录。

Bevy 兼容性

bevy 版本 bevy_scriptum 版本
0.14 0.6
0.13 0.4-0.5
0.12 0.3
0.11 0.2
0.10 0.1

承诺 - 从脚本获取返回值

从脚本中调用的每个函数都返回一个承诺,您可以对该承诺使用 :and_then 并传递一个回调函数。当承诺解决时,将调用此回调函数,并将从脚本中调用的函数的返回值传递给它。例如

get_player_name():and_then(function(name)
    print(name)
end)

这将在使用以下公开函数时打印出 John

use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;

App::new()
   .add_plugins(DefaultPlugins)
   .add_scripting::<LuaRuntime>(|runtime| {
           runtime.add_function(String::from("get_player_name"), || String::from("John"));
   });

从脚本访问实体

一个名为 entity 的变量自动对所有脚本可用 - 它代表附加了 Script 组件的 bevy 实体。它公开了一个 index 属性,该属性返回 bevy 实体索引。这对于从脚本中访问实体的组件非常有用。它可以以下述方式使用

print("Current entity index: " .. entity.index)

entity 变量目前在承诺回调中不可用。

贡献

欢迎贡献!请随意提出问题或提交拉取请求。

许可协议

bevy_scriptum 根据您的选择,受以下任何一个许可协议的约束:Apache License,版本 2.0,(LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)或 MIT 许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT

依赖项

~23–58MB
~1M SLoC