【GDevelop 基礎 10】ずっと水平に移動して衝突したら反転する (衝突検知時の処理)

今回作成するもの

【GDevelop 基礎 07】Physics Engine で衝突する - Make Everything Games で一度衝突した場合の処理について触れました。

前回は、「衝突すると止まる(進めない)」ことの確認程度でしたが、今回は簡単に「衝突を検知し、何かする」の例としてここまでやってきた「反転する」をしてみます。

Handling collisions in your game

Handling collisions in your game - GDevelop documentation

上記の公式チュートリアルでは以下の3つが紹介されています。

  • Separate objects を使うパターン
  • Platformer games を使うパターン
  • Physics を使うパターン

ここでは、Separate objectsPhysics を使うパターンをやってみます。

冒頭の Gif 画像は上が Separate objects を使ったパターン、下が Physics を使ったパターンになっています。

Separate objects を使うパターン

Forever_MoveH_OnCollision_Flip の作成

どの Extensions に保存しても問題ありません。ToggleFlipAction で作成しています。

プロパティの追加

移動速度の Speed と現在の反転状態を持つ IsFlipped を作成します。Flippable behavior に Horizontally flipped の条件式があるので、そのまま使えそうなのですが、If-else の構文の使い方が私がまだ分かっておらず、仕方なくフラグを経由しています。

以下のようにしたいのですが、以下の場合は1つ目を通過すると2つ目も必ず通過してしまうので、反転状態を切り替えられないのです。

ToggleFlip の実装

この Function は衝突検知時に呼び出されることを想定しています。衝突県知事に反転状態を切り替えます。

Parameters

今回は追加はありません。

Configuration

Sentence in Events Sheet を記載しています。 (_PARAM0_ は Behavior を付けた Object です)

Events

IsFlipped プロパティを反転させ、その値に応じて Flip horizontally を切り替えています。

doStepPreEvents の実装

Events

今回は水平方向のみの移動なので、Add a force で X 軸方向のみに Speed プロパティを設定しています。

ToggleFlip Function で反転は行われているので、その状態に応じて Speed の方向を切り替えているだけです。

【GDevelop 基礎 04】 一定間隔で反転する - Make Everything Games ここの実装ともまた少し異なっていますが、お好みの方法で良いと思います。

シーンの準備

今回は以下のように2つの Wall をキャラクターを挟むように配置しています。

今回はこの Wall をまとめて扱うために Scene Groups に Walls を追加し、そこに2つの Wall をまとめます。

イベントシートの設定

ここでようやく CollisionSeparate objectsが出てきます。

Collision Separate objects

上記の通り、いずれも CharacterWalls の関係として定義しています。

これで、WallsCharacter が衝突して通過しないようになります。その後 ToggleFlip が呼び出され反転されて移動するようになります。

Trigger Once

今回、Trigger Once while true を利用しています。これは、1フレームではこの処理が一度しか実行されないようにするものです。

これを付けないと、この判定が複数回実行されてしまい、壁際でくるくると反転を繰り返してしまいます。

Physics を使うパターン

Forever_MoveH_OnCollision_Flip_Physics の作成

名前の付け方は違いますが、Forever_MoveH_OnCollision_Flip と基本は同じです。

プロパティの追加

Forever_MoveH_OnCollision_Flip に追加して Physics Engine 2.0 を Required Behavior として指定しています。これで、この Behavior を付けるオブジェクトは必ず Physics Engine 2.0 が付いている状態になります。

### ToggleFlip_Physics の実装

Forever_MoveH_OnCollision_Flip と同じです。

doStepPreEvents の実装

Events

Forever_MoveH_OnCollision_Flip と同じように見えるのですが、force を与えるアクションが Apply force という Physics Engine 用のものに変わっています。

【GDevelop 基礎 07】Physics Engine で衝突する - Make Everything Games この時作成したスクリプトだと Add a force でも動作したのですが、今回はうまくいかず Apply force を利用しています。

シーンの準備

先ほどとやることは同じです。Wall_Physics はグループ化します。

また、各 Wall_Physics にも Physics Engine 2.0 を付け、Static にしておきます。詳細は 【GDevelop 基礎 07】Physics Engine で衝突する - Make Everything Games を確認してください。

イベントシートの設定

まず、Condition 側の Collision 判定を確認します。

見て分かる通りで、先程の Collision とは異なっています。以下のように Physics 用は別に用意されているためです。

また、Action 側は Toggle Flip だけだということが分かります。

つまり、Physics Engine 2.0 を使っている場合は、そもそもオブジェクト同士が衝突するため、Separate objects のような処理が必要ないということです。

シーンのキャラクターの Behavior の設定

Forever_MoveH_OnCollision_Flip_PhysicsSpeed は実際には速度を表すものではないため(名前変えるべきでした)、ここでは値を 5 まで下げておきます。

また、Physics Engine 2.0 の設定も Fixed Rotation にチェックを入れておきます。これを入れないと、キャラクターがくるくる回りながら移動してしまいます。
加えて、Gravity Scale0 にします。今回は床を設置していないため無重力として動いて欲しいためです。

動作確認

だいぶざっくりした形になってしまいましたが、Separete objectsPhysics のそれぞれの機能を使った衝突時の処理の記述を試すことができました。