サイトアイコン schilverberch★ROBLOX

【12】elseif、elseを含む複数の条件

プレイヤーの着順で、金、銀、銅などの異なるメダルを授与したい場合があります。
プレイヤーにメダルを授与するために、各メダルに対して個別に if 文を書くこともできますが、elseif を使用することにより、コンパクトで高速なコードが実現できます。
if/then 文が実行されると、最初に見つかった真の条件だけが実行されます。以下は elseif を使用した場合と使用しない場合のコード比較です。elseif の場合、end は一度だけ入力する必要があり、コードが非常に短くなっている点に注目してください。

elseif なしelseif あり
if プレイヤーが1位 then
  金メダルを獲得する
end

if プレイヤーが2位 then
  銀メダルを獲得する
end

if プレイヤーが3位 then
  銅メダルを獲得する
end
if プレイヤーが1位 then
  金メダルを獲得する
elseif プレイヤーが2位 then
  銀メダルを獲得する
elseif プレイヤーが3位 then
  銅メダルを獲得する
end




レース用コースを作成する

このプロジェクトでは、プレイヤー1人用のパルクールコースを作成します。プレイヤーは完走までにかかったタイムにより、異なるメダルが与えられます。まず、コースにスタートとゴール地点を配置します。次にプレイヤーのタイムを計り、異なる種類のメダルを与えるスクリプトを作成します。

パーツとスクリプトを作成する

  1. FinishLine という名前のアンカーにしたパーツを作成し、ParkourScript という名前のスクリプトを追加します。テストを早くするために、スタートとゴール地点を近くに設置します。ゴール地点はスクリプトを作成した後でも移動させることができます。
  1. ParkourScript に下記の2つの変数を作成します。
local timePassed = 0
local finishLine = script.Parent
  1. 後でコードをテストするための print文を持つ finish() という名前の新しい関数を作成します。
local timePassed = 0
local finishLine = script.Parent
 
local function finish()
    print("touched the finish line")
end
  1. プレイヤーがタッチしたときに finish() を実行する partTouched() という名前の関数を作成します。finishLine の Touched イベントを partTouched に紐づけることを忘れないでください。
local function finish()
    print("touched the finish line")
end
 
local function partTouched(otherPart)
    local character = otherPart.Parent
    local humanoid = character:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
        finish()
    end
end
 
finishLine.Touched:Connect(partTouched)
  1. テストプレイし、ゴールに到達すると finish() が呼び出されることを確認します。

finish()が繰り返されるのを防ぐ

現在、プレイヤーがゴール地点にタッチしている間、finish() が何回も呼ばれているのが確認できると思います。それでは都合が悪いので、true または false を格納するブーリアン変数を使用して、finish() が一度だけ呼び出されるようにします。

  1. raceActive という名前の新しい関数を作成し、true に設定します。
local timePassed = 0
local finishLine = script.Parent
 
local raceActive = true
 
-- プレイヤーがフィニッシュラインに触れるたびに実行される
local function finish()
  1. if文に2つ目の条件を追加し、raceActive を呼び出す前に finish()true になっているか確認します。
local function partTouched(otherPart)
    local character = otherPart.Parent
    local humanoid = character:FindFirstChildWhichIsA("Humanoid")
    if humanoid and raceActive == true then
        finish()
    end

 end
  1. finish() が再び呼び出されるのを防ぐため、raceActivefalse に設定します。
local function finish()
    print("touched the finish line")
    raceActive = false
end
  1. ゲームをテストし、finish() が1度だけ実行されることを確認します。

タイムを計る

if文と同じように、while ループも実行するかどうかを判断することができます。プレイヤーの時間を計測するには、while true do ループを使用してタイマーを作成し、raceActive 変数が true の場合にのみ実行するようにします。以前使用したwhile true do ループには条件がなかったので、永遠に実行され続けました。

  1. スクリプトの一番下に while raceActive == true do と入力します。
finishLine.Touched:Connect(partTouched)
 
while raceActive == true do
 
end

whileループが一番下になっていることを確認する
この while true do ループは最終的には停止しますが、必ずスクリプトの一番下に記述する必要があります。こうすることにより、ループに到達する前に、それ以前のコードが確実に実行されるようになります。

  1. プレイヤーのタイムを計測するには、ループで1秒にごとにtimePassed 変数に1を加算します。作業をテストするために print文も入れておきます。
finishLine.Touched:Connect(partTouched)
 
while raceActive == true do 
    wait(1)
    timePassed = timePassed + 1
    print(timePassed)
end
  1. ゲームをプレイし、Outputウィンドウに秒数が表示されることを確認します。

プレイヤーにメダルを与える

if文を作成する

2つの elseif を持つ if/then 文を使用してプレイヤーのゴールタイムを確認し、適切なメダルを与えます。

  1. finishRace() の作業をテストしたので、テスト用の print 文を削除します。コードは1行1行実行するのに時間がかかるので、余分なコードを削除するとゲームの実行が速くなります。
local function finish()
    -- printを削除
    raceActive = false
end
  1. どのタイムにどのメダルを与えるのかを分かりやすくするため、timePassed を含む print 文をコーディングします。文字列と変数名の間に「..」と入力します。これは、文字列と変数、または文字列同士をを繋げる、結合と呼ばれるものです。
local function finish()
    raceActive = false
    print("You finished in " .. timePassed)
