物理マテリアルを使って足音を変化させる
ファミコンやスーパーファミコン時代はキャラクタの足音はあまり実装されていませんでしたが、最近の3Dゲームでは足音がないゲームを探すほうが難しいのではないでしょうか?
足音は発生させるキャラクタの種類によって音を変えたりすることがありますが(子供と大人、履いている靴によって足音は変わるので)、それ以上によくあるのは歩いている地面によって足音を変えることです。
草地とコンクリート、金属床では足音が違うのが当たり前で、全て同じだとやっぱり違和感が出てしまいます。
というわけで、今回はUE4の機能の1つである物理マテリアルを使って足音を変更する手段を記事にしました。
物理マテリアルは他にも、オブジェクトの物理挙動で反射の挙動なども変更できる機能です。
物理マテリアルを作成する前に、SurfaceTypeを設定する必要があります。
これはプロジェクトごとに設定できる機能ですので、メニューの [編集] → [プロジェクト設定] を開きます。
プロジェクト設定ウィンドウで [エンジン] → [Physics] を選択、[Physical Surface] の項目にいくつかのSurfaceTypeを設定しましょう。
この設定を行わないと物理マテリアルを作成してもSurfaceTypeを設定できません。
さて物理マテリアルを作成しましょう。
[新規追加] → [フィジックス] → [物理マテリアル] で今回のための物理マテリアルを2つ作成します。
作成した物理マテリアルはそれぞれ [PM_Grass] と [PM_Metal] という名前にしておきます。
とりあえず [PM_Grass] をダブルクリックして編集ウィンドウを表示しましょう。
パラメータの [Physical Properties] → [Surface Type] のドロップダウンリストから Grass を選択します。
[PM_Metal] も同様に Metal を選択しましょう。
物理的な挙動を変更したい場合は [Friction] などのパラメータもいじるとよいでしょう。
今回は足音の問題なのでそれらのパラメータは編集しません。
この物理マテリアルはどこに設定するのかというと、実はけっこう色んな所に設定項目があったりします。
わかりやすいところではコリジョン関係があります。
StaticMeshであればStaticMeshの編集ウィンドウ内に、SkeletalMeshであれば物理アセットの編集ウィンドウ内にあります。
LandscapeにはLayerInfoの設定として存在しますし、レベル内に配置されているアクターにコリジョンに対して上書き可能な項目として存在しています。
今回はマテリアルに設定する項目として利用してみます。
まずは適当に草っぽいマテリアル、金属っぽいマテリアルを作成し(スターターコンテンツを利用してもよい)、詳細パネルで物理マテリアルを設定しましょう。
草マテリアルも金属マテリアルも同様に設定します。
レベル上に適当な床となるメッシュを配置し、草マテリアルと金属マテリアルをそれぞれに適用させてみましょう。
ここまでで物理マテリアルの設定は完了です。
これからアニメーション通知を利用して足音を発生させる処理を書いていきましょう。
アニメーション通知は各アニメーションデータに設定可能なイベントです。
デフォルトではエフェクトの発生と音の発生が簡単に可能ですが、今回はそれらは使いません。
カスタムのイベントを作成し、アニメーションブループリントで処理します。
とりあえずWalkアニメーションとRunアニメーションに通知を追加してみます。
どちらでもいいのでアニメーションアセットをダブルクリックすると編集ウィンドウが立ち上がります。
立ち上がった当初はアニメーションがループしていると思いますので、停止しましょう。アニメーションしてると編集の邪魔です。
真ん中下段のウィンドウに [通知] と書かれたバーが存在します。通知はここに追加していきます。
まずは1フレームずつアニメーションを動かしてみて、足が地面に設置する瞬間のフレームを探し、そこまで移動します。
移動したら通知バーの対象フレームを右クリック、[新規通知] を選択します。
通知名を設定するウィンドウが開きますので、今回は [PlayFootsteps] と入力しましょう。
作成すると次からは [新規通知] を選択しなくても [PlayFootsteps] が選択できるのでWalk、Runともに2箇所(右足と左足の設置タイミング)に [PlayFootsteps] 通知を設定します。
この通知はアニメーションBPのイベントグラフでイベントとして作成することが出来ます。
[AnimNotify_PlayFootsteps] というイベントがあるはずなので、これを配置して処理を書いていきましょう。
実装はこんな感じです。
まず、アニメーションBPのオーナーとなっているPawnアクターを取得します。
このアクターから真下方向にラインでコリジョン判定を行います。
正しく処理をするのであれば右足のボーンからとかの方がいいんでしょうけど、今回はそこまでやっていません。
コリジョン判定で衝突なしとなる場合もありますが、普通に床を歩いたり走ったりしているはずなのでコリジョン判定は成功しているものと判断していこうの処理を行っています。
空中を歩く能力があるなどの場合は衝突したかどうかをReturnValueでチェックするようにしましょう。
戻り値の [Hit Result] 構造体には [Get Surface Type] という命令がありますので、この命令から最初に設定したSurfaceTypeを取得します。
衝突していない場合は [Default] が返ってきます。
SurfaceTypeから [選択する] のノードでサウンドアセットを選択します。
[選択する] ノードは作成段階では何を返す命令となるか決まっていません。
入力ピンに何かを接続するか、出力ピンを何かに接続するか、もしくは右クリックで型を指定するかで決定されます。
今回の場合に一番簡単なのは出力ピンを [Play Sound at Location] の [Sound] ピンに接続することでしょう。
右クリックで決定する場合はノードのどこかのピンを右クリックし、[ピンの種類を変更] を選択して [Sound Base] にしましょう。
ここまで出来たらアニメーションBPをコンパイルしてゲームを実行してみましょう。
草マテリアルと金属マテリアルで音が変化するはずです。
もしもデフォルトに設定した音がなるようでしたらライン判定で衝突していないということになっています。
[LineTraceByChannel] 命令の [Draw Debug Type] で衝突判定ラインをデバッグ表示して衝突しているかどうか確かめるのがよいでしょう。
今回は足音ですのでアニメーション通知を利用しましたが、攻撃処理などではほぼ間違いなく衝突判定を取りますので、その際に衝突した物理マテリアルのSurfaceTypeをチェックして音やエフェクトを変化させることも出来ますし、物理挙動も変化させることが出来ます。
ただし弱点として、いわゆるレイヤードマテリアルで各レイヤーごとに物理マテリアルを変化させることは出来ません。
苔むした岩の上を歩いた際に岩の部分と苔の部分で音を変えたい場合はマテリアルを変更する必要があります。
Landscapeの場合はレイヤーごとに物理マテリアルを設定できるので、どうしてもという場合はLandscapeを使いましょう。
また、Complex Collisionの場合に場所ごとに変更する方法がわかりません。
ドキュメントを調べてみたんですが、それっぽい情報が見つかりませんでした。
見つけ方が悪いのかもしれませんが、どこかにあるならどなたか教えて下さい。