i-school - 3Dダイビングゲーム 手順8
 以下の内容で順番に実装を進めていきます。

 この手順では、キャラが湖の水面に着水した際の判定を利用して、水しぶきのエフェクトの生成処理とSEの再生処理を順番に実装していきます。

手順8 −着水時のエフェクト処理の実装−
11.スクリプトを使って、着水状態になったら水しぶきのエフェクトを生成するようにする
12.水しぶきのエフェクトと同時にSEを鳴らすようにする



新しく学習する内容


 ・Instantiateメソッド
 ・パーティクルのエフェクトが正常に再生されない場合の対処法
 ・AudioSource.PlayClipAtPointメソッド



11.スクリプトを使って、着水状態になったら水しぶきのエフェクトを生成するようにする(SEも鳴らす)

1.設計


 キャラが着水した際に、水しぶきのエフェクトを生成するための処理を考えます。

 先ほどの手順においてキャラの着水判定の処理を OnTriggerEnter メソッドを活用することによって実装しました。
こちらのメソッド内にさらに処理を追加して、着水の判定に合わせて、水しぶきのエフェクトを生成するように制御をします。

 水しぶきのエフェクトについては、生成された位置を少しだけ調整したいので、生成と同時に、変数を用意しておいて操作できる状態にしておきます
このようにすれば、生成されたエフェクトを探して変数に入れる、という手間がなくなります

 ゲームオブジェクトは生成したタイミングが一番操作しやすい状態ですので、生成に合わせて何か操作を行いたい場合には
このように変数を用意しておいて、その変数を利用して操作を行うように設計をしましょう


2.PlayerController スクリプトを修正する


 水しぶきのエフェクト用に、GameObject 型の splashEffectPrefab 変数を用意します。
SerializeField属性を付与することで、インスペクターからアサインして値を代入出来るようにしておきます。

 OnTriggerEnter メソッド内に処理を追加して、着水の判定が行われたら、このプレファブのゲームオブジェクトを生成するようにします。
またエフェクトの位置を調整したいため、生成後にエフェクトのゲームオブジェクトを操作できるよう、
生成に合わせて effect 変数に水しぶきのエフェクトのゲームオブジェクトを代入しておきます。


PlayerController.cs

 <= クリックすると開きます




 スクリプトの修正が終了したら、Penguin ゲームオブジェクトのインスペクターから PlayerController スクリプトを確認します。
新しく宣言した splashEffectPrefab 変数の表示が追加されていれば問題ありません。次の手順で水しぶきのエフェクトを選定してから、こちらにアサインを行います。


Penguin ゲームオブジェクト インスペクター画像



3.<Instantiateメソッド>


 Instantiate(インスタンシエイト)メソッドは、オブジェクトを元にクローンのゲームオブジェクトを生成する命令です。
この命令を実行することによって、プレファブのクローンをゲームオブジェクトとして生成しています。

Unity公式スクリプトリファレンス
Object.Instantiate
https://docs.unity3d.com/ja/2018.4/ScriptReference...


 // 水しぶきのエフェクトを生成して、生成された水しぶきのエフェクトを effect 変数に代入
 GameObject effect = Instantiate(splashEffectPrefab, transform.position, Quaternion.identity);

 Instantiateメソッドを実行すると、このメソッドには戻り値があるため、生成したゲームオブジェクトの情報を左辺へ用意してある変数へ戻し、代入処理を行うことが出来ます
代入処理は、左辺 = 右辺 という条件でなければ成立しませんので、両辺が同じ型である必要があります

 左辺で用意している変数は GameObject型であり、Instantiateメソッドの戻り値の型も GameObject型 です。このためこの処理が成立しています。


参考サイト
@Tecah様
オブジェクト生成の仕方 Instantiate
https://qiita.com/Teach/items/c28b4fe5ca8dc4c83e26
Samurai Blog様
【Unity入門】Instantiateを使いこなそう!使い方・使用例まとめ!
https://www.sejuku.net/blog/48180


4.水しぶきのエフェクトを選択して設定する


 インポートしているアセットの中から、水しぶきのエフェクトを選択して、そちらの設定を行います。

 アセットの場所は次の場所になります。
Assets/EffectExamples/Water Effects/Prefabs/BigSplash.prefab


