【GDevelop 素振り】チェックポイント機能

プラットフォーマーチュートリアルのチェックポイント機能

プラットフォーマー チュートリアル Part 8:チェックポイントをゲームに追加しよう - GDevelop documentation

上記の公式のチュートリアルの最後でチェックポイント機能を作成しています。

チュートリアルでは Scene variables として CheckpointX, CheckpointY の変数を用意します。
シーンの開始時には、プレイヤーの初期座標をそこに入れます。
シーン中のチェックポイント用のオブジェクトと衝突した際には、その座標をそこに入れます。

そして、プレイヤーがやられた場合には、その CheckpointX, Y の座標に戻すというものです。

Extension の Checkpoints

Extension として Checkpoints が公開されています。

Checkpoints - GDevelop documentation

サンプルプロジェクトを開いてみると、以下のように関数のみで構成された Extension であることがわかります。

利用のされ方

引き続きサンプルプロジェクトで利用のされ方を確認してみます。

まず、シーンには PlayerCheckpoint のオブジェクトが複数あることを確認しておきます。

チェックポイントの保存

  • シーンの開始時には Player の座標を保存 (Save checkpoint) している
  • PlayerCheckpoint オブジェクトに衝突した際に、Checkpoint の座標を保存している

ここまでは、プラットフォーマーチュートリアルとほぼ変わりませんが、一つ異なることがあります。

保存先の CheckpointScene variables ではありません。(もちろん Global variables でもない)

Checkpoint of Player となっているので、Player の Object variables かとも思いましたが、そこにもありません。あるのは dead フラグだけです。

では、このままこの保存処理の実態である、SaveCheckpoint 関数を見ていきます。

SaveCheckpoint 関数

設定・パラメータ

改めてシーンが始まった際の使われ方を見てみると以下のようになっており、ToSaveObjectPlayerCoordinateX, CoordinateYPlayer.X()/Y() がそれぞれ入っていることが分かります。

最後のパラメータである CheckpointName ですが、これは次のイベントで利用される値のキーのようなものです。 "Checkpoint" という文字列が渡されていることだけ押さえておきましょう。

イベント

続いてイベントです。

まず、GetArgumentAsNumber("CoordinateX")` ですが、パラメータとして渡ってきた X 座標、Y 座標を数値として取り出しているようです。

GetArgumentAsNumber は現在は利用しないようです。直接パラメータ名を書くだけに変更されています。

[Solved] GetArgumentAsNumber() not proposed in expression editor (This is intended) - #2 by Keith_1357 - Bugs reports - GDevelop Forum

続いて、__Checkpoints.Position["X" + GetArgumentAsString("CheckpointName")]です。
まず、GetArgumentAsString("CheckpointName") を渡された "Checkpoint" 文字列に置き換え、"X" と結合すると __Checkpoints.Position["XCheckpoint"] となることがわかります。

ここに CoordinateX の値を代入しているようです。

そして、この __Checkpoints.Position["XCheckpoint"]ToSaveObject つまり今回の使われ方では Player の変数であることが分かります。

では、実際にデバッガーを使って Player のオブジェクト変数を見てみます。

型情報付きの JSON 形式に構造化されていますが、__Checkpoints.Position["XCheckpoint"] (この場合は __Checkpoints.Position.XCheckpoint と考えた方が見やすいかも) であることが分かります。

ただ、前述で確認した通り、Player のオブジェクト変数の定義にはこの __Checkpoints.Position は存在しないため、この変数のデータはゲーム中に追加されるものである事がわかります。

ちなみに、ゲーム開始時以外に、Checkpoint のオブジェクトと衝突した時にも以下のようになるだけで、保存される座標が衝突した Checkpoint のものになるだけです。

LoadCheckpoint 関数

続いて、読み出しの部分も見ていきます。

設定・パラメータ

もう一つ SetIgnoreUndefined というパラメータがあるのですが、上記の通り「イベントシートの文章」にも記載されておらず、FALSE で固定のようなので無視しました。

この関数は PlayerTriggerDeath 関数で以下のように呼び出されています。

ToLoadObject, ToMoveObject の両方に Player が渡されており、SaveCheckpoint の方にも出てきた CheckpointName"Checkpoint" という同じ値で渡されているのが分かります。

イベント

まず条件部分についてですが、要は先程の JSON で見た XCheckpointYCheckpoint の値について確認しています。

前述の通り SetIgnoreUndefined は必ず FALSE なので、どちらかが欠けていても条件を満たします。

そしてアクション部分ですが、ToMoveObject つまり今回の例では Player の座標を ToLoadObject つまりこちらも Player ですが、Player__Checkpoints.Position 変数に保存されている座標に置き換えているということです。

まとめ

「プラットフォーマーチュートリアル」の方は、Scene variables にチェックポイントの座標を保存し、イベントシートを通して、プレイヤーの初期位置や、それぞれのチェックポイントオブジェクトの座標を衝突時に保存し、プレイヤーが失敗した時にはその座標に戻すということをしていました。

「Checkpoints Extension」の方は、保存先が特定のオブジェクト(例では Player) のオブジェクト変数 (Object variables) でした。
それ以外の点については、サンプルでの使われ方としてはですが、プラットフォーマーチュートリアルとそれ程違いはありませんでした。

Scene variables ではなく Object variables に保存する利点はありそうですが、今回確認した「単独のプレイヤーのチェックポイント機能」という点ではどちらでも問題はなさそうです。