end
  1. プレイヤーが金メダルを獲得したかどうかをチェックするには、if 文で、プレイヤーがゴールすると予想される最速タイムと timePassed を比較すれば良いわけです。この例では、プレイヤーのタイムが10秒以下かどうかをチェックしています。
local function finish()
    raceActive = false	
    print("You finished in " .. timePassed)
 
    if timePassed <= 10 then
        print("You get a gold medal!")
    end
end
  1. テストプレイし、金メダルが与えられることを確認します。

elseIf条件を追加する

金メダルをのテストが済んだところで、次に elseif キーワードを使用して、他のメダルの条件をコーディングします。

  1. 銀メダルについては、elseif と入力した後に、与えられるタイムの範囲を指定します。この例では、10秒より大きく、20秒以下を範囲としています。

    elseifthen で締めくくり、次の行に print 文を追加します。
local function finish()
    raceActive = false	
    print("You finished in " .. timePassed)
 
    if timePassed <= 10 then
        print("You get a gold medal!")
    elseif timePassed > 10 and timePassed <= 20 then
        print("You get a silver medal!")
    end 
end
  1. 次に銅メダルです。見なくてもコーディングできると思います。下記の例では、20秒より大きく、30秒以下を範囲としています。
local function finish()
    raceActive = false	
    print("You finished in " .. timePassed)
 
    if timePassed <= 10 then
        print("You get a gold medal!")
    elseif timePassed > 10 and timePassed <= 20 then
        print("You get a silver medal!")
    elseif  timePassed > 20 and timePassed <= 30 then
        print("You get a bronze medal!")
    end
end

elseif をスコープ内に収める
if 文は多くの elseif 条件を持つこともありますが、すべて if/then 文の最初の行と if/then 文の end の間にコーディングされる必要があります。

  1. 銀メダルと銅メダルのテストを行ってください。

問題解決のヒント
・各 elseif では、条件の後に then を入れる必要があります。
 例:elseif timePassed > 10 then
partTouched() では、if 文の2つ目の条件で == が使われていることを確認します。
 例:raceActive == true
・各 elseif がスコープ内にあることを確認します。各 elseif 条件は if/then 文の最初の行と end の間に入れる必要があります。

elseを使って確認する

プレイヤーがメダルを獲得できなかった場合、もう一度トライしてみるように促します。この場合、else 文が使用できます。これは、他の条件が true でなかった場合に実行され、メッセージを表示するものです。

  1. 最後の elseif の下、end の上に新しい行を追加し、else と入力します。then入れないでください。else の下で print 文を使用してもう一度トライするように促します。
local function finish()
    raceActive = false	
    print("You finished in " .. timePassed)
 
    if timePassed <= 10 then
        print("You get a gold medal!")
    elseif timePassed > 10 and timePassed <= 20 then
        print("You get a silver medal!")
    elseif  timePassed > 20 and timePassed <= 30 then
        print("You get a bronze medal!")
    else
        print("Try again!")
    end	
end
  1. テストプレイし、“Try again!” のメッセージを確認します。30秒を超えるとメッセージが表示されるはずです。

else文は、常にif文の最終チェックを行うものとして扱います。else文の下にifelseifelseのような条件や、元のif文のendがないことを確認します。問題解決のヒント
else 文の後に、timePassed <= 20then のような条件がないことを確認します。
else 文は、常に if 文の最終チェックを行うものとして扱います。else 文の下に ifelseifelse のようなキーワードは決してあってはいけません。if で始まり、最後は end で終了していることを確認します。

完成したスクリプト

local timePassed = 0
local finishLine = script.Parent
 
-- レースが終わったときに、finishとタイマーが繰り返されないようにするために使用する
local raceActive = true
 
-- プレーヤーがフィニッシュラインに触れると実行さる
local function finish()
    raceActive = false	
    print("You finished in " .. timePassed)
 
    if timePassed <= 10 then
        print("You get a gold medal!")
    elseif timePassed > 10 and timePassed <= 20 then
        print("You get a silver medal!")
    elseif  timePassed > 20 and timePassed <= 30 then
        print("You get a bronze medal!")
    else
        print("Try again!")
    end	
end

-- フィニッシュラインに触れたら呼ばれる
local function partTouched(otherPart)
    local character = otherPart.Parent
    local humanoid = character:FindFirstChildWhichIsA("Humanoid")
    if humanoid and raceActive == true then
        finish()
    end
end

finishLine.Touched:Connect(partTouched)
 
-- レースが実行されている間、時間をカウントアップする
-- これはスクリプトの一番下に記述する必要がある
while raceActive == true do 
    wait(1)
    timePassed = timePassed + 1
    print(timePassed)
end

参考

実は、elseif をもう少しコンパクトにし、実行速度を上げることができます。

最初の timePassed <= 10 が true になった場合、金メダルを受け取った後、if 文から抜け出ます。つまり、その下の行「elseif timePassed > 10 and timePassed <= 20 then」には行かないため、timePassed は10よりも大きいことは確実です。よって、timePassed > 10 は不要ということになり、elseif timePassed <= 20 then だけでよいことになります。銅メダルも同じことが言えますので、最終的には下記のコードで問題ないでしょう。

    if timePassed <= 10 then
        print("You get a gold medal!")
    elseif timePassed <= 20 then
        print("You get a silver medal!")
    elseif timePassed <= 30 then
        print("You get a bronze medal!")
    else
        print("Try again!")
    end	
モバイルバージョンを終了