フォルダ画像




 もしもフォルダが見つからない場合には、アセットストアで Unity Particle Pack を探していただいて、そちらのインポートをお願いします。

https://assetstore.unity.com/packages/essentials/t...


Untiy Particle Pack



インポートするファイルに BigSplash.prefab が含まれていることを確認する




 BigSplash ゲームオブジェクトを選択して、インスペクターの一番上にある Open Prefab をクリックしてください。プレファブの編集モードになります。 


<手順動画 プレファブの編集モードを開く>
https://gyazo.com/ac6956e1d6e0831466a671600accb625


BigSplash ゲームオブジェクト インスペクター画像


 
 ParticleSystem コンポーネントの中にある、Looping のチェックを外しておきます。このチェックを外しておくと1回だけエフェクトが再生されます。


 プレファブの編集モードでは、Scene ビューにおいて、そのプレファブをフォーカスして確認することが出来ます。
またParticleSystemコンポーネントがアタッチされている場合には、Play ボタンを押すことで、どのようなエフェクトなのかを再生して確認することが出来ます。
操作を覚えるとともに、水しぶきのエフェクトの確認をしておいてください。


<手順動画 パーティクルを再生して、どんなエフェクトか確認する>
https://gyazo.com/8ff15558e4b9afbd405f1f2e7f043180


5.<パーティクルのエフェクトが正常に再生されない場合の対処法>


 Unityのバージョンによっては、パーティクルのマテリアルの設定が外れていて、ピンクのゲームオブジェクトが表示される場合があります。


<検証動画 マテリアルの設定が None になっている場合>
https://gyazo.com/aa4d2c148f4935c0a4a34ad31b59a452


 こういった場合には、どのゲームオブジェクトのマテリアルが外れているのかを順番に1つずつ確認していきましょう。
ParticleSystem コンポーネントの一番下の設定項目である Renderer をクリックすると、マテリアルの設定場所があります。


<手順動画 問題のあるゲームオブジェクトを探す>
https://gyazo.com/c6a572db7b5a4a6e1c16b2942848b495


 今回は Ripple ゲームオブジェクトのマテリアルが外れていましたので、対象となる WaterRipple マテリアルのアサインを行います。
Renderer 内の Material の右横にあるボタンをクリックしてマテリアルの一覧ウインドウを開きます。対象のマテリアルを探して設定します。


<手順動画 マテリアルの再設定>
https://gyazo.com/a5b06f465f4075ab4b2b1f65f4c4b41d


Ripple ゲームオブジェクト インスペクター画像



 これで正常に再生されるようになりました。


<検証動画 問題解消後のエフェクト>
https://gyazo.com/e78812e75a4b895a700fed9b98dedd22


6.Penguin ゲームオブジェクトの PlayerController スクリプトのアサイン情報に水しぶきのエフェクトをアサインする


 先ほど Penguin ゲームオブジェクトのインスペクターで確認した、PlayerController スクリプトの splashEffectPrefab 変数に
水しぶきのエフェクトのプレファブ・ゲームオブジェクトをドラッグアンドドロップしてアサインします。


<手順動画 プレファブをアサインする>
https://gyazo.com/9bb41e7c774d8a5657d7fea157dca5cf


Penguin ゲームオブジェクト インスペクター画像



6.ゲームを実行して動作を確認する


 ゲームを実行してキャラを水面に着水させてみましょう。大きな水しぶきのエフェクトが生成されれば、制御成功です。
着水の判定によって、if 文の処理内には1回しか処理が動かないように制御されていますので、水しぶきのエフェクトも1回だけ生成されています


<実行動画>
https://gyazo.com/b6de6a39b30d6a22f49aa4eeeb9283f3


12.水しぶきのエフェクトと同時にSEを鳴らすようにする

1.設計


 こちらの処理も、水しぶきのエフェクトと同じように、PlayerController スクリプトの、OnTriggerEnter メソッドの中に追記を行います。

 事前の準備としまして、SE用のオーディオファイルを用意して、それをUnityへインポートを行います。
そちらを、Unityが用意しているメソッドの1つである、PlayClipAtPoint メソッドを利用して再生を行います。


2.オーディオファイルをUnityへインポートする


 Googleの検索で「SE ゲーム 無料」と検索すると、色々な無料サイトからダウンロードが可能です。
