🐥

【bevy_baby】Bevyを使ってデスクトップマスコットを開発中です【OSS】

2025/03/05に公開

リンク

バイナリはitch.ioで公開しています!
まだα版ですがよかったらお試しください。

https://notelm.itch.io/bevy-baby

オープンソースで公開しています。
不具合などありましたらIssue頂けると助かります。
PRも歓迎しております。

https://github.com/not-elm/bevy_baby

はじめに

bevy_baby
ウィンドウの上に座らせることができます

baby2
複数のマスコットを配置できます

Bevy、Blender、VRMの学習を兼ねてBevyというRust製のゲームエンジンを使ってデスクトップマスコットの制作を始めました。
マスコットの表示にはVRM1.0、アニメーションはVRMAを使っています。

現状MacOSとWindowsに対応しています。

Bevyについて

Bevy周辺の技術についてしっかりと理解できているわけではないため概要だけ説明します。
BevyはRust製のゲームエンジンでECS(Entity Component System)アーキテクチャ(のみ)をサポートしています。
Entityは他のゲームエンジンにおけるゲームオブジェクトという概念をより抽象化したものと私は捉えています。
Entityの実態はただのIDであり、それ自体はそれ以外の役割はありません。もちろん継承などの概念もありません。EntityにComponentを紐づけることで始めてオブジェクトとしても役割をもたせることができます。
ComponentはComponentStorageというものに格納されており、効率的なメモリ管理ができるらしいです。
当初は単純な配列のようなものなのかなと思っていたのですが、少しBevyのコードを覗いてみたらそんな単純なものではなさそうでした。自分は早々に理解を諦めましたが興味がある方は覗いてみてください。

ECSのもう一つの特徴としてデータ指向が挙げられます。
ざっくりと説明すると、Component自体はただのデータでレンダリングのスケジュールで始めてUIに反映されます。
つまりデフォルトでマルチスレッドに対応されています。
このプロジェクトでもボーンのリターゲットなど重い処理がちょくちょくありますが、そこまで意識しなくても軽快に動くため恩恵をかなり受けています。

アプリの説明

アニメーション

待機、つかみと座るモーションは自作しています。
BlenderとVRMはほぼ知識ゼロの状態からプロジェクトを始めているため、アニメーションを作るのが一番大変でした。
ちなみにつかみモーションは会心の出来だと思っていましたが、BevyのDiscordコミュニティで見せたらアニメーションが不自然だと指摘いただきました...。自然なアニメーションを作るのはムズカシイ。
全然関係ない話ですが、外国人の人は駄目だと思うものははっきりと言ってくれるので開発者目線からしたらありがたいですね。(致命傷は喰らいますが)

アクション

このアプリの特徴的な機能としてアクションというものがあります。
現時点ではアクション=アニメーションです。
例えば"回転する"というアクションを実行すると"rotate.vrma"が再生されます。

少しややこしいのですが、アクションは状態遷移マシンのような役割もあり、それぞれのマスコットは現在のアクションを保持するようにして、変更されたらそのアクションに遷移します。

アクションにはアクショングループが存在し、例えばつかみ状態を表す"drag"というグループの中には"index"と"hold"というアクションが所属しています。
グループは後述するTransitionMode::Autoで使用されます。

TransitionMode

各アクションにはTransitionModeというものがあり、次のアクションへの遷移方法を指定できます。普段の待機状態にはAutoが設定されており、ランダムにアニメーションが再生されるようになっています。

Mode 説明
Auto 一定時間経過後に同グループの別のランダムなアクションに遷移
Manual アクション終了後(アニメーション再生後)に指定のアクションに遷移
None(default) 遷移しない

アクションの拡張

前述した通り、現状アクション=アニメーションですが、今後もっと自由な動作を定義できるようにしたいと考えています。
例えばマスコットの位置やスケールを指定したり、効果音を再生したりなどです。

技術的な部分

VRMの解析

VRMはGltfの拡張らしく、Bevy標準のGltfLoaderでロードできました。
GltfLoaderのSettingsにはinclude_sourceという真偽値があり、これをtrueにすることでソースの情報を取得できます。
VRMの拡張情報はGltfのExtensionsという項目に記載されているため、ロード後に解析する方法で実装しました。
現状ExpressionsとHumanoidBonesを解析していますが、LookAtやFirstPerson(これはよくわかっていない)などの情報もここから取得できます。

メニュー画面

メニュー画面は自作のwebviewを表示するライブラリ、bevy_webview_wryを使って作成しました。
このライブラリは現状あまり使われていませんが、これからもメンテナンス予定なのでよかったらお試しください。
webviewなのでReactのようなライブラリももちろん使えます。
マスコットのスケールなどをwebviewから制御できるようにしましたが、Tauriっぽくコマンドのようなものでやりとりできるようにしているため、比較的楽に実装できました。(自画自賛)

baby3
スケール変更

これからの実装計画

ローカルサーバの構築

ローカル上にHTTPサーバを立てて外部プロセス経由でアクションを制御できるようにしたら意外に需要がありそうだなと思っています。
真っ先に思い浮かぶのがライブ配信ですね。配信画面上にマスコットを表示しておいて特定のコメントが来た時やスパチャが来た際にアクションを取らせるようにしたら配信が映えます(多分
自分自身たまに配信をするので結構欲しい機能だと思っており、優先度高めに実装したいと考えています。

MToonShaderのサポート

現状Bevyデフォルトのマテリアルとシェーダを使っているためMToonShaderに対応できたらいいなと思っています。
ただ、シェーダとかの知識がほぼ皆無なので苦戦することになると思います...。

VRMのボーンリターゲットの改善

サンプルで用意しているVRMやVRMAはBlenderから編集して出力しています。
Blenderから出力されたモデルに関してはうまくリターゲット出来るのですが、Unityから出力されたVRMだと正常にリターゲットできない状況です。

以下の記事を参考にすると、どうやらローカル軸の問題?っぽいです。
正直まだ完全に理解できていないのですが、ここら辺の問題を解決するためには理解必要がありそうなので頑張ります。
https://qiita.com/TokageItLab/items/e5880123a9f508b2769d

SpringBoneの設定

VRMは揺れものの設定ができるらしく、髪の毛や服などを揺らしたり当たり判定をつけられるようです。
Discordで聞いたのですがbevy_vrmというクレート内でこのSpringBoneも実装されているそうなので参考にして実装できたらいいなと思っています。

Look Atのリターゲット

自分の理解が間違っていなければ視線移動を制御する設定です。
これもまだ実装できていないため実装したいです。

パッケージをビルドするGithubActionsの構築

手動でビルドするの面倒くさいので。

最後に

Bevyはまだできたばかりで知名度は低いですが、慣れるとかなり描きやすいゲームエンジンだと思います。(大規模なゲームだと流石にきつそうですが...)
この記事をキッカケで興味を持っていただけたら嬉しいです。
あと、日本人のBevy使いに遭遇したことがないためコミュニティなどあれば教えてください!

参考

https://qiita.com/TokageItLab/items/beaf219762e1e34a6250

https://qiita.com/TokageItLab/items/e5880123a9f508b2769d

Discussion