RenderTarget を使用することにより一時的にテクスチャーを描画対象に切り替えることができ、描画した結果をテクスチャーとして使用することができます。
タグ: MonoGame
MonoGame で制作したゲーム「リトルセイバー」を Web (Blazor + WebGL) で動かしてみた話 その2
前回の投稿
今回の記事は前の投稿の後日談になるので前回の記事を読んでいない場合は読むことをお勧めします。
nkast.Xna.Framework.Blazor がバージョンアップされました!
ゲームフレームワーク「MonoGame」で作ったゲームを Blazor で動かせるライブラリ「nkast.Xna.Framework.Blazor」が 3.8.9100 から 3.8.9101 にバージョンアップされました!
数字を見るとマイナーバージョンアップのように見えますが、内容的にはかなり大きな改善が入っています。改修内容を見てみると私が報告した不具合と、なんと私が書いたブログの内容がいくつか反映されているようでした。
主なバージョンアップ内容
バージョンアップ内容についてはコミュニティの以下の投稿に書いてあります。(一部私宛の返信の内容になっています)
バージョンアップ内容を簡単にまとめると以下のようになります。
- SpriteBatch のパフォーマンスが大幅に向上 (←これがすごい)
- SoundEffect.Volume の設定が反映されない不具合修正
- DXT3 圧縮がサポート
まず SoundEffect.Volume の不具合が直ったのでわざわざ音量を調整した音声ファイルを用意する必要はなくなりました。さすがにそれは面倒なのでやっていませんが。こちらはコミュニティに報告した内容が反映されています。
DXT3 圧縮もサポートされたので、SpriteFont などのコンテンツを作成する際にわざわざ別なフォーマットを選択する必要がなくなりました。こちらはなぜかブログに書いていた内容が反映されています。
そして一番影響が大きいのが SpriteBatch のパフォーマンスが上がったことです。プログラムを変更することなくライブラリを更新するだけで 2D のゲームのパフォーマンスが大幅に上がります。どのぐらいパフォーマンスが上がったかは動画を上げましたので前回の動画と比較して見てみてください。
プレイ動画
以下は前回、バージョン 3.8.9100 で作成したゲームを動かしてみたときの動画です。動画の内容は前回と同じものです。
ニコニコ動画
Youtube
そして今回、バージョン 3.8.9101 に更新してゲームを動かしてみた動画が以下になります。
ニコニコ動画
Youtube
見てもらえれば一目瞭然ですが、ちょっとどころではなく数倍ぐらいパフォーマンスが上がっているように見えると思います。パフォーマンスが上がっていると行ってもさすがにネイティブに比べれば劣りますが、多少低スペック向けにゲームを調整すれば Blazor 版でも十分に実用に耐えられるゲームが動かせると思います。
バージョンアップの経緯
今回 Blazor 版で実装するにあたりライブラリの中の `SoundEffect.Volume` で不具合を見つけたのでコミュニティの Blazor のスレッドで報告しました。Blazor 版のライブラリはお試し版であることもあり、せっかくゲームを動作させてみたので Blazor で動かしてみたらこうなったよ、という動画も一緒に作って投稿しました。動画にはブログのリンクも付けてあります。
その後コミュニティで nkast さんから返信を頂いたのですが、回答を頂いた内容を見るとコミュニティに投稿した内容や動画の内容だけではなく、私がブログに書いた内容についても回答を頂いていました。本人に確認したわけではないので本当かどうかは分かりませんが、おそらく日本語で書いたブログをわざわざ読んでいただいたんだと思います。
前回の調査内容に対しての相違点
先述の通り、nkast さんに前回の記事を読んでいただいたらしく、いくつかの調査内容は正しくないものがあるようでした。以下相違点について記載します。書いてる内容はコミュニティで回答いただいたものと同じです。
Effect (.fx) コンテンツはシェーダモデル 2.0 まで対応可能
前回 Effect コンテンツはサポートされていないと書きましたがシェーダモデル 2.0 までなら対応されているようです。確かに私がゲームで使用していたのはシェーダモデル 4.0 なので対象外ですね。
ちなみにシェーダモデル 2.0 にしたら動きました。
Load 用コンテンツ (.xnb) の配置場所
こちらについてはコンテンツを実行ファイルに埋め込むか、静的ファイルとして `/wwwroot/Content/` に配置するかの2択であることは前回説明した通りです。
`/wwwroot/Content/` に配置した際にうまく読み込めない件については Web サーバーで .xnb ファイルの MIME タイプを 'application/octet-stream' にするとうまくいくという回答を頂きました。ただ、こちらは試していないので実際に使う方は正しく動くか確認してみてください。
SpriteFont.Characters は使えない
どうやら Blazor 版では `SpriteFont.Characters` の代わりに `SpriteFont.Glyphs` を使うようです。現在 MonoGame の正式版では `SpriteFont.Characters` が使われてるので今後 `SpriteFont.Glyphs` に置き換わる可能性はあるかもしれません。
まとめ
前のバージョンでは Blazor+WebGL で高負荷のゲームを動かすのはなかなか難しいという印象を受けましたが、今回のバージョンアップで2Dスプライトの描画性能が飛躍的に上がったので、Web 上でゲームを動かすのもかなり現実味を帯びてきたと思います。パフォーマンス的には Silverlight + XNA に近いレベルになったのではないかと思います。これなら体験版としてゲームを作って Web で公開するという方法も行けそうな気がしました。
MonoGame で制作したゲーム「リトルセイバー」を Web (Blazor + WebGL) で動かしてみた話
Web で動くゲームを作ってみようと思った話
現在 Steam や DLsite, Microsoft Store, Google Play で配信中のアクションゲーム「リトルセイバー」ですが、動作フレームワークとして「MonoGame」を使用しています。
当ゲームは有料での販売であるため各々で体験版を配布しているのですが、よりお手軽にゲームを体験できるようにするために開発中のデモ版も含めて以前まで Web で公開していました。
その時は「Silverlight + XNA」をフレームワークとして作り公開していましたが、残念ながら 2021 年にサポートが終了し、唯一動く IE もサポートが終了してしまったため、現在 Web で試せる環境はなくなってしまいました。まあ一応「β版開発室」にはずっとページは残っているのですが。
Unity など他のゲーム開発プラットフォームでは WebGL がサポートされていたりしますが、MonoGame では現時点で Web 版はサポートされていません。しかし実験的に開発はしているらしく、コミュニティを見てみたら一応 Web 上で動くライブラリを公開しているようでした。
内部的な動作ベースは WebAssembly となっているため、これまでの Flash や Silverlight とは異なり多くのブラウザでサポートされています。今後 (現在もですが) Web ブラウザで手軽に遊べるゲームを作るなら WebAssembly + WebGL ベースで作るのが良いかと思います。
WebGL で動かせるライブラリが見つかったので、今後 Web でゲームのお試し版を公開する可能性があるかもしれないことも考え、試しに現在のゲームを Web 版で動かせるかどうか試してみました。
実際に動かしてみた動画
実際にどうやったのかなどは後で書きますが、結果としては「動かすこと」はできました。どんな感じに動いているかは動画としてアップしましたので見てみてください。
ニコニコ動画
Youtube
ちなみにこのゲームを動かしているサイトは開発目的で作ったものなので非公開となっており一般の方が遊ぶことはできません。理由としては使用しているライブラリがまだ未完であるのと、遊べるレベルまで最適化するのが非常に面倒だったためです。
使用しているライブラリなど
今回使用しているライブラリは MonoGame の開発者でもある nkast さんが個人的に作ったライブラリとなっています。
該当するコミュニティのページは以下となっています。
またビルド・実行可能なサンプルプログラムも公開されています。
フレームワークとしては「Blazor WebAssembly」+「WebGL」+「.NET 6」+「C#」で動く形となっています。
動くプログラムを確認するならサンプルプログラムを触ってみるのが手っ取り早いですが、ライブラリは nuget でも公開されているので新規プロジェクトとして制作することもできます。
プログラムの移行に関していろいろやったこと
WebGL 版も MonoGame ベースのフレームワークとして作られているので大部分のコードについては変更することなく移行することができました。ただ本ゲームは 2D ベースなので 3D ベースのゲームプログラムの場合はどのぐらい影響があるかは分かりません。また、大部分は変更はありませんでしたが Web ブラウザで動くプログラムになってしまうので、いくつかは変更が必要になるものはありました。ここではゲーム固有部分ではなく誰にでも影響がありそうな修正箇所についていくつか書いてみたいと思います。
Effect (.fx) コンテンツは使用できない
デフォルトで実装されているエフェクトは分かりませんがコンテンツパイプラインから読み込む形の Effect は使用できないみたいです。`Content.Load` で読み込もうとした時点でエラーになります。2D でもカスタマイズした描画を実行している場合は注意が必要です。3D は特に影響が大きいのではないでしょうか。
リトルセイバーでは被弾時の白点滅にエフェクトを使っていたのですが今回省きました。
Song クラスは使用できない
BGM 再生などに使用されることがある `Song` クラスは使用できません。こちらも `Content.Load` でエラーになります。BGM を流したい場合は効果音と同じ `SoundEffect` クラスを使用する必要があります。`Song` クラスはストリーム再生できるメリットがあるのですが汎用性が低いこともあり、リトルセイバーでは `SoundEffect` で BGM を再生していたため手間はあまりありませんでした。
GamePad は使用できない
`GamePad` クラスで何らかのアクセスをしようとしただけでエラーになります。キーボードやマウスは使用可能です。Web ブラウザではゲームパッドの対応が元々難しかったりするので仕方ないですね。
Load 用コンテンツ (.xnb) を実行ファイルに埋め込み
WebGL 版のライブラリでは `wwwroot` フォルダ内にあるファイルからコンテンツを読み込むように作成されていますが、テスト段階でなぜか読み込めない場合がありました。キャッシュの問題なのかなんなのか不明だったため、コンテンツファイルはすべて「埋め込みリソース」として実行ファイルに埋め込むようにしました。これが原因か分かりませんが、先述のサンプルプログラムでも一部そのようにカスタマイズして読み込んでいるコードがあったりします。
コンテンツファイルを埋め込むと初回ダウンロード時にすべてのファイルをダウンロードする必要があるので読み込みに時間が掛かります。ただし、全て読み込んでからゲームを動かすのでゲーム実行中の読み込みスピードは上がります。逆に `wwwroot` に置くパターンは初回のゲーム読み込みは早いですが、コンテンツが必要なタイミングでインターネットからダウンロードするので途中の読み込みは遅くなります。
テクスチャーで Dxt3 は使用できない
おそらく WebGL 版にデコーダーがないので `Content.Load` でエラーになります。`SpriteFont` もデフォルトでは `Compressed` (Dxt3) になっているので、普通に作ってるとエラーになります。テクチャーフォーマットは `Color` にしておけば大丈夫です。
SpriteFont.Characters は使えない
使っている人がいるかどうかは分かりませんが `SpriteFont` に何の文字が含まれているかをチェックするためなどの目的で `Characters` プロパティは使用できません。
暗号化やハッシュのライブラリは使用できない
これは MonoGame 側の話ではなく Blazor 側の話です。一応クラスはあるのですが使おうとするとサポートされていないという Exception が発生します。代わりに `BouncyCastle.NetCore` などのサードパーティライブラリを使用する必要があります。ただ今後の .NET のバージョンで暗号化やハッシュがサポートされる可能性はあります。
ローカルファイルへの書き込みはできない
Web ブラウザで動作するものなのでローカルへのファイル書き込みは出来きず代案が必要となります。...とはいうものの実は一時的にできたりはしますが、結局は永続化はできないので対処は必要です。ローカルストレージやインターネット上の Web ストレージなどを使用する必要があります。
SoundEffect の音量が正しく設定できない
これはおそらく不具合だと思うのですが、`SoundEffect.Volume` プロパティを設定しても必ず 100% の音量で再生されてしまいます。対処法としては元のサウンドファイルの音量を下げるしかないのですが、さすがに面倒なので放置しています。ただなぜか再生中には音量は変更できるようです。
パフォーマンス関連
おそらくこれが一番影響がでかいのではないかと思います。ネイティブで動くコードと WebAssembly で動くコードではパフォーマンスに大きな差があるため、ネイティブでギリギリまで調整して動いているプログラムは Web で動かそうとするとほぼ動かすことが困難になるのではないかと思います。ちなみにどれぐらいパフォーマンスが落ちるかについては先述の動画で確認できると思います。
ただ WebAssembly はまだ発展途上なので今後少しづつ改善はされていくと思います。それでもネイティブに勝てることはないと思うので Web 版が正式リリースの対象に含まれているゲームの場合は定期的にパフォーマンスの確認をしていった方がよいと思います。
まとめ
今回 WebGL 版としてゲームを動かせるか試してみたのですが、目的としてはローカルで動くゲームをまずは手軽に Web 上で遊んで確認できるような環境を作りたかったというのがあります。
リトルセイバーについてはすでに本リリースしているので今のところそういう環境が必要という場面にはなっていないですが、今後そういったこともあるかもしれないので興味的なものも含めて試してみました。
もしかしたら WebGL でゲームを公開してみたいという方もいるかもしれないので、この調査結果が大なり小なりでも参考になればいいかなと思いました。
MonoGame 3.8.1 で「共有プロジェクトにある mgcb ファイルをダブルクリックしても MGCB Editor を開けない問題」「MGCB Editor でビルドしても無反応な問題」の対応方法
共有プロジェクトにある mgcb ファイルをダブルクリックしても MGCB Editor を開けない問題
まずこの現象については MonoGame 3.8.1 のテンプレートから「MonGame Shared Library Project」を作成すれば確認できます。今回の共有プロジェクトは mgcb がビルドできるので便利です。
作成後「Content/Content.mgcb」をダブルクリックしても MGCB Editor は起動しません。
ちなみに他のプロジェクトはダブルクリックすれば開けます。
MGCB Editor でビルドしても無反応な問題
まず他のゲームプロジェクトで開いた MGCB のプロジェクトはビルドをすれば通ります。
しかし、この MGCB Editor から他の MGCB プロジェクト、例えば先ほどの共有プロジェクトで作成された mgcb ファイルや、他のフォルダにコピーした mgcb ファイルを開いてビルドしても全く無反応になります。
対処方法
他のプロジェクトとの差異を調べてみたのですがどうやら mgcb ファイルのある場所から見て「..\.config\dotnet-tools.json」ファイルがあるかどうかでダブルクリックで開けたりビルドができるようになるみたいです。
なので共有プロジェクトの場合は、一度他の MonoGame のプロジェクトを作成してから「.config」フォルダを共有プロジェクトにコピーすればダブルクリックで開けるようになり、ビルドもできるようになるみたいです。
ちなみにプロジェクトとは全く関係ない場所に mgcb ファイルを置いている場合は下の図のように1階層上のフォルダに .config フォルダを置いておけばビルドはできるみたいです。ちょっといまいちですが。まあ単独でビルドすることはあまりないとは思います。
ちなみになぜこんなことになっているかというと、OS に MGCB Editor をインストールさせてしまうと、バージョンの異なるプロジェクトが複数あった場合に問題になることが多いため、プロジェクトにくっつけてしまいバージョンは全てプロジェクト依存にさせれば問題はなくなるだろう、ということらしいです。以下の記事にそれっぽいことが書いてありました。
【MonoGame】 3.8.0 の MGCB Editor を削除する方法
2022/07 に MonoGame 3.8.1 がリリースされ MonoGame のテンプレートや MGCB Editor は Visual Studio 2022 の拡張機能に全て統合されました。
ただ、3.8.0 で使用していた MGCB Editor は「dotnet tool」でインストールしているため、3.8.1 をインストールしたあとも残り続けます。これを削除するにはコマンドプロンプトなどで以下の手順を実行します。
インストールされている .NET Tool を確認します。
dotnet tool list --global
その中に以下のものがあるか確認します。
- dotnet-mgcb 3.8.0.1641 mgcb
- dotnet-mgcb-editor 3.8.0.1641 mgcb-editor
あった場合は以下のコマンドをそれぞれ実行して削除します。
dotnet tool uninstall --global dotnet-mgcb
dotnet tool uninstall --global dotnet-mgcb-editor
もう一度リストを表示してなくなっていることを確認します。
ちなみにスタートメニューには MGCB Editor のショートカットは残ってしまうのでクリックして削除してください。
MonoGame 公式サンプルプログラムの Tips を2本公開しました
MonoGame の公式サイトにサンプルプログラムがあるのですが、公開されているものはすべて英語コメントでプロジェクトのみがアップロードされている形となっています。
なので今回その中から最初の2つを日本語で解説しつつコメントの日本語化してみました。以下の2つのサンプルが対象です。
- Aiming
- Audio3D
他のプロジェクトも解説していこうかと思ったのですが、現在公開されているサンプルは以前の MonoGame のバージョンで作られたものも多く、残念ながらそのまま MonoGame 3.8 に持っていけないものもあったため移行作業は中断しています。
今後の公開については気が向いたらレベルで見ていただければと思います。
公開ページは以下の場所にあります。
ゲーム「リトルセイバー」の公開時期変更について
ゲーム「リトルセイバー」の開発も佳境に入り2月に公開を予定しておりましたが、予想以上にゲーム制作のほうに時間が取れなかったのとテストに時間がかかっていることもあり、2月の公開が難しい状況となっております。そのため、ゲームのリリースは3月にずれ込む見込みとなってしまいました。ゲームの公開とプレイを楽しみにされていた方申し訳ありませんでした。
とはいうものの何もせずにそのまま3月に流してしまうのも申し訳ないので、本来完全版と体験版のリリースを同時に行う予定でしたが、先に体験版のみをリリースしようかと思います。
体験版の公開日については2月ぎりぎりの28日をめどに公開を予定しています (とはいっても平日にとれる作業時間が皆無なのでこれも厳しいと言えば厳しいのですが…)。体験版の中身については1月に仙台コミケで配布した体験版CDからいくつか修正の入った Ver 1.01 版となります。Ver 1.00 と同様最初のいくつかのステージが遊べるようになっているのとイベントシーンなどが省かれたものとなっています。主に戦闘などをメインに遊べるバージョンとなっております。注意点としてはセーブデータは完全版のほうには引き継ぐことはできません。
完全版のリリース時期についてはもう2~3週間ほど先になるかと思います。申し訳ありませんがそれまでもう少々お待ちください。
]]>