[GameMaker: Studio] ローカル変数の有効範囲(スコープ)

※注:この記事は古いバージョンのものです。
正確にいつからかはわかりませんが、v1.4の途中辺りからvar宣言をするとブロック内のスコープが有効になっているようです。
たとえばcreateイベントでvar宣言なしで設定した変数は他のイベントや呼び出し先スクリプトでも共通して読み書きできますが、var宣言した変数は他で参照するとエラーとなります。


gms_var_scope_1

GM:Sの変数は特に明示しない場合は基本的にそのインスタンスのみで有効なローカル変数となります。

では、そのインスタンスの中ではどこまで有効なのでしょうか?

まずは一番上の画像を見てください。
ちょっとわかりにくいですが、var a0 = 123;createイベントに記述していますが、drawイベントでa0が参照できないとしてエラーが発生しています。

このようにvarを付けた変数はそのファイル(イベント)内のみで有効な変数となり、その処理を終えた時点で破棄されます。

gms_var_scope_2

次の画像ですが、{ }内でvar宣言をし、{ }外で数値を足していますがその時点ではエラーとはならず、drawイベントに進んでからエラーとなっています。

GameMaker 8の頃まではGML{ }で括るという規則がありましたが、GameMaker: Studioになってからはそれはなくなり、単なる{ }は意味を持たなくなりました。
(もちろんif文やfor文等では{ }は使用しますが、やはり変数のスコープには影響はありません)
すなわち、このvar a3は最初の例のvar a0と同じことが起こっています。

gms_var_scope_3

この画像で、{ }が変数のスコープに影響を与えないということがよりわかります。
{ }内で宣言したvar a4{ }外で数値を足していますが、{ }外で宣言されたa3と同じ結果になっています。

ローカル変数にはもう一つ重要なことがあります、最初に「そのインスタンス中で有効」と書きましたが、これは「オブジェクト内のみではなく、イベントから呼び出されたスクリプトもインスタンスのローカル範囲に含まれる」という点です。

画面では変数b1b2の値が表示されていますが、この値を設定しているのはオブジェクトではなく、そこから呼び出されたスクリプトの中です。
宣言することなくその値がそのままdrawイベントで参照できていることからも、スクリプト中の変数はインスタンスのローカル変数であるとわかります。

もちろんこれは、呼び出し元のインスタンスに従属するローカル変数となるので、同じスクリプトを複数のオブジェクトから呼び出しても、中の値は各インスタンスで独立したものとなります。

もしスクリプトの中だけで一時的に値を格納したい場合は、最初の例のようにvarを付けてください。varを付けることでスクリプト内だけで有効な変数となります。

GM:Sにおけるスクリプトは、文中に展開されるマクロやインクルードファイルである、と考えるとその動作がわかりやすくなるかもしれません。

色々なオブジェクトで共通化できる処理はスクリプト化するクセをつけておくと、修正や変更を最小限の作業で行えるとか、他のプロジェクトでの使い回しができるなんていう利点がありますので是非活用しましょう。