サイトアイコン schilverberch★ROBLOX

3-5 else/if の練習ーポイントを与える

このプロジェクトでは、パーツに触れたときの色に応じてポイントが増えたり減ったりするパーツを作成します。ポイントはリーダーボードに表示します。
青の場合はプレイヤーに数ポイント与えられます。緑色の場合、たくさんのポイントが得られます。赤の場合はポイントを奪います。

https://prod.docsiteassets.roblox.com/assets/education/coding-3/coding3_colorPointBlockFinalizedExample.mp4

プロジェクトの設定

ポイント付与部分は、ポイントが関連する様々なゲームに応用できます。例えば、プレイヤーがポイントを集めるアドベンチャー ゲームなどに利用できるでしょう。

リーダーボードの作成

このプロジェクトを作成するには、ポイントを表示するリーダーボードと、色が変化するパーツが必要です。リーダーボードを追加するプログラムは下記の通りです。現時点ではプログラムの意味を理解しなくても構いません。そのまま入力してください。

  1. ServerScriptServiceにスクリプトを追加します。PlayerSetup という名称にしましょう。リーダーボードは、Player の下に「leaderstats」という名称のフォルダを作成することで表示されます。
-- リーダーボードは各プレイヤーごとに作成する
local function onPlayerJoin(player)
    local leaderstats = Instance.new("Folder")  -- フォルダの作成
    leaderstats.Name = "leaderstats"            -- この名称を使うとリーダーボードとして表示される
    leaderstats.Parent = player                 -- player を親にする

    local points = Instance.new("IntValue")     -- 整数値を格納するオブジェクトを作成
    points.Name = "Points"                      -- この名称がリーダーボードに表示される
    points.Value = 0                            -- 初期値は0
    points.Parent = leaderstats                 -- leaderstatsを親にする
end

-- プレイヤーが入室してきた際に発生するイベントに接続
game.Players.PlayerAdded:Connect(onPlayerJoin)

色変化パーツ

パーツの色を、赤…緑…青と変化させます。

  1. パーツを作成し名前を PointPart にします。その下に PointScript という名前のスクリプトを追加します。
  2. PointPart にアクセスしやすいように pointPart という変数に入れておきます。
local pointPart = script.Parent
  1. 赤、緑、青のオブジェクトを予め作成しておき変数に入れておきます。こちらは以前行いましたね。
local pointPart = script.Parent

-- 色
local blue = Color3.fromRGB(0, 0, 255)
local green = Color3.fromRGB(0, 255, 0)
local red = Color3.fromRGB(255 ,0, 0)
  1. 少量のポイント、大量のポイント、減算するポイントを設定します。
-- 色
local blue = Color3.fromRGB(0, 0, 255)
local green = Color3.fromRGB(0, 255, 0)
local red = Color3.fromRGB(255 ,0, 0)

-- 各ポイントの値
local smallPoints = 10
local largePoints = 50
local losePoints = 100

Playersサービスの取得

リーダーボードにアクセスするには、Explorer の Players にアクセスする必要があります。game:GetService() を使用することで、Playersサービスを取得することができます。ちなみに「game.Players」としても同じですが、GetService() を使用した方がより安全ということでこのようにします。

  1. 次のように入力して Players サービスを取得します。 「local Players = game:GetService(“Players”)」
-- 各ポイントの値
local smallPoints = 10
local largePoints = 50
local losePoints = 100

-- Playersサービスの使用
local Players = game:GetService("Players")

関数とイベント

PointsScript には 2 つの関数が必要です。ポイントを加算したり減算したりする関数と、プレーヤーがパーツに触れたときに実行される関数です。

  1. givePoints() という名前の新しい関数します。パラメータはplayerです。テスト用に print 文を入れておきましょう。
local Players = game:GetService("Players")

-- ポイントの加算と減算
local function givePoints(player)
    print("Giving player points")
end
  1. その下に、 otherPartという名前のパラメーターを持つpartTouched()という名前の 2 番目の関数を作成します。
-- ポイントの加算と減算
local function givePoints(player)
    print("Giving player points")

end

-- プレイヤーがパーツに触れたかどうかをチェックする
local function partTouched(otherPart)

end
  1. Playersサービスには、キャラクターモデルを渡すと、Playerオブジェクトを返してくれる便利な関数があります。それが、GetPlayerFromCharacter() です。この関数に与えた引数がキャラクターモデルだった場合、Player オブジェクトを返します。
-- プレイヤーがパーツに触れたかどうかをチェックする
local function partTouched(otherPart)
    -- 触れたパーツから、Player オブジェクトを取得
    local player = Players:GetPlayerFromCharacter(otherPart.Parent)

