🌏

Babylon.js 3D Game Editor を作りたいが React が難しい話

2024/06/20に公開

学生の頃からずっと作りたいと思っていた 3D ゲームエディタを試作しているのですが、中々難しいですね。

基本的にブラウザ技術で動き、ランタイムは Babylon.js を採用、という所までは決まっているんですが、それ以降の細かい仕様に関してはまだ模索中です。

昨今のエコシステムを見て、やはり React か、となって GUI を作ろうとしているのですが、 GUI で Vector3 をいじったものを Babylon.js に反映させたり、または 3D 空間でメッシュをつかんで移動させたりした結果を React に反映させたりするとなると、ある程度双方向での変数のバインディングとリアクティビティーが必要になります。

React は基本的に単方向のバインディングを提供するものなので、ここで相性が悪いなとなっています。

Vue は双方向バインディングの思想なのですが、今実現しようとしているものとは若干異なるため、採用してもあまり優位性はないように思います。

DX を考えると、 html と css も TypeScript の型補完を効かせられるとベストです。

html に関しては React などで採用されている tsx フォーマットを使えば解決なんですが、 css はデファクトスタンダードのようなものはまだありません。

強いて言えば Kuma UI などのようなものでしょうか。

https://www.kuma-ui.com/

ただ、これは React をベースにしたライブラリなので、 React を使わなければならないという流れになります。

three.js には three-react-fiber と呼ばれる React ライブラリが存在していて、そちらを使うと React と密接に操作出来る仕組みが提供されています。

https://docs.pmnd.rs/react-three-fiber/getting-started/introduction

これは Mesh や Material など three.js の要素を React Component のように記述することで 3D シーンを表現することが出来る、 React のレンダラの一つです。

Babylon.js には同じようなレンダラ実装が存在しないため、この方式は使えません。

React hooks はリアクティビティーを向上させるために、これまでの jQuery などの js と比べて特殊なアプローチがとられていて、主に変数のライフサイクルが厳密になっています。対して Babylon.js は React のライフサイクル外で動作するため、 Babylon.js の操作をするためには React の useEffect を使う必要があります。

useEffect は React のライフサイクル外の操作(windowdocument を直接操作するなど)を行う際に使われる hooks ですが、これは React のリアクティビティーを損なう動作のため、あまり多用するのは良くありません。

React Babylon.js レンダラを実装すれば回避出来るかもしれませんが、そこまでの技術力はないのと、「 Babylon.js を React で書きたい」わけではなくあくまで「 Babylon.js で使われる変数を React で管理したい」だけなので、レンダラを実装して解決するものでもないです。

Custom hooks を実装して、 useEffect を隠ぺいすると良さそうな気がしますが、 React 力が足りないのでそこのアプローチをうまく思い浮かべられていない状態です。

DX を最優先にすると React / TypeScript / Kuma UI で書くと最強に見えるんですが、 React と和解出来るかはわからない所ですね。

React も 19 になると、 useRef の扱いがベターになったりするみたいなので、楽しみではあります。

半月ほど模索を続けていて全然進捗が出せていないんですが、もう少し React を使いこなせるように考えてみたいと思います。

three.js や Babylon.js で使われる変数を上手に React で管理する方法をご存知の方がいらっしゃいましたらご教授ください。

Discussion