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

妹でもわかるUnrealEngine4

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

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

同じHitイベントが1フレームに2回発生する原因と対処法

「実は昨日の実験の最中に、ティックの発生タイミングとは別の問題に気付いてしまった。記事にしたかどうかは忘れたんだけど、妹が作ってたアクションゲームの試作で、1フレーム2回Hitイベントが起きるっていうバグがあったよね?」

妹「あったよ。パンチした時に、手のコリジョンから2回Hitが出てくるの。たまに1個の時もあって、敵との位置関係で違うみたいだったけど」

「その原因が少しわかってきたんだよ」

f:id:una_unagi:20161108210857p:plain

「昨日取ってたログの一部なんだけど、地面にあたった時、2回Hitが発生してるんだよ。"フィジックス中"の前と後で」

妹「地面に当たったら……その後は跳ね返って上に行くんだから、2回も地面に当たる必要ないよね」

「そう、1回でいい」

f:id:una_unagi:20161108211151p:plain

「この"SimulationGeneratesHitEvents"を、最初は地面とボールと両方に設定してたんだよ。Hitイベントが起きないと困るなと思って。でもこれを両方ともチェック外すと、"フィジックス中"の手前の分だけ残った」

妹「あれ要らなかったの!?」

「でもその状態だと、勢いがなくなって地面に落ちて止まった後は、Hitが発生しなくなる。厳密に言えば毎フレーム重力で下に落ちようとして、地面にあたって押し戻されてるはずだから、Hitしてるとも言えるんだけど、それは"SimulationGeneratesHitEvents"がないとノーカウントになるみたい」

妹「見た目から言えば動いてないし、もう止まってるから、Hitもしてないってことかなあ……」

  • "SimulationGeneratesHitEvents"のチェックを外す(両方、もしくは片方、都合のいい方法で)
  • HitイベントではHitしたアクターの記録だけして、実際の処理はその後のTickイベントでやる(ティックグループは"フィジックス後"にする)

「こういう対策をすれば2回Hit問題には対処できそう」

妹「Hitしたアクターの記録というのは?」

「HitしたタイミングでActor型の配列に追加して、もう配列に同じアクターがある場合は無視する。で、後のTickでForeachとか使って処理して、終わったら配列をClearする。これで毎フレーム1回分の処理が出来る。TSET型が実装されたら、配列じゃなくてそっち使ってもいいかも」

妹「全部にそういうの仕込むの大変そう」

「そのへんはComponent化するとかでなんとか」