見出し画像

【GMS2 Knowledge】イベントの実行順について(1)

GMSユーザーのためのナレッジ記事を書いていきます。

イベントってなんぞ?

イベントはGMSでオブジェクトを作ると「Create」や「Step」といった処理を行うカテゴリのようなもので、それぞれ処理方法が分かれます。
大まかに、「1度だけ呼ばれるイベント」か「毎フレーム呼ばれるイベント」かに分かれます。
例えば「Create」イベントはインスタンスが生成された時に1度だけ呼ばれるイベントです。

このイベントは1つ1つ設定していくことができます。
例えば「Create」イベントと「Step」イベントの2つを設定することができるわけです。

複数のイベントを設定したときに、どちらが先に実行されるのか?という問題があります。
上記の例では「Create」が先だということは何となくわかるのですが、さらに細かくイベントの実行順を検証してみます。

結果

以下は、各イベントにデバッグメッセージを仕込んで実行した結果になります。

create event
game start event
room start event
**********************************.
Entering main loop.
**********************************.
begin step event
step event
end step event
pre draw event
begin draw event
draw event
draw end event
post draw event
begin draw gui event
draw gui event
end draw gui event
room end event
game end event

「Create」イベントの後は「Game Start」イベント、続いて「Room Start」イベントです。
実際は複数のインスタンスが配置されているわけですから、正確には少しだけ違うので、細かく解説します。

1. インスタンスが配置される
2. インスタンスの「Creation Code」が実行される(Room Editorでのインスタンス編集画面のコード)
3. インスタンスの「Create」イベントの処理が実行される
<全インスタンスが配置されるまで1~3が繰り返される>
4. ゲーム開始の最初のRoomなら「Game Start」イベントが実行される
5. Room Editorの「Room Creation Code」が実行される
6. 「Room Start」イベントが実行される

上記が、生成時のイベント処理順です。
1~3のインスタンス生成順は、Room Editorで「CTRL+ALT+I」を押すか、メニューの中の「Room>Instance Creation Order」を選んで、左側に表示される「Instance Creation Order」のインスタンス一覧からインスタンスの生成順を変更することができます。

重要なポイント「インスタンス生成順」

インスタンスの生成順は非常に重要です。
例えば、インスタンスAの「Create」イベントで以下のようなコードを記載したとします。

with(oPlayer)
{
   x = 100;
}

インスタンスAがoPlayerに対してx座標を100pxの位置に移動させる というシンプルなコードです。
ただし、これはoPlayerがあれば正常に実行されます。

このoPlayerというインスタンスが存在する前に、上記のコードを実行するとエラーになります。
存在する前か後か、というのが「インスタンス生成順」なのです。

よくあるミス

例えば1つのオブジェクトでグローバル変数を定義し、そのグローバル変数を他のインスタンスが「Create」イベントで参照する という作りにする事があります。
この際、イベント実行順・インスタンス生成順を理解していないとこんなエラーが出ます。

うーん、GameMakerではおなじみのエラー画面です。いっそ安心感すらあるエラー画面です。
これは未定義のグローバル変数を参照してますっていうエラーです。

「インスタンス生成順」で説明したoPlayerが存在していなかった状況と同様に、グローバル変数を定義するインスタンスより先に生成され、参照しちゃった結果です。

「重要な変数を定義をしたり、参照されるインスタンスは最優先で生成する」のがシンプルな回避策です。