第十六話 複数のコライダを持つ対象に対する範囲攻撃の実装 with Contains
ハウディーーーーーーーーーーー!!!!!!!!!!!!!
たぶんもうみんな知ってると思うんですけど、ぼくは今更Containsとかいうウルトラスーパー便利機能に感動したので書きます。
過去に作ったRTSに出てくる砲兵の範囲攻撃を実装する際にwhile文か何かをミスってEditorをフリーズさせたりさせなかったりした経験があるので個人的に爆発攻撃の実装はいやだな~って感じなんですけど、ゲームには必須ですよね。どうでもいいですね。
榴弾を作るぞ!
これを作りました。
爆発範囲内に被弾対象のコライダが1つでもあれば1回ダメージが入ります。また、爆発範囲内に被弾対象のコライダが2つ以上あってもダメージは1回しか入りません。
どうしよう
ロボットは複数のコライダを持つ複数の部品で構成されています。Physics.OverlapSphere等を使って爆発範囲内のコライダを取得すると思うんですけど、じゃあ取得した後にどうしよう。
今回はコライダのrootオブジェクトを取得して犠牲者リストにぶち込み、すべてのコライダの処理後に犠牲者リスト内のオブジェクトにダメージを与えるという処理をすることにしました。
コライダの処理
犠牲者リスト.Countが0以下のとき、1つめのコライダのroot.transform.gameObjectが犠牲者リストにAddされます。
2個め以降の処理はどうしよう…for文とかを使ってコライダのrootオブジェクトと犠牲者リスト内のオブジェクトで一致している物があるか調べるのかな?いやだな~と思っていたのですがContainsとかいう便利機能を発見!
ヤバい!お手軽!
Cointainsを使うとリスト内にお望みのブツが含まれているかどうかがすぐに判定できる…何も考えなくて良いんだ…。
詳しくはiPentec様の記事を見てくれ!!!!
List<T>の中に一致する要素があるか判定する (C#プログラミング)
これで簡単にリストの中にコライダのrootオブジェクトが含まれているかがわかります。含まれていなければこのrootオブジェクトをリストに新たに追加します。爆発範囲内に複数の機体が存在している際の処理が簡単に出来るね!
具体的に
Collider[] Colliders = Physics.OverlapSphere(transform.position, Size);
foreach(Collider coll in Colliders) {
if(coll.gameObject.tag == "Player" || coll.gameObject.tag == "Enemy"){
if(HitObjects.Count == 0) {
HitObjects.Add(coll.gameObject.transform.root.transform.gameObject);
} else {
if(HitObjects.Contains(coll.gameObject.transform.root.transform.gameObject)) {
Debug.Log("コライダのルートオブジェクトは既にこの爆風に被弾しています。");
} else {
HitObjects.Add(coll.gameObject.transform.root.transform.gameObject);
}
}
}
}
foreach(GameObject obj in HitObjects) {
AddDamage(obj);
}
的な事を書けばよろしいかとおもいます。
つまり
爆発物を作る際に「リストの中に同じものが入っているかどうか」を調べるハメになった場合、Containsを使うと何も考えずに済むよという話です。おわり。