【Luaによる制御(1)】(るあによるせいぎょ いち)


Luaに触ったことがない人向け、Lua講座。
Rigid Chipsのモデルデータが書ける事を前提で進めますんでよろしく。
(1)で扱う内容は、「Scriptで出来たことをLuaでする」です。
Luaで新しくできるようになった事は(2)で取り扱います。

まずは骨組みを作ろう

とりあえず雛形です、適当なファイルに保存してRigid Chipsで開いて下さい。

val{}
key{}
body{
	core(){}
}
Lua{
	function main()
	end
}

このモデルは何もしません、ただLuaを呼び出し、終了しています。

functionキーワードはendキーワードまでのブロックを"関数名(引数)"の関数として定義します。
ここで重要なのは、関数mainがRigid Chips側からLua側へのエントリポイントだという事です。
Rigid Chipsは毎フレームmain関数を呼び出します。

試しにfunction main()とendの記述を削除してみてください、
Rigid Chipsがエントリポイントを見失いエラーを吐くはずです。

今はとりあえずmain関数を作らないとダメなんだ、ぐらいに覚えておいてください。

変数の宣言とコメント

次に変数の宣言とコメントの付け方です。

Luaのコメントには三種類あり、以下の通りです。

-- 一行コメント、改行までをコメントアウトする。
--[[ 複数行に渡るコメント、
     角括弧二つで囲まれたブロックをコメントアウトする。 ]]
# 行頭のシャープも改行までをコメントアウトする。


変数の宣言は任意の位置で行え、

hoge

のように"変数名"のみで済みます。

明示的な型名の宣言は不要で、これは変数の持つ値(属性とでも言いましょうか)の一部として型の情報も含まれ、自動的に判別されるためです。
初期化されなかった変数はnilという型のnilという値を持ち、一般にこれは他のどの型と比較しても異なることが保証されています。

nil型以外のLuaで使用可能な型は、「ブーリアン、数値、文字列、関数、ユーザーデータ, スレッド、テーブル」と様々ですが、その用法については(2)で述べたいと思います。
変数が数値型、あるいは数値に変換可能な型(多分後述)ならば、一通りの算術演算子が使用できます。

hoge = moge        -- 代入
hoge = -moge       -- 符号反転
hoge = hoge + moge -- 足し算
hoge = hoge - moge -- 引き算
hoge = hoge * moge -- かけ算
hoge = hoge / moge -- 割り算
hoge = hoge ^ moge -- 累乗

なお、通常意識する必要はありませんがLua内で宣言された数値型の変数は内部的に倍精度浮動小数点型として扱われます。
(学生氏が改変していないならば、ですが)

RC側のデータにアクセスするには

次にLuaからRigid Chips側のデータにアクセスする方法です。

先ほどの雛形を以下のように改変し、Rigid Chipsで開いてください。

val{
	Hoge()
}
〜
Lua{
	function main() -- RCから関数mainが毎フレーム呼び出される。
		HOGE = _FPS() -- RC側の変数Hogeに_FPS()の返値を代入する。
		out(0,"FPS= ",HOGE) -- RCの_Printと同じ作用をする関数。
	end
}

上手く行けばHogeの値がFPSっぽい数字になっているのを見ることが出来るはずです。
Rigid Chips側の変数名、関数名を大文字として扱うことでRigid Chips側のデータにアクセス出来ます。
outという関数を使っていますが、これは_Print関数をLua側から呼び出す関数で、引数の渡し方は_Print関数と同じです。

Rigid Chips側の変数にLua側からアクセスを行うことは出来ますが、
その逆、つまりRigid Chips側からLua側の変数にアクセスすることは出来ません。

//無効なモデルデータの一例
val{}
key{}
body{
	core(){
		N:wheel(power=hoge){} // よーし、hogeパワーでぐるぐるだー
	}
}
Lua{
	hoge = 0 -- hogeはゼロから始めよう!
	function main()
		hoge = hoge + 1 -- 毎フレームhogeはいっこづつ増えるよ
		out(0,hoge) -- 今何hoge?
	end
}

このモデルデータを開くと、待てど暮らせどwheelが動いてくれない様子が見られるかと思います。
つまり、Body内で使える変数はVal内で宣言された変数だけということです。

// 正しいモデルデータの一例
val{
	hoge(default=0) // hogeはゼロから始めよう!
}
key{}
body{
	core(){
		N:wheel(power=hoge){} // 変数hogeはvalで宣言されてるから、パワーになるぜー
	}
}
Lua{
	function main()
		HOGE = HOGE + 1 -- 毎フレームhogeはいっこづつ増えるよ
		out(0,HOGE) -- 今何hoge?
	end
}

このようにVal内に変数を宣言すれば、Body内で使えますね。

if文による制御

さて、次はif文による制御です。

if文は以下のような構造をとります。

if 条件式 then
	処理
{ elseif 条件式 then
	処理 }
[ else 
	処理 ]
end

{}で囲った部分は省略可能で、任意な回数繰り返して書くことも許されています。
[]で囲った部分は省略可能です。

条件式に使用できるのは以下の通りです

変数   -- nil値とfalse値以外は全て真となる(数値型の0も真)
A == B -- AとBが等しければ真を返す
A ~= B -- AとBが等しくなければ真を返す
A <  B -- AがB未満であれば真を返す
A <= B -- AがB以下であれば真を返す
A >  B -- つまりB <  A
A >= B -- つまりB <= A
A and B -- 論理積
A or B -- 論理和
not A -- 論理否定

喜ばしいことにif文のネストも可能です。

さて、これでScriptで書かれたコードをLuaで書き直す事が出来るような気がしますが、それだけではLuaを使う意味がありませんね。
いよいよ次回はLuaで新しく出来るようになったことに挑戦したいと思います。

つづく。