「水しぶき 効果音」などで検索すると見つけやすいかもしれません。音源ファイルはmp3かwaveにて保存してください。
ファイルの名前を splash など、わかりやすいものに変更しておきましょう。

 インポートするオーディオファイルを1つのフォルダにまとめておくために、Unityにオーディオファイル用のフォルダを作成します。

 Project 内でマウスの右クリックをしてメニューを表示し、Create => Folder を選択します。
新しくフォルダが作成されますので、名前を Audio に変更します。

 Audio フォルダ内でマウスの右クリックをして Create -> Forderを選択します。
新しくフォルダが作成されますので、名前を SE にしてください。

 ダウンロードしたオーディオファイルを SE フォルダにラッグアンドドロップします。
これでオーディオファイルがインポートされます。

 ドラッグアンドドロップしてもインポートされない場合には、オーディオファイルが圧縮されたままになっている可能性があります。
解答してから、再度ドラッグアンドドロップしてください。


フォルダ



3.PlayerController スクリプトを修正する


 宣言フィールドに、オーディオファイルを設定するための AudioClip 型の splashSE 変数を追加します。
SerializeField属性を付与することで、インスペクターからアサインして値を代入出来るようにしておきます。

 OnTriggerEnter メソッド内に処理を追加して、着水の判定が行われたら、このSE用のオーディオファイルを再生するようにします。
再生処理には、Unityの扱う AudioSource クラスの持つ、PlayClipAtPoint メソッドを利用します。


PlayerController.cs

 <= クリックすると開きます




 スクリプトの修正が終了したら、Penguin ゲームオブジェクトのインスペクターから PlayerController スクリプトを確認します。
新しく宣言した splashSE 変数の表示が追加されていれば問題ありません。次の手順で先ほど追加したオーディオファイルをこちらにアサインします。


Penguin ゲームオブジェクト インスペクター画像



4.<AudioSource.PlayClipAtPointメソッド>


 このメソッドは変数を介さなくても実行できる、AudioSource クラスの持つ static メソッドの1つです。

 第1引数で指定した AudioClip を再生します。
その際、ヒエラルキーに AudioSource コンポーネントを持つゲームオブジェクトを作成し、再生が終了すると同時に自動で破棄します。
そのため、第2引数にはゲームオブジェクトを作成する位置を指定します。
指定された位置で AudioSource コンポーネントを持つゲームオブジェクトが生成されて AudioClip が再生されます。

 // 水しぶきのSEを再生
 AudioSource.PlayClipAtPoint(splashSE, transform.position);

 このメソッドの便利な点は、もう1つあり、破壊されたゲームオブジェクトがこの命令を実行している場合にも
しっかりとオーディオファイルを再生してくれるという点です。

 例えば、ゲームオブジェクト自体に AudioSource コンポーネントを持たせてオーディオファイルを再生する場合、
当然ながら、そのゲームオブジェクトが破壊された場合にはオーディオファイルも再生されません。

 このメソッドはAudioClip再生用の新しいゲームオブジェクトを作成してオーディオファイルを再生してくれるので、
生成元であるゲームオブジェクトが破壊されていても、別のゲームオブジェクトがオーディオファイルを再生しているため、ちゃんとオーディオファイルが再生されます。


参考サイト
Unity公式スクリプトリファレンス
AudioSource.PlayClipAtPoint
https://docs.unity3d.com/ja/current/ScriptReferenc...
Unishar -ユニシャー様
破壊されたオブジェクトから・指定した場所から音再生!PlayClipAtPointの説明と使い方
https://miyagame.net/playclipatpoint/


5.Penguin ゲームオブジェクトの PlayerController スクリプトのアサイン情報にオーディオファイルをアサインする


 先ほど Penguin ゲームオブジェクトのインスペクターで確認した、PlayerController スクリプトの splashSE 変数に
水しぶき用の効果音のオーディオファイルをドラッグアンドドロップしてアサインします。


<手順動画 オーディオファイルをアサイン>
https://gyazo.com/ace90118d8984b5cd103bf7128abf0c2


Penguin ゲームオブジェクト インスペクター画像



5.ゲームを実行して動作を確認する


 ゲームを実行してキャラを着水させてください。水しぶきのSEが1回だけ再生されれば制御成功です。


 以上でこの手順は終了です。

 => 次は 手順9 −DOTweenによる補間処理の実装− です。