はじめに

BlenderでGLBの作成及び、animationを追加して、Three.jsで読み込み表示するまで本日実装したので、ざっくりとした実装までの流れをAIにまとめてもらいました。
大変なのは、実装よりも個人的にBlenderの操作の方で、かなり手間取って時間がかかりました。

以前、勉強でモデリングをいくつか作った事はあるのですが、また少しずつ触って使い方を覚えたいと思います。

3Dゲームにありがちな、カメラの向きにあわせてキャラクターの進行方向を変える処理など、2Dでもおなじみのアークタンジェントを使った回転処理など、2D以上に物理演算を使うので大変です。

とはいえ、Three.jsを使えば、ここまで出来るというのは驚きですし、物凄く面白いです。

javascriptはほんと、何でもできるので無敵ですね。

1. GLBの作成方法:

1.1. Blenderで3Dモデルを作成する

まず、Blenderを使って基本的な3Dモデルを作成します。Blenderは無料で使える強力な3Dモデリングツールで、GLB形式でのエクスポートにも対応しています。

1.1.1. Blenderのインストール

Blenderをまだインストールしていない場合は、公式サイトからダウンロードしてインストールします。

1.1.2. 基本的な3Dモデルを作成

Blenderを開いて、新しいプロジェクトを開始します。

  1. デフォルメッシュの選択:

    • Blenderを開くと、デフォルメッシュ(立方体など)が自動でシーンに表示されます。このメッシュを使ってモデルを作成することができます。
  2. モデルの編集:

    • モデルを選択し、Edit Mode(編集モード)に切り替えて、頂点や辺を移動、拡大、縮小して、自分の好きな形に整えます。

    • 基本的な操作:

      • 選択: 右クリックでメッシュを選択。
      • 移動: G(Grab)でメッシュを移動。
      • 回転: R(Rotate)でメッシュを回転。
      • スケーリング: S(Scale)でメッシュを拡大縮小。
  3. 完成形の調整:

    • ここで、3Dキャラクターの顔や体、服などをモデリングします。もし簡単なオブジェクトを作るのであれば、例えば箱(Cube)や球(Sphere)を使って、全体の形を整えていきます。

1.1.3. アーマチュア(骨組み)の作成

アニメーションを付けたい場合、アーマチュア(骨組み)を作成して、メッシュにアーマチュアをウェイトペイントで結びつける必要があります。

  1. アーマチュアの追加:

    • Shift + Aを押して、Armature(アーマチュア)を選択します。これで骨組みが作成されます。
  2. ウェイトペイント:

    • アーマチュアが作成されたら、メッシュを選択し、Weight Paintモードでアーマチュアの各部分とメッシュを関連付けます。この作業は、アニメーション時にどの部分がどの骨に動かされるかを決定します。

1.2. GLB形式でエクスポートする

3Dモデルが完成したら、次にGLB形式でエクスポートします。GLBはバイナリ形式のGLTF(GL Transmission Format)で、Webやゲームエンジンなどで広く使われています。

1.2.1. エクスポートの準備

エクスポートする前に、以下のポイントを確認しておきましょう。

  1. メッシュとアーマチュアを選択:

    • 全てのオブジェクト(キャラクターや道具など)を選択します。Shiftを押しながらクリックすることで、複数のオブジェクトを選択できます。
  2. マテリアルとテクスチャの確認:

    • マテリアルやテクスチャが適用されていることを確認します。GLBでは、テクスチャが正しくエクスポートされることが重要です。
  3. スケールと位置の確認:

    • モデルのスケール(大きさ)や位置が適切であることを確認します。必要に応じて調整します。

