読者です 読者をやめる 読者になる 読者になる

妹でもわかるUnrealEngine4

毎日更新? 妹に説明するために書いてるけど、たまにわかってない場合もあるUnrealEngine4を中心としたゲーム制作の話。略すとイモリアル

毎日更新? 妹に説明するために書いてるけど、たまにわかってない場合もあるUnrealEngine4を中心としたゲーム制作の話。略すとイモリアル

OpenAssetOrgのアセットで2Dゲームを作る⑬ 当たった弾を消す処理はどこに書いたらいいのか?

2Dゲーム UE4.14 Paper2D

「昨日は矢が当たったら敵が消えるだけで、まだ色々足りてないんだけど、まず問題なのが当たった矢が消えずに残ってしまうこと。ブロック崩しとかだったらそういうのもあるけど、今回は消したい」

妹「普通にヒットした時に消したらいいのでは?」

「でも壁に当たった時は消えて欲しくないんだよ。跳ね返って欲しい。だから敵に当たった時だけ消える。矢同士の接触はコリジョンの設定でしないようになってるから、今のところ当たるのは敵と壁の2種類」

(1)"矢"の方に、何かに当たったら自分を消す処理を入れる

f:id:una_unagi:20170109224113p:plain

「矢の方に入れるパターンの難しいのは、今回は自分が何と当たったかわかるまで消せないので、それを調べる処理が必要になること。今回の場合、当たった先のコンポーネント名を直接ブループリントに書いちゃってるから疎結合にならない。だいぶ密結合してる」

妹「矢に書いちゃ駄目なのか」

「これだと柔軟性ゼロだから、相手方のコンポーネントの種類が増えるたびに分岐が増えちゃう。もしやるとしたら、タグを使うとか、インターフェースを使うとか、なるべく直接クラス名を入れない方法が良い」

(2)"敵"の方に、当たってきた何かを消す処理を入れる

f:id:una_unagi:20170109225507p:plain
f:id:una_unagi:20170109225511p:plain

「逆に敵側の処理で消してしまう方法もある。昨日はDamageCauserに何も入れてなかったけど、そこに矢のアクターを入れるようにしておくと、ダメージイベントの中から当たってきた矢がどれかわかる。そいつをDestroyActorで始末する」

妹「じゃあ敵の方に書いとけばいいのか」

「今の仕様だとそうなる。でも弾の種類が増えたりすると対応しきれなくなる場合がある。貫通するレーザーとかだったら消しちゃ駄目なわけだから」

(3)"敵"にダメージをあたえた時に、"矢"にもダメージを与えて、"矢"のダメージ処理の中で消す

f:id:una_unagi:20170109230847p:plain
f:id:una_unagi:20170109230854p:plain

矢のHitイベント -> 敵のDamageイベント -> 矢のDamageイベント(ここで消す)

「こういう方法も考えられる。例えば消えない貫通レーザーを作った場合には、レーザー側でダメージを無視するだけでいい。そういうことを疎結合のまま達成出来る。難点は関連するイベントが多くなってめんどくさいこと」

妹「ダメージを受けた敵が矢にダメージを与える……うーん、だいぶややこしいことになってきた」

「インターフェースとか作るよりは楽かなとも思うんだけど。この方法だと、矢のOnActorHitとOnTakeAnyDamageと別のイベントだから、それぞれコンポーネントも別に出来るというのもある。これも場合によっては利点」

妹「結局どの方法がいいの?」

「当たった時の反応が1種類なら(1)、当たった時の反応が色々でも弾は1種類なら(2)、当たった時の反応も弾の種類も色々な時は(3)かインターフェース仕様かなあ。どれでも頑張れば書けるんだけど、自作クラスへの型キャストや、分岐処理が少なくなるといいかんじ」