はじめに
プレイヤー以外のキャラクターに徒歩アニメションを追加して、フィールド内を自動で散歩するアニメーションを実装してみたので、そのメモです。
衝突判定で、ポップアップメッセージを出せば、街で村人との会話のような実装も可能だと思います。
かなり大変ですが、 Three.jsでRPGゲームの作成も可能ですね…。
その他、VRに対応しようとしてたのですが、うまくいかなくて先送りになってます。

1. キャラクターの自動散歩の実装
1.1 キャラクターの基本的な移動
まず、キャラクターを指定された経路(path)に沿って自動で移動させます。キャラクターは指定されたルートを順番に進み、ターゲット地点に到達したら次のターゲットに進むようにします。以下にその基本的なコードを示します。
class CharacterWalk {
constructor(name, model, path) {
this.name = name; // キャラクターの名前
this.model = model; // モデル(THREE.jsオブジェクト)
this.path = path; // 移動するターゲットポイントの配列
this.speed = 2; // 移動速度
this.currentTargetIndex = 0; // 現在のターゲットインデックス
}
update(deltaTime) {
if (this.path.length < 2) return; // 2つ以上のポイントがない場合、移動しない
const target = this.path[this.currentTargetIndex];
const direction = new THREE.Vector3().subVectors(target, this.model.position).normalize();
const distance = this.model.position.distanceTo(target);
// 目標地点に近づいたら次のターゲットへ
if (distance < this.speed * deltaTime) {
this.model.position.copy(target);
this.setNextTarget();
} else {
// 進行方向に回転させる
this.model.lookAt(target); // モデルをターゲットの方向に向ける
const moveDistance = direction.multiplyScalar(this.speed * deltaTime);
this.model.position.add(moveDistance);
}
}
setNextTarget() {
this.currentTargetIndex++;
if (this.currentTargetIndex >= this.path.length) {
this.currentTargetIndex = 0; // 最後のターゲットに到達したら先頭に戻る
}
}
}
解説
path: 進むべきターゲットポイントの配列です。キャラクターはこの配列に沿って移動します。update(deltaTime): このメソッドはキャラクターを移動させるために呼び出されます。deltaTimeはフレームごとの経過時間です。setNextTarget(): キャラクターが次のターゲットへ進むために使用されるメソッドです。
1.2 自動回転
キャラクターが進行方向に回転するためには、lookAt()メソッドを使います。これにより、キャラクターはターゲットの方向に自動的に向きます。
this.model.lookAt(target); // モデルをターゲットの方向に向ける
lookAt()メソッドは、キャラクターがターゲットに向かって回転するため、キャラクターが進行方向に向かって動きます。
2. 衝突判定の実装
キャラクターが自動で移動する際、周囲に障害物があるかどうかを確認する必要があります。そこで、Three.jsのBox3(3Dボックス)を使用して、衝突判定を行います。
2.1 衝突判定ボックスの生成
Box3を使用して、キャラクターの周囲の空間を表現します。ボックスは、最小点(min)と最大点(max)を使用して定義されます。
const box = new THREE.Box3();
const boundingBox = modelData.boundingBox;
box.set(
new THREE.Vector3(
position[0] + boundingBox.min[0],
position[1] + boundingBox.min[1],
position[2] + boundingBox.min[2]
),
new THREE.Vector3(
position[0] + boundingBox.max[0],
position[1] + boundingBox.max[1],
position[2] + boundingBox.max[2]
)
);
ここでは、boundingBoxのminとmaxを使用して、モデルの周囲の衝突判定ボックスを作成しています。
2.2 衝突判定ボックスの更新
キャラクターが移動するたびに、衝突判定用のボックスを更新する必要があります。ボックスの位置はキャラクターの位置に基づいて動的に更新されます。
updateCollisionBox() {
const box = config.model.wallBoxes.filter((box) => box.name === this.name)[0];
if (box) {
// ボックスの位置を移動分だけ更新
const moveDistance = this.model.position.clone().sub(box.min); // 移動量
box.min.add(moveDistance);
box.max.add(moveDistance);
}
}
このメソッドは、キャラクターの移動に応じて、衝突判定ボックスを動的に更新します。
3. 衝突判定の実行
衝突判定を実行するためには、Box3同士が交差しているかをチェックする必要があります。これには、intersectsBox()メソッドを使用します。
if (box1.intersectsBox(box2)) {
console.log('Collision detected!');
}
このコードで、box1とbox2が交差している場合に衝突が検出され、Collision detected!がコンソールに出力されます。
4. まとめ
この記事では、Three.jsを使ってキャラクターの自動移動と衝突判定を実装する方法について説明しました。キャラクターが指定されたルートを自動で歩き、その動きに応じて衝突判定ボックスを更新し、周囲の障害物と衝突しないようにしています。この実装により、3D空間で動くキャラクターの基本的な動作を実現しました。
💬 コメント