17
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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の記事を投稿していきたいと思います。

17
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?