1.2.2. GLB形式でエクスポート

  1. エクスポートメニューを開く:

    • 上部メニューの File -> Export -> glTF 2.0 (.glb) を選択します。
  2. エクスポート設定を行う: エクスポート設定では、以下のオプションを調整できます:

    • Format: glTF Binary (.glb)を選択。GLB形式を選ぶと、バイナリ形式でエクスポートされます(ファイルサイズが小さくなる)。
    • Include: Selected Objects を選ぶと、選択したオブジェクトのみエクスポートできます。
    • Transform: エクスポート時にスケールや位置を調整したい場合、ここで設定できます。
    • Animation: Animation チェックボックスをオンにして、アニメーションも含めてエクスポートします。
  3. エクスポートを実行:

    • エクスポート先のフォルダを指定し、エクスポートをクリックします。

1.2.3. エクスポート後の確認

エクスポートが完了したら、GLBファイルをThree.jsや他のツールで読み込み、モデルやアニメーションが正しく表示されることを確認します。


1.3. エクスポート時の注意点

  • テクスチャの管理:

    • テクスチャを使っている場合は、相対パスでリンクされていることを確認してください。エクスポート時にテクスチャがGLBファイルに埋め込まれるため、テクスチャファイルが正しく配置されているかを確認します。
  • アニメーションの設定:

    • アニメーションをエクスポートする場合、アーマチュアが正しく設定されていることを確認し、アニメーションの設定をエクスポート時にオンにします。
  • スケーリングの調整:

    • Blenderのスケールとエクスポート後のスケールが異なる場合があります。GLBファイルが読み込まれたときに、サイズが不適切になる場合がありますので、スケールを確認しましょう。

2. Three.jsでGLBモデルを読み込む

2.1. GLBファイルの読み込み

まず、Three.jsでGLB形式の3Dモデルを読み込む方法について説明します。Three.jsでは、GLTFLoaderを使用してGLBファイルを読み込むことができます。

2.1.1. GLTFLoaderのインポート

GLTF形式のファイルを読み込むには、まずGLTFLoaderをインポートします。Three.jsのGLTFLoaderは、GLTFやGLBファイルを読み込むためのクラスです。

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

2.1.2. GLBファイルの読み込み

GLTFLoaderを使ってGLBファイルを読み込み、シーンに追加します。以下のコードは、GLBファイルを読み込んで表示する基本的な方法です。

const loader = new GLTFLoader();

loader.load(
  'path/to/your/model.glb', // GLBファイルのパス
  (gltf) => {
    // 読み込んだモデル(gltf.scene)をシーンに追加
    const model = gltf.scene;
    scene.add(model);

    // 読み込んだモデルのスケールや位置を調整
    model.scale.set(1, 1, 1);
    model.position.set(0, 0, 0);

    // アニメーションがあれば再生
    if (gltf.animations && gltf.animations.length) {
      const mixer = new THREE.AnimationMixer(model);
      gltf.animations.forEach((clip) => {
        mixer.clipAction(clip).play();
      });

      // アニメーションの更新処理
      function animate() {
        requestAnimationFrame(animate);
        mixer.update(0.01); // アニメーションの更新速度
        renderer.render(scene, camera);
      }
      animate();
    }
  },
  (xhr) => {
    // 読み込み進行状況の表示
    console.log((xhr.loaded / xhr.total * 100) + '% loaded');
  },
  (error) => {
    console.error('An error occurred while loading the model:', error);
  }
);

2.1.3. コードの説明

  • GLTFLoaderを使ってGLBファイルを読み込み、成功時にはそのシーンをシーンに追加します。

  • アニメーションの処理:

    • GLBファイルにアニメーションが含まれている場合、AnimationMixerを使用してアニメーションを制御します。
    • mixer.update(0.01)でアニメーションを更新し、renderer.render(scene, camera)でシーンをレンダリングします。

2.2. GLBモデルの位置やスケールを調整

読み込んだ3Dモデルの位置やスケールを調整することができます。例えば、モデルが大きすぎる、または小さすぎる場合に、スケールを調整して画面に適切に表示させることができます。

model.scale.set(1, 1, 1); // モデルのスケールを調整(X, Y, Z軸)
model.position.set(0, 0, 0); // モデルの位置を調整

2.3. カメラをモデルに合わせて調整

