アセットを読み解く:BallisticsFX ※訂正あり
タダより安いものはない!!!!
皆さん!毎月無料のUE4アセット、欠かさずにゲットしてますか!?僕のような貧乏人は毎月どころか毎日、いやなんなら毎時間、毎分、毎秒、別に更新されてるわけでもないのにチェックしておりますよ!
世間ではなんとかPayが何割還元とかで大騒ぎしておりますが、こちとら10割還元です!半額で2倍お得とか言ってる量販店も反省してください!2とか3とか本当にケチ臭くて嫌だ!こっちは無限倍お得!どころかゼロ除算で数学すら超越しているいるのですよ!
…え?UE4のアセットは自分にはレベルが高すぎて参考にならない?
…うん、実は俺もそうなの…
というわけで、レベルの高い(無料の!)アセットの中身をなんとか取っ掛かりを見つけて解析、学習しつつ、ついでにそれをブログに載せてアクセス稼いでやるぜゲヘゲヘ、ということをやっていきたいと思ってます。なんかレジ横の肉入れる用のビニール袋を大量に持っていく奴みたいだな、俺。
記念すべき最初のアセットはこちら…
BallisticsFX!
BallisticsFXはCubitStudiosというスタジオが開発したフォトリアル系のエフェクト集です。主に弾丸が様々なマテリアルに着弾した際のインタラクションが集まっています。
カバー範囲がかなり広く、砂や水、金属、草、マグマなどリアル系なら大半の素材は用意されています。この被弾サンプルのMaterialだけでも結構な価値がありますね。大きめの凝ったDemoMapが付属しているのでそこでドンパチやって遊んでいるだけでも楽しいです。
早速中身を見させてもらいましょう。
インタラクションの素材そのものはParticleやMaterialで実装されております。当たった時に吹き上がる土埃、マズルフラッシュなどはもちろんParticle、弾痕はNormalMapを含んだDecalの貼り付けで実装されているようです。
・インタラクション及び跳弾の実装
ここで注目したいのがBPです。インタラクションとは言いつつ被弾素材には一切ノードが実装されていません。じゃあどうやっているのかなと見てみると、実装はほとんど弾丸側で処理されています。
どうやら弾が物質に当たると
①ProjectileがImpactFXSpawnerというActorをSpawnしてそこにHitResultを送る
②ImpactFXSpawnerがHitResultからPhysicsMaterialを取得する
③PhysicsMaterialからSurfaceType(EPhysicalSurfaceというEnum型の変数)を参照する
④参照したSurfaceTypeからGetDataTableRawNameノードを用いて
FXMaterialDataTableというcsvファイルからデータを参照する
※訂正:これは間違いで実際に使用されていたノードはGetDataTableRowという名の別のノードでした。申し訳ありませんでした。
⑤FXMaterialDataTableにはProjectileが当たった時に発生させるべきParticleや貼り付けるべきDecalなどのデータが格納されているので、それに従って処理を行う
という処理を行っているようです。一応ProjectileがデータにないSurfaceTypeのPhysicsMaterialを持つ物質に当たったときのことも考えられており、GetDataTableRawNameの参照に失敗した場合にはDefault行のデータが参照され実行されるようになっています。
なるほど、こういう処理にすれば基本的にはPhysicsMaterial(にくっついているSurfaceType)にエフェクトが依存するので、素材側に余計な設定をせずに済むのですね。
ちょっと補足としてSurfaceTypeの型であるEPhysicalSurfaceですが、DefaultでPhysicsMaterialに付属している変数で、これの設定はProjectSetting>Physics>PhysicalSurfaceで行います。
一応62個まで設定できるようです。
ちなみにこのアセットでは一定確率で跳弾するRicochet(もしくはBouce)という機能がありますが、これも実装は似たような感じです。
こちらの場合はProjectileそのものがSurfaceTypeに従ってMaterialProjectileDataTableというcsvファイルを参照します。そこには素材による跳弾率や跳弾した際の速度変化率などが格納されており、これをもとに跳弾の計算をします。
・WorldSupport
このアセットでは支柱や扉などを撃って一定量ダメージが蓄積されると破壊されてバラバラになります。もちろんこれはDestructibleMeshComponentを用いて実装されているわけですが、最初なぜ一部だけが崩落したような状態になるのか良く分かりませんでした。自分が実験していた時はそういう破壊のされ方はしなかったからです。中身を見てみるとDestructibleMeshのパラメーターであるWorldSupportにチェックが入っているようです。
どうやら…
こういうことのようです。