Kick soccer ball
ボタンを押すとサッカーボールが飛びます。
はじめに
ARIの土井です。前回【Babylon.js】Reactを使って3Dモデルを表示するという記事を書きました。今回は物理エンジンを使って実際にサッカーボールを蹴ってみたいと思います。
物理エンジンとは
物理エンジンを使用すると、Scene内に重力を発生させたり、メッシュに質量や反発係数、摩擦係数を設定したりすることができます。詳細は以下のドキュメントを参照してください。
手順
物理エンジンの有効化
物理エンジンの有効化はシンプルで、cannonパッケージをimportしてscene.enablePhysics();
でScene内で物理エンジンを有効化するだけです。
import * as cannon from "cannon";
// 物理エンジン有効化
window.CANNON = cannon;
scene.enablePhysics();
groundの作成
BABYLON.MeshBuilder.CreateGround
関数によって、単純な平面のメッシュを作成します。作成したメッシュにphysicsImpostor
というものを設定することで、質量や摩擦係数、反発係数を設定することができます。groundは重力の影響を受けないように質量を0にしておきます。
// ground作成
const ground = BABYLON.MeshBuilder.CreateGround(
"ground",
{ width: 6, height: 6 },
scene
);
ground.physicsImpostor = new BABYLON.PhysicsImpostor(
ground,
BABYLON.PhysicsImpostor.BoxImpostor,
{ mass: 0, friction: 0.7, restitution: 0.7 },
scene
);
Colliderを使って3Dモデルを剛体にする
読み込んだ3Dモデルを剛体にするためには、Collider
という透明なメッシュを作成し、3DモデルとCollider
をグループ化したメッシュを作成するという方法をとります。サッカーボールは球体なのでsphereCollider
を作成し、isVisible = false
で透明なメッシュにします。このsphereCollider
と3Dモデルをグループ化した親メッシュsoccerBall
を作成し、それに質量や摩擦係数を設定します。
// 親メッシュの作成
const soccerBall = new BABYLON.Mesh("soccerBall", scene);
// soccerBall.babylonからノードの読み込み
const assetsManager = new BABYLON.AssetsManager(scene);
const task = assetsManager.addMeshTask("task", "SoccerBall", SoccerBallAsset);
task.onSuccess = function (task) {
// 読み込んだ3Dモデル
const mesh = task.loadedMeshes[0];
// 球体のColliderを作成
const radius = 0.25;
mesh.position.set(0, -radius, 0);
const sphereCollider = BABYLON.Mesh.CreateSphere(
"sphere",
16,
2 * radius,
scene
);
sphereCollider.isVisible = false;
// 3DモデルとColliderをグループ化
soccerBall.addChild(mesh);
soccerBall.addChild(sphereCollider);
sphereCollider.physicsImpostor = new BABYLON.PhysicsImpostor(
sphereCollider,
BABYLON.PhysicsImpostor.SphereImpostor,
{ mass: 0 },
scene
);
// 親メッシュに質量や摩擦係数を設定
soccerBall.physicsImpostor = new BABYLON.PhysicsImpostor(
soccerBall,
BABYLON.PhysicsImpostor.NoImpostor,
{ mass: 2, friction: 0.7, restitution: 0.7 },
scene
);
soccerBall.position.y = radius;
};
ボタンの作成
ボタンがクリックされたらサッカーボールに力が与えらえるようにします。Pulse
関数でサッカーボールに加わる力の向き、大きさ、作用点を設定し、applyImpulse
関数で3Dモデルに力を与えます。作用点をサッカーボールの重心から少しずらしているので、横向きの回転がかかるようになります。ボタンをクリックしたらこの関数が実行されるように、button.onPointerClickObservable.add(Pulse);
とします。
const Pulse = function () {
const impulseDirection = new BABYLON.Vector3(0.5, 1, 1);
const impulseMagnitude = 15;
const contactLocalRefPoint = new BABYLON.Vector3(0.15, 0, 0);
soccerBall.physicsImpostor.applyImpulse(
impulseDirection.scale(impulseMagnitude),
soccerBall.getAbsolutePosition().add(contactLocalRefPoint)
);
};
button.onPointerClickObservable.add(Pulse);
advancedTexture.addControl(button);
まとめ
今回はBabylon.jsで物理エンジンを試してみました。パラメータをべた書きしてしまっているので、力の向きや大きさをGUIで設定できるようになったらPKのゲームとか作れそうですね。これからもBabylon.jsの記事を投稿していきたいと思います。