CrossRoad

XRを中心とした技術ブログ。 Check also "English" category.

Babylon.js Editorを使って、キャラクタが魔法剣を振ったときの破壊エフェクトを作る方法

時間が経ってしまいましたが、前回からの続きです。魔法剣を振ったときに岩を破壊するエフェクトを作りました。

これまでの内容はこちらです。
www.crossroad-tech.com

www.crossroad-tech.com

www.crossroad-tech.com

www.crossroad-tech.com

www.crossroad-tech.com

www.crossroad-tech.com

www.crossroad-tech.com

使用した環境

Babylon.js Editor v4.3

1. エフェクトの作成方針

このようにしました。
・光の線が大きな岩に衝突
・爆発エフェクトを表示
・大きな岩をdispose
・立ち上る煙を表示

本来は小さな破片を飛ばすエフェクトも入れたかったのですが、Babylon.js Editorだからなのか、参考にする予定のサンプルコードが動きませんでした。

こんな感じになります。

flame sword effects on Babylon.js Editor

2. 個別の処理について

2.1 光の線と大きな岩に衝突するエフェクト

光の線はsphereを表示にしています。ここでは次の爆発エフェクト発動のトリガーにするため、sphereと岩meshの衝突判定を作りました。

衝突判定を実現する方法はいくつかありそうですが、今回はActionManagerを使っています。

doc.babylonjs.com

このドキュメントにあるように、メッシュの子メソッドとして使うことで、〜したら〜する、という処理を実現できます。ここでは"OnIntersectionEnterTrigger"を使うことで、衝突したら〜するという処理を実現しています。衝突対象はparameterに記載します。 ExecuteActionを使うことで、衝突したら、の後に任意の処理を実行できます。

まとめるとこのようになります。

gist.github.com

generateSmoke()、explode()、this.largeRock.dispose()は、実際の処理を関数にしたものです。generateSmoke()は爆発後に立ち上る煙ですが、発動に少しかかるので先に実行させています。
disposeはdelete objectという意味です。

2.2 爆発エフェクト

色々探していたところ、ParticleHelperのCreateDefaultで表現しているサンプルコードがあったので、これを使わせていただきました。

https://www.babylonjs-playground.com/#VS5XS7#0

このようなエフェクトです。
fire burst effect example on Babylon.js

ParticleHelperには、他にも煙、雨、炎などのエフェクトがあります。詳細はこちらをご覧ください。
doc.babylonjs.com

先ほどの_explode()関数の中でサンプルコードを使っています。爆発の規模を大きくするためにEmitPowerのminとmaxを2倍にしました。

    // Emission power
    fireBlast.minEmitPower = 60; //original は30
    fireBlast.maxEmitPower = 120; // original は60

2.3 大きな岩をdispose

これは、先ほどのExecuteActionの中で this._largeRock.dispose(); で宣言するだけです。

2.4 立ち上る煙を表示

このサンプルコードを使用しました。

https://www.babylonjs-playground.com/#2BEARJ#2

Smoke effect example on Babylon.js

3. Tips

今回、内容としてはそれほど多くないのですが、Babylon.js Editorが思ったように動かないことが多く、そちらの対応に時間がかかりました。参考のため、いくつか書いておきます。

3.1 別のスクリプトから関数を呼べなくなっていた

以前は、このようにクラス全体がexport defaultされていて、これを別のスクリプトからimportすれば、変数や関数を呼び出すことができました。
gist.github.com

少なくとも、Editorのv4.0.0のときは動いていました。

しかし、Editorのv4.2もv4.3も、この書き方をすると処理が呼ばれた瞬間に画面が固まってしまいます。

そこで、今回は呼ばれたい関数だけをclassの外に出してexportすることで対応しました。
gist.github.com

3.2 v4.2からv4.3で、decoratorのimport場所が変わった

decoratorとは、@fromScene (これを宣言して追加で1行書くと、GUIのViewにあるmeshをスクリプトで取得できる) など、TypeScript記述をちょっと便利にする機能です。v4.2まではスクリプトの冒頭でこのように宣言していました。

import { visibleInInspector, onKeyboardEvent, fromScene, fromChildren } from "../tools";

v4.3からはこのように変わりました。

import { visibleInInspector, onKeyboardEvent, fromScene, fromChildren } from "../decorators";

tools.tsに処理の実態があったのですが、decorators.tsに移動したようです。
そのため、これらのdecoratorを読んでいる箇所は全て修正しないとビルドが通らなくなります。

3.3 v4.2からv4.3で、scene内のindex.tsが不要になった

今までは個別のsceneの中にもindex.tsがあったのですが、v4.3からは不要になりました。scene/index.tsが残っていると、以下の部分でエラーが出ます。エラーが出ても実行はできますが、Build failedと表示されます。

export function attachScriptToObjectImmediately(scriptPath: string, object: Node | Scene): void {
    attachScriptToNodeAtRuntime(scriptPath, object);
}

3.4 index.tsの中にあるrunSceneのimport指定が変わった

このように変わりました。これも直接変更しないとBuildエラーになります。

//v4.2の場合
import { runScene } from "./scenes/scene";
//v4.3の場合
import { runScene } from "./scenes/tools";

3.5 スクリプトの中からテクスチャを参照する方法が不明

Babylon.js Editorでは、Asset Browserという中でテクスチャを管理できます。ここで管理しているテクスチャをスクリプトから呼びたかったのですが、呼び出すパスがわかりませんでした。

たとえば、このようなフォルダ階層になっていて、explosion.tsの中でsmokeParticleTexture.pngを呼ぶ場合、 ../../assets/texture/smokeParticleTexture.pngでいけるかと思ったのですが失敗しました。

An example of folder configuration

ログを見ると、Babylon.js Editor.app (Windowsの場合はexe) の中にあるResourcesからパスを計算しており、今のところパス指定方法が不明です。

今回は、githubに公開されているテクスチャを直接httpsで指定して使いました。

4. おわりに

今回、火炎大地斬を再現してみたいという動機から、AnimationGroupによるキャラクターモーション割り当て、particle systemをつかった炎の魔法剣、trail meshとglow layerによる魔法剣を振ったときの衝撃波、ParticleHelperによる爆発エフェクトなどを学ぶことができました。

個別の処理が参考になるかもしれないので、整形したらGitHubに公開予定です。