制御構造は、Luau コードの実行フローを管理するステートメントです。制御構造には主に4つのタイプがあります:
- if then else ステートメントは、指定された条件が true の場合にのみコードを実行します。コードの実行は繰り返されません。
- repeat ループ は、コードを実行し、条件が true の場合に実行を繰り返します。
- for ループ は、指定された入力に基づいて決められた回数だけコードを実行します。
if ステートメント、while ループ、および repeat ループの条件は、任意の Luau 表現または値にすることができます。もし値が false や nil でない場合、Luau はそれを条件文で true と評価します。他のスクリプト言語とは異なり、Luau はゼロと空の文字列を true と見なします。
If ステートメント
基本的な if ステートメントはその条件をテストします。条件が真であれば、Luau は then と end の間にあるコードを実行します。
if 条件が偽の場合、追加の条件をテストするために elseif ステートメントを使用することができます。すべての if および elseif 条件が失敗した場合にコードを実行するには、else ステートメントを使用します。elseif と else の部分はどちらもオプションですが、初めの if ステートメントなしに使用することはできません。
if、elseif、および else の条件の連鎖の中で、Luau は条件を上から下にテストし、最初の true 条件で停止し、その後のコードを実行します。
if 2 + 2 == 5 thenprint("二足す二は五です") -- 条件が偽であるため、印刷されませんelseif 2 + 3 == 5 thenprint("二足す三は五です") -- 二足す三は五ですelseprint("すべての条件が失敗しました") -- 以前の条件が真であるため、印刷されませんend
While ループ
while—do ループは、指定された条件が真か偽かを評価します。条件が false または nil の場合、ループは終了し、Luau はループ内のコードをスキップします。条件が true の場合、Luau はループ内のコードを実行し、プロセスを繰り返します。
local timeRemaining = 10while timeRemaining > 0 doprint("残りの秒数: " .. timeRemaining)task.wait(1)timeRemaining -= 1endprint("タイマーがゼロになりました!")--[[ 結果としての出力:残りの秒数: 10残りの秒数: 9残りの秒数: 8残りの秒数: 7残りの秒数: 6残りの秒数: 5残りの秒数: 4残りの秒数: 3残りの秒数: 2残りの秒数: 1タイマーがゼロになりました!]]
無限ループ
条件に true を設定することで、while—do ループを使用して無限ゲームループを書くことができます。
while true doprint("ループ中...")task.wait(0.5)end--[[ 結果としての出力:ループ中...ループ中...ループ中...ループ中......]]
Repeat ループ
repeat—until ループは、条件が真になるまで繰り返します。条件テストはコードブロックが実行された後に評価されるため、コードブロックは必ず少なくとも1回実行されます。他の言語とは異なり、repeat—until ループ内に宣言されたローカル変数のスコープは条件を含みます。
local currentGoblinCount = 18-- ゲーム内の最大25体までゴブリンを生成repeatspawnGoblin()currentGoblinCount += 1print("現在のゴブリンの数: " .. currentGoblinCount)until currentGoblinCount == 25print("ゴブリンが再配置されました!")--[[ 結果としての出力:現在のゴブリンの数: 19現在のゴブリンの数: 20現在のゴブリンの数: 21現在のゴブリンの数: 22現在のゴブリンの数: 23現在のゴブリンの数: 24現在のゴブリンの数: 25ゴブリンが再配置されました!]]
For ループ
for ループは、指定された回数だけコードを実行します。これは 数値カウンタ に基づくか、コレクション内のアイテムの数 に基づきます。
数値 for ループ
for—do ループは、カウンタを使用してループを実行する回数を決定します。ループは開始値、終了値、およびオプションの増分で宣言されます。
Luau はカウンタを開始値に等しくし、for ループ内のコードブロックを実行し、次にカウンタに増分を加えます。増分が正の場合、プロセスはカウンタが終了値以上になるまで繰り返されます。増分が負の場合、プロセスはカウンタが終了値以下になるまで繰り返されます。
オプションの増分はデフォルトで 1 です。必ずしも整数である必要はありません。
for counter = 1, 3 doprint(counter)end--[[ 結果としての出力:123]]for counter = 1, 6, 2 doprint(counter)end--[[ 結果としての出力:135]]for counter = 2, 0, -0.5 doprint(counter)end--[[ 結果としての出力:21.510.50]]
ジェネリック for ループ
ジェネリック for ループは、数のシーケンスではなくコレクション内のアイテムを繰り返します。ジェネリック for ループを使用すると、コレクション内の各アイテムに対してコードを実行することができ、各アイテムをコード内で簡単に使用できます。
for ループは、さまざまなタイプのコレクションを繰り返すために関数またはイテレータが必要です。グローバルな ipairs() は配列用のイテレータを返し、グローバルな pairs() は辞書用のイテレータを返します。string ライブラリは string.gmatch() を提供して文字列を繰り返します。
一般化された反復
Luau では、イテレータ関数 ipairs() を使用するのではなく、テーブル上で直接 in キーワードを使用してテーブルを繰り返すことができます:
for i, v in {1, 2, 3, 4, 5} doprint(i, v)end
一般化された反復では、カスタムイテレータ関数を作成するために __iter メタメソッドを使用することもできます。この便利な例では、配列の最後の要素から最初の要素に向かって逆順に繰り返します:
local myTable = {1, 2, 3, 4, 5}
myMetatable = {
__iter = function(t)
local i = #t + 1
return function()
i -= 1
if i > 0 then
return i, t[i]
end
end
end,
}
setmetatable(myTable, myMetatable)
for i, v in myTable do
print(i, v)
end
--[[ 結果としての出力:
5 5
4 4
3 3
2 2
1 1
]]
配列
ipairs() 関数は、テーブル内の数値インデックスを反復し、各要素の index と value を返すイテレータを返します。これはすべてのインデックスが数値である配列に適しています。
local array = {"a", "b", "c", "d", "e"}for index, value in ipairs(array) doprint(index, value)end--[[ 結果としての出力:1 a2 b3 c4 d5 e]]
辞書
pairs() 関数は、テーブル内のすべてのインデックス(数値インデックスを含む)を反復し、辞書内の各エントリについて key と value を返すイテレータを返します。辞書テーブル内の要素を横断する順序は任意です。これは、アイテムが数値以外のインデックスで順不同に保存される辞書を反復するのに適しています。
local dictionary = {[1] = "a",["Hello"] = "b",[5] = "c",[true] = "d",["World"] = "f",[false] = "e"}for key, value in pairs(dictionary) doprint(key, value)end--[[ 結果としての出力:Hello btrue dfalse eWorld f5 c1 a]]
ループを強制終了する
ループを強制的に終了するには、break キーワードを使用します。以下のサンプルコードは、無限の while—do ループを終了する方法を示しています。
local secondsElapsed = 0local timeout = 5while true dotask.wait(1)secondsElapsed += 1print("経過秒数:", secondsElapsed)if secondsElapsed == timeout thenbreakendendprint("5秒が経過しました。次に進む時間です!")--[[ 結果としての出力:123455秒が経過しました。次に進む時間です!]]
ループをスキップする
ループをスキップして再開させるには、continue キーワードを使用します。for ループはカウンタを反復し、while と repeat—until は続行する前にループ条件をチェックします。以下のサンプルコードは、特定の ClassName の子要素すべてを取得します。
local function GetChildrenOfClass(parent: Instance, className: string): {Instance}
local children = {}
for _, child in parent:GetChildren() do
if child.ClassName ~= className then continue end -- ループを反復
table.insert(children, child)
end
return children
end