モデルがシーンに追加されたら、カメラの位置も調整してモデルが見えるようにします。例えば、モデルの周りにカメラを配置して、その向きをモデルに向けることができます。

camera.position.set(0, 1, 3); // カメラの位置を調整
camera.lookAt(model.position); // カメラがモデルを見るように設定

これで、カメラがモデルを常に見ている状態になります。


3. アニメーションの制御

GLBファイルにはアニメーションが含まれている場合があり、そのアニメーションをThree.jsで制御する方法を説明します。

3.1. アニメーションの再生

GLBファイルに含まれるアニメーションは、THREE.AnimationMixerを使って再生します。アニメーションが読み込まれると、gltf.animationsにアニメーションデータが格納されているので、それを利用して再生できます。

const mixer = new THREE.AnimationMixer(model);
gltf.animations.forEach((clip) => {
  mixer.clipAction(clip).play(); // アニメーションを再生
});
  • AnimationMixer: アニメーションを管理するためのクラスです。
  • clipAction(clip): ここで、指定したアニメーションクリップをアクションとして登録します。
  • play(): アクションを再生します。

3.2. アニメーションの更新

アニメーションを更新するには、毎フレームごとにmixer.update()を呼び出します。このメソッドでアニメーションが進行し、シーンが再描画されます。

function animate() {
  requestAnimationFrame(animate);
  mixer.update(0.01); // アニメーションを進める
  renderer.render(scene, camera); // シーンをレンダリング
}
animate();
  • mixer.update(0.01): アニメーションの進行速度を設定します。ここでは0.01で進行させています。

3.3. アニメーションの停止・切り替え

アニメーションを停止したり、他のアニメーションに切り替えることも可能です。mixerを使ってアニメーションの操作を行います。

3.3.1. アニメーションの停止

mixer.stopAllAction(); // 全てのアニメーションを停止

3.3.2. アニメーションの切り替え

mixer.clipAction(clip).stop(); // 現在のアニメーションを停止
mixer.clipAction(newClip).play(); // 新しいアニメーションを再生

これで、アニメーションの切り替えが可能になります。


4. カメラの向きに合わせたキャラクターの移動

最後に、カメラの向きに合わせてキャラクターを動かす方法を解説します。

4.1. カメラの回転に基づく移動

カメラが回転することで、キャラクターの進行方向も変える必要があります。これを実現するには、カメラの向きを取得し、キャラクターの移動方向をそれに合わせるようにします。

// カメラの回転に合わせてキャラクターの進行方向を変更
const cameraRotation = config.camera.rotation.y; // カメラのY軸回転
const moveDirection = new THREE.Vector3(0, 0, 0);

// 上方向キー(W)でキャラクターを前進させる場合
moveDirection.z = Math.cos(cameraRotation) * config.character.speed;
moveDirection.x = Math.sin(cameraRotation) * config.character.speed;

// キャラクターを移動させる
config.character.box.position.add(moveDirection);

4.2. 移動後にキャラクターを回転

移動した後、キャラクターが進行方向を向くように回転を調整します。

const moveAngle = Math.atan2(moveDirection.x, moveDirection.z);
config.character.box.rotation.y = moveAngle; // 移動方向に合わせて回転

これで、カメラの向きに基づいてキャラクターが進行方向を変更し、回転して移動します。


まとめ

このセクションでは、GLB形式のモデルの読み込みから、アニメーションの制御、さらにカメラの向きに合わせたキャラクターの移動に関する実装方法を紹介しました。

  • GLBの読み込み:GLTFLoaderを使って、3Dモデルとアニメーションを読み込む方法を説明しました。
  • アニメーション制御:THREE.AnimationMixerを使ったアニメーションの再生、停止、切り替え方法について説明しました。
  • キャラクターの移動:カメラの回転に合わせてキャラクターが進行方向を変更し、移動する方法を解説しました。

この方法で、GLBファイルを活用したインタラクティブな3Dキャラクター移動が可能になります。次のステップとして、さらに物理エンジンを使った衝突判定や反発処理を組み合わせることで、リアルな動作を実現できます。