変数について
原文:Variables - Bohemia Interactive Community
変数 はデータのための箱である。一度作った変数は参照したり、改変することが出来る。
目次
前提知識
下記のリンクはこの記事を理解するのに必要な基礎を紹介しています。
初期化
まずはじめにあなたがしなければいけないことは、変数の名前を決めることです。この名前は 識別子 と言います。
名前を決めたら、ゲームエンジンにこの識別子を使うことを知らせなければなりません。これを 初期化 と言います。そしたら今変数に対して何でもできるようになります。
心配しないで: 大袈裟に聞こえるかもしれませんが、初期化は変数に値を割り当てるだけで出来ます。
myVariable = 0;
未定義もしくは初期化されていない変数にアクセスしようとすると nil を返します (未定義値)。str コマンドで 未定義な変数を 文字列 に変換しようとすると常に scalar bool array string 0xe0ffffef (in Armed Assault) or scalar bool array string 0xfcffffef (in Operation Flashpoint) を返します。
myString = str(undefinedVar); myString => "scalar bool array string 0xe0ffffef"
このように変数は初期化しないと、どんな 操作 も出来ません。
削除
変数が作られると、あなたのPCのメモリを食います。小さい変数なら気にすることでもないですが、大量に大きな変数を使う際は必要なくなった変数を解放すべきです。これは nil コマンドを代入することで出来ます。
hugeVariable = nil;
名前空間
変数はゲーム内の特定のエリア(名前空間)でしか見えません。これは別の scripts 間での名前の衝突を防ぎます。
ARMA3には3つの名前空間が有ります
- local ローカル
- 変数は定義された script 内でしか見えない。
- global グローバル
- 定義されたコンピュータ内全体で見える。
- public パブリック
- ネットワークに接続された全てのコンピュータで見える。
ローカル変数
ローカル変数は特定の script 内だけで見える。そのスクリプト内のすべてのコードから変数にアクセスでき、スクリプト内から呼ばれた 関数 も含まれる。
script に対してローカルな変数の 識別子 は常にアンダースコアからはじめなければいけません。
_myLocalVariable = 0;
関数の中では加えて private コマンドを使って変数をローカルに指定すべきです。さもないとその関数を呼んだスクリプト内のローカル変数を改変してしまうでしょう。
private "_myLocalVariable"; _myLocalVariable = 0;
配列 を使って2個以上の 識別子 を private コマンドに入力できます。
private ["_myLocalVariable1", "_myLocalVariable2", ...];
グローバル変数
グローバル変数は定義されたコンピュータ内全体から見える変数です。ミッションエディタ内でユニットに与えた名前もまたそのユニットを示すグローバル変数となり、再定義・改変してはいけないものです。
グローバル変数の 識別子 はアンダースコアからはじめては いけません。
myGlobalVariable = 0;
パブリック変数
パブリック変数はグローバル変数がネットワーク内のすべてコンピュータ上で見えるようになったものです。とは言え、ARMA3では本当の意味でのパブリック変数はありません、が同じように真似ることは出来ます。
publicVariable コマンドを使うことでグローバル変数をネットワーク上に伝えることが出来ます。このコマンドを使われると変数は全ての クライアント で同じ値となります。変数を再度改変した場合はもう一度手動で publicVariable を使って全てのクライアントに伝えなければいけません。
スコープ
ローカル変数が 制御構文 (すなわち. if, for, switch, while) 内で初期化された場合、そのスコープはその構文の中に留まります。(すなわち その構文の外では未定義として扱われる)。これはグローバル変数やパブリック変数には適応されません。
if (alive player) then {_living=true}; hint format["%1",_living];
Returns "scalar bool array string 0xe0ffffef", since the local variable was not initialized before being used within a control structure.
_dead=true; if (alive player) then {_dead=false}; hint format["%1",_dead];
Returns "false", since the variable was initialized before the if...then.
To initialize local variables, so that they are available throughout the whole script (including any control structures), either initialize it via the private command (e.g. private ["_varname"];), or by assigning a default value to it (e.g. varname=0;).
データ型
変数は特定の値を格納し、値の種類によって変数の 型 が決まります。演算子やコマンドによって異なる型の変数が必要となります。
詳しくは データ型 記事参照。
マルチプレイヤーでの留意事項
Storing vars and functions into global vars without securing them with compileFinal is a very bad practice in MP.
Basically, if you have a script installed on a server in mission file that uses functions stored in unprotected variables then hackers can overwrite that function attached to a global variable and make it execute code for everyone and do a lot of nasty stuff. So please put all of the code for each function in a SEPARATE file and initialize them like this:
myGlobalVarFunction = compileFinal preprocessFileLineNumbers "Dir\where\function\is\fnc_globalVarFunction.sqf";
That way, the function can be called and spawned without it being subject to hackers that attempt to overwrite the global variable "myGlobalVarFunction".
Everyone happy :)