tanaka's Programming Memo

プログラミングについてのメモ。

2D Game KitのVFXController

am1tanaka.hatenablog.com

上記でまとめたObject Poolingは弾などのゲームオブジェクト用のプールシステムでしたが、パーティクルもまたプールシステムを持たせるべきものです。VFXControllerがそれに該当します。公式ドキュメントを読みながらのメモです。目次は私の方で勝手に入れたものです。

目次

このコンポーネントは、VFXプレハブをプールから生成して、既定の時間が過ぎたらそれらを停止して、プールに戻すために使います。

f:id:am1tanaka:20180220161325p:plain

VFXとは

"ゲーム業界ではエフェクト制作のことをVFXとよぶ場合もある"(VFX | CG用語辞典 | CGWORLD Entry.jp )。

2D Game Kitでは、一定時間ゲームに効果を与えて、時間が過ぎたら効果が消えるパーティクルによる演出全般のことを指しているようです。

VFXControllerはゲームで利用するすべてのVFXをリストで持たせて管理するアセットです。このアセットはVFXインスタンスのプールを事前に作成しておくことで、それらが画面に出現するたびにInstantiateによる負荷が発生しないようにします。

VFXを出現させるには、PlayerControllerStateMachineBehaviour TriggerVFXなどのスクリプトから、VFXController.Instance.Trigger()メソッドにVFXのプレハブ名や座標などを指定して呼び出します。

着地した場所や、着弾した場所のマップのタイルの種類に応じて、VFXを差し替えることもできます。例えば、足元にあるタイルの種類に応じて着地した時の土煙のエフェクトを変えることができます。VFXControllerの利用例は2D Game Kitプロジェクトを参照してください。DustPuff VFXは、プレイヤーが石の上を歩く時の土煙を設定しています。

f:id:am1tanaka:20180220164048p:plain

差し替えるタイルは、VFXControllerTrigger()メソッドの引数で渡します。例えば、着地処理では足元のサーフェイスを渡し、弾がサーフェイスに当たった処理では当たった場所のタイルを渡します。

タイルマップのオブジェクトではないタイルを上書きするように設定することもできます。GameObjectがどのように上書き設定をするべきかはサウンドのドキュメントであるSounds.txtを参照してください(訳注:Sounds.txtがどこにあるかわかりません。)

補足:実例を見る

公式ドキュメントは以上で終わりです。具体的な使い方がわからないので補足しておきます。

2D Game KitのHierarchyを見ると、VFXControllerオブジェクトが確認できます。

f:id:am1tanaka:20180220165912p:plain

VFXControllerオブジェクトは、VFX Controllerスクリプトがアタッチされているだけのオブジェクトです。

f:id:am1tanaka:20180220170038p:plain

VFX Controllerコンポーネントに、ゲームで利用するVFXをすべて登録します。デフォルトでは10個のパーティクルが設定済みです。中を見ると、JumpPuffDustPuffといったパーティクル以外に、EllenDeathなどのアニメーションのオブジェクトも設定されています。

f:id:am1tanaka:20180220161325p:plain

パーティクルに限らず、一定時間が経過したら自動的に消えるようにしたいエフェクトはすべてここに登録すればよいでしょう。

VFX Controllerの設定方法

利用するVFXをすべてこのオブジェクトに登録します。

f:id:am1tanaka:20180220175109p:plain

最低限設定するのは、VFXPrefabと、発生させてから効果を消すまでの秒数Lifetimeです。

VFXオーバーライドの設定方法

関連するタイルマップに応じてVFXを差し替えたい場合は、Vfx Override属性を設定します。

f:id:am1tanaka:20180220173347p:plain

  • Tile: 差し替える対象のタイルのルール
  • Prefab: 差し替えたいVFXのプレハブ

上記の設定をしてTrigger()を呼び出す時にタイルの情報を渡すと、通常はDustPuffVFXが発生しますが、足元がTilesetRockRolesだった場合は、GrassPuffVFXを代わりに発生させることができます。

VFXの発生方法

VFXスクリプトで指定します。一例をPlayerCharacter.csから抜粋します。

        public void PlayFootstep()
        {
            footstepAudioPlayer.PlayRandomSound(m_CurrentSurface);
            var footstepPosition = transform.position;
            footstepPosition.z -= 1;
            VFXController.Instance.Trigger("DustPuff", footstepPosition, 0, false, null, m_CurrentSurface);
        }

VFXControllerクラスのstaticメンバーであるInstanceを参照して、TriggerメソッドでVFXを呼び出しています。

VFXController.Trigger

Triggerメソッドの引数は以下の通りです。

public void Trigger(string name, Vector3 position, float startDelay, bool flip, Transform parent, TileBase tileOverride = null)
  • string name(あるいは int hash)
    • 発生させたいVFXをPrefab名か、int型のHash値で指定
  • Vector3 position
    • 発生させる座標
  • float startDelay
    • VFXの開始を遅らせる秒数
  • bool flip
    • trueの時、左右反転
  • Transform parent
    • 親のゲームオブジェクトがあれば指定。なければnull
  • TileBase tileOverride
    • マップタイルによってVFXを変化させたい場合、取得したタイルのインスタンスを渡します。変化が不要な場合は省略します

第1引数を名前で指定した場合は、内部でint型のハッシュ値を求めて参照しています。パフォーマンスにこだわる場合は、VFXController.StringToHash("VFX名")で値を求めることができるので、事前にint値を求めておいて、それを第1引数に渡すこともできます。

VFXOverrideをタイルマップ以外にするには

VFXOverrideのデータは、VFXController.csに以下のように定義されています。

        [System.NonSerialized] public Dictionary<TileBase, VFXInstancePool> vfxOverrideDictionnary;

TileBaseの種類によって検索が行われるようになっています。上記TileBaseの部分を変更すれば、他の型に変更が可能そうです。試してはいませんが、3Dゲームに対応させることもできるでしょう。

まとめ

VFX Controllerプレハブを設置してVFXプレハブを設定したら、Triger()メソッドで発生させるだけです。タイルマップを使ったゲームであれば、簡単にVFXのプール機能を実装できます。Object Poolingと同様にウォームアップはしてくれないので、自前で処理を追加するとさらに使えるようになりそうです。

インスタンスの管理にはObjectPoolingの仕組みを使っていますので、併せて理解することで応用の幅が広がりそうです。

参考URL