54.イベントHitノードとは? 衝突時に処理を実行してみよう
衝突時に処理を実行する方法とは?
ではここまでアクタ同士の衝突について学んできました。ここからはコリジョン同士が衝突した際に何らかの処理を実行する方法について学んでいきます。
例えばゲームで一般的な「プレイヤーがコインを拾う」という処理や、「剣で攻撃した敵にダメージを与える」などはイベントHitノードなどを使用して実装していきます。
https://scrapbox.io/files/65c725191873f0002493c6cf.jpg
そして衝突判定を取るためのコリジョンのイベントノードは主に三種類あります↓
https://scrapbox.io/files/65c725391bdc2100272079a9.jpg
①他のアクタとの衝突時に処理を実行する「イベントHit」
②他のアクタと重なった瞬間に処理を実行する「イベント Actor Begin Overlap」
⓷他のアクタと重さりから抜けた瞬間に処理を実行する「イベント Actor End Overlap」
このように衝突時に行う処理や、重なった瞬間に処理を実行する処理などの衝突時のノード基礎について紹介していきます。このページではイベントHitノードについて解説していきます。
①衝突時に処理を実行してみよう(イベントHitノード)
下のGifのようにアクタが衝突した瞬間に処理(テキスト表示)させるという事をやっていきます。
https://scrapbox.io/files/65c72593ad629d002408e620.gif
今回もサードパーソンのテンプレートプロジェクトを使用していきます。
https://scrapbox.io/files/65c725abf551110025e7ebdb.jpg
キューブを設置します。
https://scrapbox.io/files/65c725c7b5c093002814903f.jpg
🐱今回もコリジョンプリセットを確認しつつ進めていきます。
このキューブのコリジョンプリセットを確認します。「Default」になっています。
https://scrapbox.io/files/65c732689c700d0025c153c1.jpg
🐱基本的にDefault = BlocakAllなので、他アクタと衝突するという認識でオッケーです!ではこのキューブとプレイヤーが衝突した時に処理を実行させていきます。
BP_ThirdPersonCharacterを開きます。
https://scrapbox.io/files/65c732974b7e6c002553a489.jpg
既存のノードありますが、これはそのままで良いです。
https://scrapbox.io/files/65c732affecfb20025246f11.jpg
空いてる場所にイベントHit(Event Hit)ノードを作成します。
https://scrapbox.io/files/65c732cfcfd70000265b34d5.gif
イベントHit(Event Hit)ノードとは?
イベントHitノードは、このノードを記載したアクタが他のアクタと衝突した時に実行されるノードです。なので先ほど配置したキューブとこのプレイヤーが衝突した時や、地面とプレイヤーが衝突した時など他のアクタと衝突するたびに実行されるノードとなります。
https://scrapbox.io/files/65c732fb948c120025c63542.jpg
衝突時に一番上の実行ピンから実行されて、下の出力ピンからは衝突した他アクタの情報だったり、衝突した場所などを出力します。
次にPrintStringで「他のアクタと衝突した!」と入力しておきます。
https://scrapbox.io/files/65c846be552ad70026772536.jpg
これでプレイしてみましょう。地面のアクタも含む他のアクタに衝突した際に「他のアクタと衝突した!」とテキスト表示されました。
https://scrapbox.io/files/65c72593ad629d002408e620.gif
Q&A なぜ最初の時点で地面と衝突しているはずなのにテキストは表示されない?
イベントHitノードは他のアクタと触れた瞬間に実行するので、ゲーム開始時の最初から触れている地面のアクタに対しては衝突処理は実行されません。あくまで衝突した瞬間のみに実行されます。
Q&A なぜ何度もテキスト表示される??
壁やキューブなどの他アクタに触れるとイベントHitノードが何度も実行されてテキスト表示される場合があります。
この現象を解説すると短い一瞬の間に、
①プレイヤーがキューブに向かって移動
②プレイヤーがキューブに接触してテキスト表示
③ぶつかった事で少し離れる
④プレイヤーがキューブに向かって移動
⑤プレイヤーがキューブに接触してテキスト表示
という事を繰り返しているためです。つまり"ガガガガガガ"と壁に擦りつけているためその分イベントHitが実行されてるといった感じになります。もちろんノードの組み方によって衝突時に一度だけ処理させる事もできます。
イベントHitノードについて
イベントHitノードについて少しまとめていきます。イベントHitノードは他アクタと衝突した時に実行されるノードです。
https://scrapbox.io/files/65c8486a84be9500257cf006.jpg
既に他のアクタに触れてる状態だとイベントHitは実行されないので注意です。
イベントHitノードが実行されない?三つの発動条件について
イベントHitノードは具体的には以下の三つの発動条件が満たされていないと実行されません。なぜかイベントHitノードが実行されない場合は以下を確認してみてください。
発動条件① : 衝突するアクタ同士は互いにコリジョンレスポンスをブロックに設定してある事
発動条件② : 衝突するアクタ同士は互いにコリジョンを有効にしてある事
発動条件③ : 物理シミュレーションをオンにする場合は「Simulation Genetates hit Envents」にチェックを入れる事
🐱発動条件の①と②は問題が起きても気づきやすいですが、③については事前に知っていないとわからないので物理シミュレーションを行い,かつイベントHitノードを使用する場合は「Simulation Genetates hit Envents」にチェックを入れると覚えておきましょう。
OnComponentHitノードとは?ついでに紹介していきます
ついでにイベントHitノードと非常によく似ているOnComponentHitノードについて解説していきます。OnComponentHitノードはコンポーネントと衝突した時に処理が実行されます。
まずは実際にOnComponentHitノードを使って処理を実装してみましょう。
コンテンツブラウザで右クリック > ブループリントクラス > Actorを作成します。名前をBP_Chairとします。
https://scrapbox.io/files/65c849f8cb46f30025941ab6.jpg
開いてStaticMeshコンポーネントを追加して、スターターコンテンツのアセット「SM_Chair」を選択します。
https://scrapbox.io/files/65c84a12549c5e0025d9f0fb.jpg
BoxCollisionコンポーネントを追加して、椅子を覆うぐらいに大きさを変更します。
https://scrapbox.io/files/65c84a3a2c9c6a0024940eb4.jpg
BoxCollisionコンポーネントを選択した状態でコリジョン > コリジョンプリセットをBlockAllにします。BlockAllにする事で他アクタと衝突するコリジョンになりました。
https://scrapbox.io/files/65c84a68c17f4f0027c907ef.jpg
BP_Chairのイベントグラフを開きます。
BoxCollsionコンポーネントを右クリック > イベントを追加 > OnCompoentHitを追加を選択します。
https://scrapbox.io/files/65c84a8ccd7c110024b2217b.gif
(Box)はコンポーネント名(BoxCollision)を表しています。
https://scrapbox.io/files/65c84bbb0db52f0024303244.jpg
OnCompoentHitノードとは?
コンポーネントが他のアクタと衝突した時に実行されるノードです。イベントHitノードと仕様が非常に似ていますが、イベントHitノードはアクタ全体(つまりアクタの全コンポーネント)の衝突を検知するノードで、OnCompoentHitノードは対象のコンポーネントのみの衝突を検知するノードになっています。
https://scrapbox.io/files/65c84b82e93a0c0023d3cb3c.jpg
PrintStringを繋げて「BoxCollisionコンポーネントと衝突した!」と入力しておきます。
https://scrapbox.io/files/65c84ba03d51b9002433d686.jpg
BP_Chairを配置します。
https://scrapbox.io/files/65c84c106ad0eb002477297e.jpg
プレイして衝突しにいきましょう。椅子のブループリントクラスに触れると「BoxCollisionコンポーネントと衝突した!」とテキスト表示されるようになりました。
https://scrapbox.io/files/65c84c32d38a7700261129a3.gif
このようにOnCompoentHitノードを使う事でコンポーネント毎に衝突時に処理を実行する事ができます。
イベントHitノードとOnComponentHitノードどっちを使えば良い?
では「イベントHitノード」と「OnComponentHitノード」はどちらを使用すれば良いのでしょうか?
答えとしてはどちらでも良いです。
イベントHitノードはアクタ全体の衝突時の処理で、OnComponentHitノードはコンポーネント毎に衝突時の処理を実行する事ができます。正直大して変わらないのでどちらでも良いのですが、迷ったらイベントHitノードをおすすめします。アクタ全体の衝突という事でわかりやすいかと思います。
🐱基本的にはイベントHitノードでアクタの衝突時の処理をとっていきましょう!
コンポーネント毎に衝突時の処理を分けたい場合にはOnComponentHitノードを使用しましょう。