7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🦀ひとりRustとBevyでゲーム開発🕊️Advent Calendar 2024

Day 1

【Rustのまほう2】#1 Bevy Engineでオンラインアクションゲームを作る

Last updated at Posted at 2024-11-30

はじめに

Tiny Gladeというゲームが9月末にSteamで販売開始されました。

この記事を書いている時点でレビューが12,000件以上ついているという盛況ぶりです。こちらのゲームでは Bevy Engine というゲームエンジンが使われているそうです1

今回のアドベントカレンダーは、ちょっとしたゲームを作りながらこのBevy Engineの解説記事で完走を目指して走っていきたいと思います。もっとも、とてもすべては解説しきれないので、BevyやECSの大まかな概念やTipsなどに絞っていく予定です。

ちなみに2022年のアドベントカレンダーで書いたRustのまほう1期はこちらです。

Bevy Engineについて

Bevyは次のような特徴のゲームエンジンです。

  • プログラミング言語Rustのライブラリ
  • 2Dと3Dの両方に対応
  • クロスプラットフォーム (Windows, MacOS, Linux, Web, iOS, Android)
  • オープンソース
  • Entity Component System (ECS)というアーキテクチャ

Bevyはまだまだ開発途上の段階にあり、バージョンアップのたびにゴリゴリAPIが変わっているようです。なにしろ「まだAPIが不安定だしRustでゲーム作るならGodotとかを検討してもいいんじゃない?」と公式が自分で言っているくらいです。あくまでゲームを完成させることが目的の人は、素直に Unity や Unreal Engine、あるいはオープンソースが好みなら Godot Engine などを使ったほうが安心できると思います。でも自分は今回、以下のような理由で Bevy にしました。

  • プログラミング言語Rustを練習がてら何か作ってみたかった
  • オブジェクト指向を脱却したデータドリブンなECSアーキテクチャを体験してみたかった
  • UnityやUnreal Engineはすでに幾らでも資料や記事があるので、私が書くことはもうあまりない。日本語圏で資料が少ないもののほうが執筆のやる気が出る
  • 多機能なGUIエディタつきのゲームエンジンより、シンプルなライブラリのほうが性に合っている気がする

Bevyはまだ若いエンジンのわりにはコミュニティが比較的大きく、ユーザーの熱意も感じます。探してみると良さげなプラグイン(ライブラリ)もたくさん見つかります。本体の開発も活発で、このあいだBevy財団が発足して寄付を募っているなどコアチームの開発体制づくりにも力が入っています。もしこの記事の読者のなかに大富豪がいらっしゃいましたら、ぜひとも寄付してもらえればコミュニティ全員が喜ぶと思います。

自分が作っているゲームについて

今回私が作っているのは、ジャンルでいうと「ツインスティックシューター」などと呼ばれている種類のものです。これは文字通り「左のスティックと右のスティック(またはWASDとマウス)でそれぞれ移動と攻撃の方向を指示」という操作の2Dのアクションゲームです。

私がプレイしたことのあるゲームでいうと「Enter the Gungeon」が典型的で、「Factorio」「Noita」のようなゲームも操作が同様です。FPSのような3次元的なゲームより操作が簡単でわかりやすく、私はこのジャンルのゲームが好きなのでこれにしました。

現状だとどうにか基本的なシステムは形になってきていて、プレイヤーキャラクターと敵キャラクターがなんとなくそれっぽく戦えたり、オンラインでプレイヤー同士が簡単なバトルをできるというところです。

screenshot.png

詳しい内容については、今後の記事に少しづつ書いていきたいと思います。

Bevyで画像を表示してみる

このシリーズはあくまでプログラミングの記事なので、早速ですがウィンドウを開いて何か画像を表示するコードを実際に書いて、Bevyの雰囲気を体験してみましょう。まずはいつものように cargo initでプロジェクトを初期化し、bevyクレートを依存関係に追加します。

