React Three Fiberとデータ駆動による3D-ADVシステムの設計と実装仕様
React Three Fiberとデータ駆動による3D-ADVシステムの設計と実装仕様
本書は、React Three Fiber(R3F)およびThree.jsを用いて構築した、3Dアドベンチャー(ADV)探索システムのアーキテクチャおよび実装内容をまとめた技術リファレンスです。
本システムは、ステージ構成、プレイヤー能力値、アバター設定をすべて独立したJSONデータで定義する「データ駆動型設計」を採用し、コンポーネント間の疎結合性を担保しています。
Three.js / Astroで多層世界の3Dアドベンチャーゲーム基盤を1日で制作(VRM / データ駆動)
Astro + Three.js(React Three Fiber)を使って、Webブラウザ上で3D RPG/アドベンチャーゲームの基盤を、ほぼ1日で作成した開発記録・デモ動画です。【実装プロトコル一覧】・JSON(データ駆動)による複数ステージ、ワープポイント、NPCの完全支配・ステージ遷移に伴うBGMの動的...
www.youtube.com1. 全体アーキテクチャとコンポーネントの責務
システムは以下の6つのモジュールおよびデータレイヤーに分割され、単一責任の原則に従って設計されています。
| コンポーネント / ファイル | 主要な責務・役割 |
|---|---|
ADVManager.tsx | システムの最上位に位置するマスターコンポーネント。現在のステージID(State)を保持し、画面フェードの実行および各サブコンポーネントの仲介を行います。 |
ADVController.tsx | キーボード入力の検知、プレイヤーの物理移動計算、接地判定、および三人称(TPS)カメラの追従軌道計算を担当します。 |
ADVStage.tsx | 背景となる3Dモデル(GLTF/GLB)のロードと描画、およびポリゴンのチラつき(Zファイティング)の自動補正を行います。 |
ADVAvatar.tsx | プレイヤーアバター(VRM)のロード、スケール・高さオフセットの適用、およびボーン構造へのアニメーション適用を担当します。 |
ADVNPC.tsx | 空間内のノンプレイヤーキャラクター(VRM)の配置、常時アイドリングアニメーションの駆動、およびプレイヤーとの2次元距離判定によるテキスト展開を行います。 |
useADVAnimation.ts | three-vrm-animation を用いて、VRMのボーン構造(Humanoid)に対して安全にモーションを再生・ブレンドするためのカスタムフックです。 |
2. コア機能の実装詳細
① データ駆動によるステージとイベントの統治(Stages.json)
ステージ情報、ワープポイント(座標・当たり判定)、および配置NPCのパラメータはすべて外部のJSON(Stages.json)で統合管理されています。
- 空間ワープトリガー:
ADVController内において、プレイヤーの現在座標(XZ平面)とJSON内に定義されたwarpPointsの中心座標との距離を毎フレーム計算しています。指定された閾値(radius)未満に侵入した際、トップレベルのonWarpハンドラを発火させ、ステージ遷移(IDの上書き)を実行します。 - NPCの動的マウント:
ADVManagerは、選択されたステージJSONのnpcs配列をマップループ処理し、必要なアセットURLをキャッシュ機構から解決した上でADVNPCコンポーネントを動的に空間へ配置します。
② ローポリモデルにおけるチラつき(Z-Fighting)の根絶(ADVStage.tsx)
インポートした背景3Dモデルにおいて、重なり合うポリゴンや透過デカール、白線メッシュが描画時に点滅する不具合を解決するため、マテリアル階層への介入処理を実装しています。
- ロードされた
sceneをtraverse(巡回)し、各子メッシュを走査します。 - メッシュの名称(例:
line,cross,decal,stripe)またはマテリアルのtransparent(半透明)属性を検知します。 - 条件に合致したマテリアルに対し、
polygonOffset = true、polygonOffsetFactor = -1、polygonOffsetUnits = -1を動的に適用し、描画優先度を強制的に手前に補正することでチラつきを完全に抑制します。
③ ピュア3Dによる高没入型画面フェード(ADVManager.tsx)
ステージ遷移時の画面暗転(フェードアウト・フェードイン)において、WebのDOM要素を被せるのではなく、3D空間内で完結するシェーダー制御を採用しています。
- 実装構造: カメラのレンズの直前(
position.set(0, 0, -0.1))に、カメラのトランスフォームに完全追従するピュアな3Dメッシュ(平面ポリゴン)を密着配置しています。 - アルゴリズム:
useFrameのループ内でfadeState(fade-out/fade-in)を監視し、デルタ時間(経過時間)を基にマテリアルの不透明度(opacity)を0.0から1.0の間でリアルタイムに増減させ、破綻のない暗転を実現しています。
④ 2次元距離判定に基づく吹き出しコンポーネントの自動展開(ADVNPC.tsx)
NPCのセリフ表示システムは、高負荷な3次元空間計算を避け、水平面(XZ平面)に投影した効率的な距離計算プロトコルを実装しています。
- 毎フレーム、
ADVNPCの固定座標と、親から渡されるプレイヤーアバターの最新座標をTHREE.Vector2に変換します。 distanceTo()メソッドを用いて2点間の直線距離を算出します。- 距離が2.0メートル未満となった場合に
showBubbleステートをtrueに切り替え、以前構築した独自のWiredSpeechBubble(吹き出し)UIを空間上に展開します。領域外へ離脱した場合は自動的に非表示へと切り替わります。
⑤ 初期化バグを防止する生存チェックガード(useADVAnimation.ts)
非同期でロードされるVRMアバターのボーン構造に対し、初期化前にアニメーションを適用しようとすることで発生する描画バグ(座標の消失やモデルのフリーズ)を、厳格なガード句によって回避しています。
- 制御プロトコル: アニメーションの再生フックである
useADVAnimationの内部において、GLTFモデル内のuserData.vrm(VRMコア構造およびボーンデータ)の生成が完了したか否かを真偽値(vrmReady)で検証します。 - 動作:
gltfインスタンス、vrmReadyフラグ、およびミキサーの参照がすべて出揃うまでreturnによる早期離脱(処理スキップ)を徹底し、安全性が確保された直後に、プレイヤーの移動状態(isMoving)に応じた走行モーション(SYS_RUNNING)または待機モーション(IDLE_CHANGE_POSE)へのクロスフェード移行を開始します。
3. 拡張データ構造(PlayerGrowth.json)
プレイヤーの成長曲線およびバトルシーンへの移行を見据えたステータス管理コンテキストとして、以下のJSONスキーマが定義されています。
[
{
"level": 1,
"nextExp": 50,
"maxHp": 100,
"maxMp": 30,
"attack": 10,
"skills": ["MAGIC_SHOT"]
},
{
"level": 2,
"nextExp": 120,
"maxHp": 120,
"maxMp": 45,
"attack": 15,
"skills": ["MAGIC_SHOT", "HEAL"]
}
]
このデータ構造は、今後実装を予定しているバトルマネージャー(ターン制またはリアルタイム戦闘のステートマシン)における最大HPの参照や、コマンドUIに動的に展開する利用可能スキルの制御バインダーとして機能する設計となっています。