2015年04月05日

FPS作成--(10)爆発処理




ゲーム「FPS(ファーストパーソン・シューティング)」をUnityで作成致します。
今回は手榴弾の爆発処理を行います。


手榴弾の爆発エフェクト


前回に引き続き、まずは手榴弾の爆発エフェクトを追加します。

手榴弾の爆発エフェクトには、アセットストアからダウンロードした
『KY_magicEffectsFree』の「White Bomb」を使用したいと思います。
※他のエフェクトを使用しても別に構いません。

@では、まず、《Assets》フォルダの《KY_magicEffectsFree》-《prefab》フォルダ内にある、「White Bomb」を、「 Ctrl + D 」でコピーします。

Aコピーしたファイルを、《F03-prefab》に移動します。

B名前を「PE_HitEffect2」に変更します。

C各種設定を変更変更/確認のため、「PE_HitEffect2」を《Hierarchy》に追加します。






では、「PE_HitEffect2」を少し弄っていきましょう。

中身を確認したところ、何やら時間差で爆発エフェクトが発生しています。
今回欲しいエフェクトは、そんな時間差エフェクトはいりません。
なので、遅延時間を取っ払ってしまいたいのですが……

遅延している「KYsphere」「KYcircle」「KYdustB」の3つのエフェクトの設定を見たところ、
遅延を意味する『Start Delay』の数値が「KYcircle」は2になっているのに、
何故か「KYsphere」「KYdustB」は0になっています。



その他の設定を確認しても、それらしい設定は見当たりません。



とりあえず、まずは試しに「KYcircle」の『Start Delay』を 2 → 0 にしてみます。
すると、エフェクト状態を確認してみると、きちんろサークルの広がりが0秒から始まってくれました。



さて、原因不明の「KYsphere」「KYdustB」の2つですが、
「PE_HitEffect2」の親子関係から切り離し、単体にしてみたところ、
遅延なく普通に動きました。

再び戻してみたところ、やはり動作が遅延しています。
やはり何かしら、遅延処理の設定がされているようです。



そこでもう少し設定を詳しく確認していったところ、
「PE_HitEffect2」の『Sub Emitters』-『Death』項目に、何やら怪しい設定が。



どうやら、この項目は、
自分の処理が完全に終わってから、設定したパーティクルの処理を開始させる
みたいな設定の模様です。



というわけで、早速『Sub Emitters』のチェックを外して動作確認してみました。



遅延もなくなり、うまく動作するようになりました。
「KYcircle」だけ『Start Delay』が2になっていたのは、『Sub Emitters』の設定項目数に上限があったからみたいですね。





遅延も無くなったので、後はサクサクっと設定を変えていきます。

まず、ライトはいらないので、「Point light」の2つはチェックを外します。




次に、メラメラ燃えてくれる「PE_HitEffect2」のサイズを変更します。
現在の設定だと
  ・『Duration』(継続時間)が2秒で
  ・『Start Lifetime』(パーティクル単体の生存時間)が2秒で
  ・『Start Size』(初期の大きさ)が2で
  ・『Size over Lifetime』(生存時間中のサイズ変化)で、時間経過でサイズ変更
となっています。



『Size over Lifetime』のグラフは、
  ・横軸が経過時間
  ・縦軸がサイズ
を意味しており、それぞれ最大値を1としてグラフが作られています。


『Duration』で、2秒間ずっとパーティクルを発生させ続けます。
各パーティクルは、『Start Lifetime』の2秒間だけ生存します。
パーティクルの初期サイズは2、『Size over Lifetime』のグラフの様にサイズ変更します。

以上から、メラメラ燃えてくれる「PE_HitEffect2」は単一のパーティクルではなく、
次々と発生するパーティクルが重なって、そう見えるようになっている模様です。




というわけで、これらの設定を以下の様に変えてみました。
  ・『Duration』(継続時間)を、0.2秒に
  ・『Start Lifetime』(パーティクル単体の生存時間)を、0.8秒に
  ・『Start Size』(初期の大きさ)を、3に
  ・『Size over Lifetime』(生存時間中のサイズ変化)を、最初に少し小さく



動作を確認してみたところ、なんかいい感じです。
少々、爆発サークルが大きい気がしますが、これでいく事にします。


では、忘れずにプレハブ本体に反映(Apply)させておきましょう。



および、《 Hierarchy 》内の「PE_HitEffect2」を削除しておきます。



手榴弾を爆発させる


では、実際に爆発するように致しましょう。

C#ファイル『C12_Bom』のプログラムを書き換えます。