$ cargo init

$ cargo add bevy

ウィンドウを開いてスプライト(画像)を表示する最低限のコードは以下のようになります2

src/main.rs
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn(Camera2dBundle::default());
    commands.spawn(SpriteBundle {
        texture: asset_server.load("bevy_bird_dark.png"),
        ..default()
    });
}

それからassetsフォルダ以下に画像や音声などのアセットを置きます。assetsがBevyのデフォルトのアセットパスです。あとは cargo runで実行すれば、ウィンドウが開いて画像が表示されるはずです。

main関数

少し詳しくコードの中身を見てみます。

まずは app.add_plugins(DefaultPlugins)でデフォルトのプラグインを設定しています。Bevyの個々の機能は、 プラグイン として個別に提供されます。ウィンドウを表示する機能やスプライトを表示する機能などの最小限の機能をまとめたのがDefaultPluginsで、これを登録することで最低限ウィンドウを開いて画像を表示することができます3

次の app.add_systems(Startup, setup)では、Startup というスケジュールsetup システム を登録しています。Bevyにおけるシステムとは、特定のパターンの引数を持った関数のことです。またスケジュールとはそのシステムが呼び出されるタイミングのことです。要するに、イベントにイベントハンドラを登録しているようなものだと考えればいいでしょう4

最後に app.run() を呼び出して実行を開始します。

setup関数

Startupはゲームの開始時に1度だけ実行されるスケジュールなので、先ほど登録された setup システムが一度だけ実行されます。まずCamera2dBundle::default()でカメラを作成しcommands.spawnでゲーム世界に追加しています。ゲーム画面を表示するには、少なくともひとつのカメラが必要です。

次に asset_server.load("bevy_bird_dark.png")で画像のパスを指定し、画像のハンドルを取得しています5。そしてそれを SpriteBundle に渡して初期化し、commands.spawnで追加しています。

そしてBevy 0.15へ……

実はこの記事が投稿される前日に、Bevy 0.15 が正式リリース されました。この変更により、上記のコード中のCamera2dBundleSpriteBundleが非推奨になりました。0.15対応のコードだと以下のようになります。

src/main.rs
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn(Camera2d::default());
    commands.spawn(Sprite::from_image(asset_server.load("bevy_bird_dark.png")));
}

自分も必死にリリースノートを読んでいるところです。Required Componentsという機能が追加されたのですが、これは「Bevyが始まって以来最も重大なAPI改善」だといいます。確かに今までのAPIよりもシンプルに書けるようになって、良い感じだとは思います。破壊的変更は恐ろしいですが、Bevy界隈は活発なので外部のBevyプラグインもすぐに追従してきてくれることでしょう。

次回予告

これだけならあまりECSっぽさもないので、とくに難しくないですね。次回以降は、Bevyの最大の特徴である Entity Component System について解説したり、Bevyでの開発について実践的な部分の解説をできたらと思います。

  1. ただしレンダリングはBevyのものではなく、Vulkan上で独自のレンダリングパイプラインが実装されているそうです。作者インタビュー→ https://80.lv/articles/exclusive-tiny-glade-developers-discuss-bevy-proceduralism-publishers-cozy-games/

  2. これはバージョン 0.14 のコードなのですが、実は次のバージョン 0.15 で書き方が変わりそうです。変化が激しい……。

  3. サーバーサイドで動かすなど、ヘッドレスに実行したい場合はこのDefaultPluginを登録しない場合もあるようです。

  4. ただしBevyの機能としての「イベント」はまた別に存在します。

  5. 勘のいい人は「ファイルアクセスなのに同期的でいいのか?」と思うかもしれませんが、このasset_server.loadは画像データそのものではなくハンドルを即座に返します。あとはエンジンが実際の読み込みを裏で行い、完了しだい画面に描画してくれるので、開発者がデータの非同期読み込みを意識する必要がなくなっています。

7
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?