end
  1. プレイヤーがパーツに触れた場合、player変数にオブジェクトが格納されます。そうでない場合、変数は空のままになります。
-- プレイヤーがパーツに触れたかどうかをチェックする
local function partTouched(otherPart)
    -- 触れたパーツから、Player オブジェクトを取得
    local player = Players:GetPlayerFromCharacter(otherPart.Parent)
    if player then
        givePoints(player)
    end
end

pointPart.Touched:Connect(partTouched)
  1. テスト実行します。プレイヤーがパーツに触れるたびに、出力ウィンドウに「Giving player points」というメッセージが表示されます。

トラブルシューティング

ループするカラーの作成

随時、色を変化させるために while ループを使用します。パーツの色を数秒ごとに変更します。この while ループの条件は true にしているため無限に実行できます。

  1. スクリプトの最後に、条件が true である新しい while ループを作成します。これは、ループが常に実行されることを意味します。
-- プレイヤーがパーツに触れたかどうかをチェックする
local function partTouched(otherPart)
    -- 触れたパーツから、Player オブジェクトを取得
    local player = Players:GetPlayerFromCharacter(otherPart.Parent)
    if player then
        givePoints(player)
    end
end

pointPart.Touched:Connect(partTouched)

-- 色を変化させる無限ループ
while true do

end
while true do ループがスクリプトの最後にない場合、それより下のコードは実行されません。while ループは、停止しないため、do から end の間を実行し続けます。
  1. 予め作成しておいた変数を使い、パーツのColorプロパティに代入します。色を変えた後はtask.wait() 関数を使い数秒待ちます。これで、青、緑、赤の3色が無限に切り替わります。
-- 3色でループし、各色の間で待機する
while true do
    pointPart.Color = blue
    task.wait(3)
    pointPart.Color = green
    task.wait(2)
    pointPart.Color = red
    task.wait(1)
end
  1. テスト実行し、3 色すべてがループすることを確認します。

トラブルシューティング

この時点で、3色が切り替わらない場合は、次の項目を確認してください。

プレイヤーにポイントを与える

プレーヤーは、パーツに触れたときの現在の色に基づいてポイントが与えられます。

現在の色を見つける

触れたときの色によってプレイヤーに与えるポイントが決定されますので、現在の色を取得しておきます。

  1. givePoints() にある print 文を削除し、パーツ(pointPart)の現在の色を取得します。currentColor 変数は、プレイヤーが獲得する (または失う) ポイント数を決定します。
local function givePoints(player)
    local currentColor = pointPart.Color
end
  1. プレーヤーのポイントはリーダーボードに表示しますので、そのオブジェクトを取得します。リーダーボードにアクセスするには、player の 子供である leaderstats を取得すれば良いわけです。
local function givePoints(player)
    local currentColor = pointPart.Color

    local playerStats = player:WaitForChild("leaderstats")
end
  1. leaderstats の子供に Points という整数値を保存するオブジェクトを追加しましたね。このオブジェクトにポイントが入っていますので、これを playerPoints という変数に入れておきます。
local function givePoints(player)
    local currentColor = pointPart.Color

    local playerStats = player:WaitForChild("leaderstats")
    local playerPoints = playerStats:WaitForChild("Points")
end

ポイントの付与または減算

次に、if と elseif を使用して、触れた部分の色に応じてポイントを加算または減算します。青は少量、緑は多量のポイントを加算し、赤はポイントの減点になります。

  1. まず、青を判定しましょう。if 文を使用して現在の色が青かどうかを確認し、そうであれば、プレーヤーの現在のポイント値に smallPoints を加算します。
local function givePoints(player)
    local currentColor = pointPart.Color

    local playerStats = player:WaitForChild("leaderstats")
    local playerPoints= playerStats:WaitForChild("Points")

    if currentColor == blue then
        playerPoints.Value = playerPoints.Value + smallPoints
    end

end
  1. 次に、緑を確認します。緑は、else if 文を使用します。緑色の場合、プレーヤーの現在のポイント値に largePoints を加算します。
if currentColor == blue then
    playerPoints.Value = playerPoints.Value + smallPoints
elseif currentColor == green then
    playerPoints.Value = playerPoints.Value + largePoints
end
  1. pointsPart が青でも緑でもない場合は、赤のはずです。else 文を使用してポイントを減算します。
if currentColor == blue then
    playerPoints.Value = playerPoints.Value + smallPoints
elseif currentColor == green then
    playerPoints.Value = playerPoints.Value + largePoints
else
    playerPoints.Value = playerPoints.Value - losePoints
end
  1. 最後に、パーツを削除します。これを行わないと、何回もパーツに触れてしまいポイントがたくさん加算されたり、減算されてしまいます。最も簡単な方法はパーツを削除することです。Destroy() を使用してパーツを消去します。