using UnityEngine;
using System.Collections;

public class C12_Bom : MonoBehaviour {
public GameObject prefab_HitEffect2;

void Start () {
StartCoroutine("bom"); // コルーチン開始
}

IEnumerator bom(){
yield return new WaitForSeconds(2.5f); // 2.5秒、処理を待機.

GameObject effect = Instantiate(prefab_HitEffect2 , transform.position , Quaternion.identity) as GameObject; // ボムエフェクト発生
Destroy(effect , 1.0f); // ボムエフェクトを、1秒後に消滅させる

Destroy(gameObject); // 自分自身を消滅させる。
}
}

爆発エフェクトを格納する変数「prefab_HitEffect2」を作成し、
ボム自身が消滅する直前に、ボムのいる位置に、プレハブを発生させます。

ボムエフェクトは1秒後に消滅



あと、忘れずにUnity上でボム自身にプレハブを設定致しましょう。

ドラッグ&ドロップか、
項目の右の◎をクリックし、一覧ウィンドウから選択して設定します。




では、ゲームを実行してみましょう。
ボムを投げると、消滅する時に爆発してくれるようになります。





手榴弾のダメージ処理


では最後に、ボムで敵を消滅させましょう。

範囲内の敵情報を取得するには、
「Sphere Collider」「Rididbory」を追加して、
プログラム内で OnCollisionEnterでヒット判定して......

……といきたいところですが、残念ながらこの方法ではうまくいきません。


その理由は、今回判定するオブジェクト同士が、動かないからです。
「Collider」による判定は、各フレーム間で変化があった場合に処理されます。

つまり、今回の様に「敵が動かない」「ボムが爆発する時、ボムは動かない」という状況では、
「Collider」は何も検出する事が無く、思っていたような動作をしてくれません。

前回作ったピンポールのように、常に片方が動いている状況がないといけないのです。



なので、今回は別の手法を使います。

簡単に言えば、指定座標における範囲内のコリダーを探し出す方法です。
むしろ頭で考えるならば、こちらの方がしっくりくると思います。

という訳で、C#ファイル『C12_Bom』のプログラムを追加します。

using UnityEngine;
using System.Collections;

public class C12_Bom : MonoBehaviour {
public GameObject prefab_HitEffect2;

void Start () {
StartCoroutine("bom"); // コルーチン開始
}

IEnumerator bom(){
yield return new WaitForSeconds(2.5f); // 2.5秒、処理を待機.

GameObject effect = Instantiate(prefab_HitEffect2 , transform.position , Quaternion.identity) as GameObject; // ボムエフェクト発生
Destroy(effect , 1.0f); // ボムエフェクトを、1秒後に消滅させる

bomAttack(); // ボムによる攻撃処理

Destroy(gameObject); // 自分自身を消滅させる。
}

// ■■■ボムによる攻撃処理■■■
private void bomAttack(){
Collider[] targets = Physics.OverlapSphere(transform.position , 0.7f); // 自分自身を中心に、半径0.7以内にいるColliderを探し、配列に格納.
foreach(Collider obj in targets){ // targets配列を順番に処理 (その時に仮名をobjとする)
if(obj.tag == "Enemy"){ // タグ名がEnemyなら
Destroy(obj.gameObject); // そのゲームオブジェクトを消滅させる。
}
}
}
}

追加したのは、bomAttack()関数です。


bomAttack()関数では、まず
  Collider[] targets = Physics.OverlapSphere(transform.position , 0.7f);
で、指定範囲内にあるコリダーを全て取得しています。

Physics.OverlapSphere(中心座標 , 半径)で調べ、それを配列としてtargetsに格納しています。
※コリダー全てを取得 = 子オブジェクトが持っているコリダーも全て取得です。ご注意ください。


そして、foreach()文で配列の中身を順に調べていき、
Enemyというタグが見つかったら、そのゲームオブジェクトを消滅させています。


では、ゲームを実行してみましょう。
ボムが爆発すると、範囲内にいたEnemyが消滅していきます。









今回の説明に関しては以上です。




前回 : FPS作成--(9)手榴弾を投げる
次回 : FPS作成--(11)攻撃制限と攻撃音追加

Unity初心者の為の記事一覧へ
Unityで製作したゲーム一覧へ
ブログTOPへ










posted by 漆之黒褐 at 11:43| Comment(1) | TrackBack(0) | Unity | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
参考になります
Posted by at 2016年01月06日 12:05
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

この記事へのトラックバックURL
http://blog.seesaa.jp/tb/416806931

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。