RustのゲームエンジンBevyに触れてみる

[PONOS Advent Calendar 2021](https://qiita.com/advent-calendar/2021/ponos)の17日目の記事です。
昨日は、 @jesseniqiita さんの [Unityで予測できるランダム値を生成](https://qiita.com/jesseniqiita/items/8b98b953713de42cd77b) でした。

## はじめに

前回、[RustのゲームエンジンAmethystを触れてみる](https://qiita.com/nisei275/items/e94758bb30d35c438ef9)という記事を投稿いたしました。Amethystの開発エンジンを調べるために公式サイトを閲覧してみると、[Amethyst – Starting fresh](https://amethyst.rs/posts/amethyst--starting-fresh)という記事の中に、以下が記されていました。

```
We are officially halting development of Amethyst Engine.
Both the stable v0.15 version as well as the pending v0.16 (Legion) version.
```

Amethystは正式に開発を中止したことが記載されており、その中で

```
Enjoy life on the cutting edge?
Bevy, a formidable spiritual successor to the Amethyst Engine,
is the most advanced ECS-powered game engine in Rust-land.
```

と記載されており、和訳する「Amethystの考え方を後継しているBevyは、Rustのゲームエンジンで最も先進的なECSを搭載したゲームエンジンです。」(自分なりに英訳しているので間違っていたらすみません。)ということが書かれていました。今回はここで書いている最も最先端なRust製のゲームエンジン[Bevy](https://bevyengine.org/)を触れてみることにします。

## Bevy
今回触れてみるRust製のゲームエンジン[Bevy](https://bevyengine.org/)は「Amethyst」と同じくECSアーキテクチャを採用しています。ECSの説明については、[RustのゲームエンジンAmethystを触れてみる](https://qiita.com/nisei275/items/e94758bb30d35c438ef9)で記述していますので、そちらの方をご確認ください。

公式サイトを確認するとBevyは以下点特徴のようです。

* **データ駆動型**: BevyECSを使用し、他のエンジンより高速である。
* **レンダリンググラフ**: グラフ構造を使用してカスタムレンダリングパイプラインを作成する。
* **シーン**: BevyのSceneシステムを使用して、ECSワールドを作成、保存、およびロードする。
* **ホットリロード**: アプリを再起動や再コンパイルせずに、変更に関するフィードバックを即座に取得できる。
* **高速コンパイル**: Bevyを使用すると、0.8〜3.0秒でコンパイルが完了する。

他にも特徴がありましたが、Amethystと比較したときにピックアップされる特徴になるのではないかと考えています。Amethystと比べてまだたりてない機能として、githubにある[Roadmap](https://github.com/bevyengine/bevy/projects/1)(Bevy v.0.5時点)を確認すると、iOSやAndroidのようなスマートフォン端末にはまだ対応していないようです。

## 実装

RustでBevyを使用してウィンドウを表示するだけの実装を実施したいと思います。実装環境としてはローカル(macOS)で実施することを前提しています。

|開発環境|バージョン|
|:-:|:-:|
|macOS|11.15.2|
|Rust(rustc、cargo)|1.52.1|
|Bevy|0.5.0|

### 事前準備

開発端末にRustを導入しなくてはいけませんが、導入する方法は[2019年アドベントカレンダーの17日目の記事](https://qiita.com/nisei275/items/a60cb3d3e97aeb429fa7)で記載しておりますので、今回は省略します。また、amethystと比べてツールというものは見つけられることができませんでしたので`Cargo`の仕組みを使用し`new`をします。

1. プロジェクトの作成

    ```
    $ cargo new hello_world --bin
    ```

`--bin`の指定はバイナリプログラムを作成する場合になり、ライブラリを作成している場合は、-libを渡します。今回はライブラリではないので、`--bin`を指定します。プロジェクトの生成をすると、以下のようなシンプルなディレクトリ構成のプロジェクトが生成されます。

```
├──Cargo.toml
├──README.md
└──src
   └──main.rs
```


### 実装する

各種追加したコードを記述します。

```toml:Cargo.toml
[package]
name = "project name"
version = "0.1.0"
authors = ["XXXXX <XXXXX@email.com>"]
edition = "2018"

[dependencies]
bevy = "0.5"
```

```rust:main.rs
use bevy::prelude::*;

const GAME_TITLE: &str = "2D Action Game";
const DEFAULT_WINDOW_WIDTH: f32 = 1280.0;
const DEFAULT_WINDOW_HEIGHT: f32 = 720.0;

fn main() {
    // アプリケーションの初期起動
    App::build()
        // ウィンドウの背景色の指定
        .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)))
        // ウィンドウの初期設定
        .insert_resource(
            WindowDescriptor {
                title: GAME_TITLE.to_string(),
                width: DEFAULT_WINDOW_WIDTH,
                height: DEFAULT_WINDOW_HEIGHT,
                resizable: false, // ウィンドウの大きさ変更を無効
                ..Default::default()
            }
        )
        // Bevyエンジンの全ての機能はプラグインとして実装されている。
        // 最低限のプラグイン(DefaultPlugins)を指定する。
        .add_plugins(DefaultPlugins)
        .add_startup_system(setup.system())
        .run();
}

// 初期起動のシステムのセットアップ
fn setup(mut commands: Commands) {
    // カメラを設置
    commands.spawn_bundle(OrthographicCameraBundle::new_2d());
}
```

## 実行
以下、コマンドで実行します。

```
$ cargo run
```

AmethystのようにグラフィックスAPIの指定方法を見つけることができませんでした。この項目については分かり次第記事を更新していこうかと思います。

### 実行結果

以下のようにウィンドウが表示されたら成功になります。

![Screen Shot 2021-12-12 at 23.10.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191987/5b949ef1-9d23-23a6-6e17-ea8b12dc3dbd.png)

## まとめ

今回はRustのゲームエンジンBevyをウィンドウが表示されるところまで実装してみました。実装やサンプルなどを様々確認しましたが、Amethystに比べてコードを記述する量は少ないように感じます。また、特徴にもに記述しましたがコンパイルの速度もBevyの方が速いと感じています。
Rust製のゲームエンジンとしては比較的新しいものですが、現在でもゲームエンジンに必要な機能はいくつもサポートされており、Githubのコミット履歴やプルリクエスト履歴を見てみると活発に開発されていることがわかります。また、Bevy開発者はエディターの構築に熱心に取り組んでおり、物理ベースの完全なレンダリングサポートを追加したばかりということでした。これからゲームエンジンとして大成することを願いつつ、これからも動向を確認していきたいかなと思います。

明日は、@e73ryo さんになります。お楽しみに！