if currentColor == blue then
    playerPoints.Value = playerPoints.Value + smallPoints
elseif currentColor == green then
    playerPoints.Value = playerPoints.Value + largePoints
else
    playerPoints.Value = playerPoints.Value - losePoints
end

pointPart:Destroy()
  1. テストプレイを行い、各色が期待通りのポイントになるのかを確認します。青、緑、赤の3 つの条件すべてをテストしてください。
https://prod.docsiteassets.roblox.com/assets/education/coding-3/colorPoint_showPointChange_web.mp4

プレイヤーへのフィードバック

PointPart は機能しますが、リーダーボードをたまたま見ない限り、プレイヤーは何が起こったのか気付かない可能性があります。PointPart が破棄されたときにパーティクル(粒子)を出現させ演出してみましょう。その他の演出効果としては、音を鳴らす、揺らすなど、何らかのエフェクトを加える等があります。それらを行うことでプレイヤーに満足感が与えられるでしょう。

https://prod.docsiteassets.roblox.com/assets/education/coding-3/colorPoint_showParticles_web.mp4

パーティクル エフェクトの作成

パーティクル(粒子)エフェクトは、触れたパーツと同じ色にします。

  1. GivePoints () の最下部で、ParticleEmitter オブジェクトを作成します。大文字小文字の区別がありますので確認してください。
    local particle = Instance.new("ParticleEmitter")
end
  1. ParticleEmitters の Color は、グラデーション等もサポートしているため、ColorSequence 型のデータしか入れることができません。そこで、現在の色(currentColor)を ColorSequence 型に変更しなくてはなりません。Color3型を作成できたように、ColorSequence 型も簡単に作成できます。ColorSequence.new(currentColor) とすればOKです。
pointPart:Destroy()

-- パーティクルの作成
local particle = Instance.new("ParticleEmitter")
particle.Color = ColorSequence.new(currentColor)
  1. パーティクルは、プレイヤーの頭の部分から出力したいと思います。プレイヤーモデルの中に、Headというパーツが入っていますので、それが頭になります。パーティクルの親をそれに設定すれば頭から出力されます。
local particle = Instance.new("ParticleEmitter")
particle.Color = ColorSequence.new(currentColor)

local playerCharacter = player.Character
particle.Parent = playerCharacter:WaitForChild("Head")
  1. 出力したパーティクルは1秒後に消したいので、task.wait(1) を実行してからそれを破棄します。
local particle = Instance.new("ParticleEmitter")
particle.Color = ColorSequence.new(currentColor)

local playerCharacter = player.Character
particle.Parent = playerCharacter:WaitForChild("Head")

task.wait(1)
particle:Destroy()
  1. ゲームをテストし、各色に触れた後、パーティクルがプレーヤーに短時間追従することを確認します。
https://prod.docsiteassets.roblox.com/assets/education/coding-3/colorPoint_showParticles_web.mp4

トラブルシューティング

この時点で、パーティクルが思ったように機能しない場合は、次のいずれかを試してください。

完成したプログラム

local pointPart = script.Parent

local blue = Color3.fromRGB(0, 0, 255)
local green = Color3.fromRGB(0, 255, 0)
local red = Color3.fromRGB(255 ,0, 0)

local smallPoints = 10
local largePoints = 50
local losePoints = 100

local Players = game:GetService("Players")

local function givePoints(player)
    local currentColor = pointPart.Color

    local playerStats = player:WaitForChild("leaderstats")
    local playerPoints = playerStats:WaitForChild("Points")

    -- パーツの色に応じたポイントを加減算
    if currentColor == blue then
        playerPoints.Value = playerPoints.Value + smallPoints
    elseif currentColor == green then
        playerPoints.Value = playerPoints.Value + largePoints
    else
        playerPoints.Value = playerPoints.Value - losePoints
    end

    -- パーツを破壊する
    pointPart:Destroy()

    -- パーティカルエフェクトを作成し、1秒後にそれを破壊する
    local playerCharacter = player.Character
    local particle = Instance.new("ParticleEmitter")
    particle.Color = ColorSequence.new(currentColor)
    particle.Parent = playerCharacter:WaitForChild("Head")
    task.wait(1)
    particle:Destroy()
end

local function partTouched(otherPart)
    local player = Players:GetPlayerFromCharacter(otherPart.Parent)

    if player then
        givePoints(player)
    end
end

pointPart.Touched:Connect(partTouched)

-- 3色でループし、各色の間で待機する
while true do
    pointPart.Color = blue
    task.wait(4)
    pointPart.Color = green
    task.wait(3)
    pointPart.Color = red
    task.wait(2)
end
モバイルバージョンを終了