3.アイテムを集める

リーダーボードが作成されたところで、プレイヤーは何か収集するものが必要です。そのためには、プレイヤーが世界で見つけることができる3Dアイテムを作成する必要があります。以下は、プレイヤーがアイテムを収穫する過程を撮影した動画です。

アイテムを作成する

ゲーム内のアイテムは、プレイヤーがツールを使用して収穫する 3D モデルになります。各アイテムは一度収穫すると消え、一定時間後に再び現れます。

アイテムについては、ゲーム デザインのドキュメントを参照してください。このシリーズでは例としてクリスタルを使用します。

  1. クリスタルは独自に作成しても構いませんが、ツールボックスからキーワード「crystal」でいくつかのクリスタルを見つけることもできます。
  1. 複数のパーツで作成した場合は、それらすべてを Model としてグループ化します。それらのパーツを選択し、右クリックして「Group As a Model/モデルとしてグループ化」 を実行してください。これにより、パーツで構成されたモデルが作成されます。
  1. パーツがすべて固定されていること(AnchoredがON)を確認してください。
  2. アイテムが消えている間は収穫できないようにしなくてはなりません。収穫の可否を覚えておくために BoolValue を使用します。作成したクリスタルのモデルの下に、CanHarvestという名前のBoolValueを作成します。
  1. CanHarvest のプロパティで、「Value」をオンに設定します。これをオンにするとブール値が true になり、プレイヤーがそのアイテムを収穫できるということを明示します。

ツールの作成

プレイヤーは、アイテムを集めるためにツルハシやシャベルのようなものが必要になります。Roblox では、プレイヤーが装備して使用できるアイテムはツールと呼ばれます。このレッスンでは、後でカスタマイズできるすべてのパーツとアニメーションが既に作成されたスターターツールを使用します。

ツールの追加

このシリーズにはスターターツールが用意されています。プレイヤーが使用するには、StarterPack 内に配置する必要があります。

  1. 以下のスターターツールをダウンロードしてください。
  1. エクスプローラの StarterPack を右クリックします。次に「Insert form File/ファイルから挿入」をクリックします。
  1. ダウンロードしたファイル(starterTool.rbxm)を選択します。
  1. プロジェクトをテストプレイします。StarterPack に入れたツールはゲーム開始時にバックパックに入ります。StarterTool というツールを装備してください。左クリックすると振りかざすと思います。
StarterTool の名前を変更する場合は、StarterPack 内のオブジェクトの名前を変更するだけです。その名称がそのまま表示されます。日本語も使用できます。

ツールのコーディング

ツールが収穫可能なオブジェクトに当たり、プレイヤーのバッグに十分なスペースがある場合、プレイヤーのアイテム数はリーダーボード上で1つ増えます。アイテムを収穫すると、そのアイテムは数秒間消え、数秒間収穫できなくなり、再び出現します。これにより、プレイヤーは同じアイテムをクリックするだけでなく、より多くのアイテムを見つけるために探索するようになります。

スクリプトの設定

このツールには、アニメーションを実行するスクリプト(Animations)は入っていますが、その他の処理は入っていません。収集可能なオブジェクトに触れるたびに何が起こるかを処理するプログラムを記述しなくてはなりません。

  1. StarterPack の StarterTool の下に、ToolScript という名前の新しい Script を追加します。
  1. スクリプトでは、先頭に説明的なコメントを記述してから、ツールパーツとツール自体を格納する変数を作成します。
-- 収穫できる部分に触れるとアイテムがゲットできる
local tool = script.Parent
local handle = tool.Handle

アイテムの確認

ツールがオブジェクトに触れるたびに、そのオブジェクトに CanHarvest が含まれているかどうか、ブール値が True に設定されているかどうかがチェックされます。

  1. onTouch()という名前の新しい関数を作成し、partTouchedというパラメータを指定します。
local tool = script.Parent
local handle = tool.Handle

local function onTouch(partTouched)

end
  1. その関数の中で、canHarvestという名前のローカル変数を作成します。そして、FindFirstChild()関数を使って、そのパーツの子供に CanHarvest という名前のオブジェクトがあるかどうかを確認します。
local function onTouch(partTouched)
    local canHarvest = partTouched:FindFirstChild("CanHarvest")
end
  1. 実際に何かが見つかったかどうかをチェックし、見つかった場合はコードを実行する必要があります。これを行うには、canHarvest を条件とする if 文を作成します。もし canHarvest に何か存在すれば、このステートメントは true になります。
local function onTouch(partTouched)
    local canHarvest = partTouched:FindFirstChild("CanHarvest")
    if canHarvest then

    end
end
  1. if 文の中に、スクリプトが動作しているかどうかを確認するための print 文を入れておきます。動作が確認できたら、アイテムを収穫するロジックをコーディングします。
if canHarvest then
    -- コードが動作するかどうかのテストに使用
    print("Found an item")
end
  1. 関数を end で閉じた後に、tool.Touched:Connect(onTouch) と入力します。これにより、ツールが何かに触れたタイミングで、onTouch() を呼び出すようになります。
local function onTouch(partTouched)
    local canHarvest = partTouched:FindFirstChild("CanHarvest")
    if canHarvest then
        print("Found an item")
    end
end

handle.Touched:Connect(onTouch)
  1. プロジェクトをテストプレイします。ツールを装備し、収穫可能なアイテムにツルハシが触れそうなところで左クリックします。アウトプットウィンドウに「Found an item」というメッセージが表示されることを確認します。

トラブルシューティング

メッセージが表示されない場合は、次のヒントを試してください。

  • カスタムパーツやメッシュを使用している場合、エラーが発生する可能性があります。このスクリプトは、CanHarvestオブジェクトが、ツールがタッチしているパーツの子である場合にのみ動作します。
  • ツールが Workspace ではなく、StarterPack の中にあることを確認してください。
  • パーツが固定されていることを確認します。

要素の取得

プレイヤーのアイテムを増やす前に、ツールはそのプレイヤーのリーダーボードにあるアイテム数の場所を見つけなければなりません。いったんツールがリーダーボードにアクセスできれば、そのプレイヤーのアイテム数を変更することができます。

  1. ツールからバックパックとプレーヤーを取得します。ツールの親はバックパックで、バックパックの親はプレイヤーになります。この辺りの関係は実際にテストプレイ見て、Players の中を覗いてみると理解できると思います。
local tool = script.Parent
local handle = tool.Handle

local backpack = tool.Parent
local player = backpack.Parent

local function onTouch(partTouched)
  1. 次の行で、 FindFirstChild() 関数を使用してプレーヤーの leaderstats を見つけます。
local backpack = tool.Parent
local player = backpack.Parent
local playerStats = player:FindFirstChild("leaderstats")

local function onTouch(partTouched)
  1. playerStatsの子供である Items と Spaces をそれぞれの変数に入れておきます。
local playerStats = player:FindFirstChild("leaderstats")
local playerItems = playerStats:FindFirstChild("Items")
local playerSpaces = playerStats:FindFirstChild("Spaces")
FindFirstChild()のパラメータの文字列は、PlayerSetup スクリプトの IntValue 名と同じである必要があります。項目の名前が異なる場合は、PlayerSetup スクリプトと同じであることを確認してください。

収集可能なオブジェクトの確認

ツールスクリプトに変数 playerItems と playerSpaces が作成されたので、プレイヤーにアイテムを与えることができます。作成した関数を使って、ツールに触れているオブジェクトが収穫可能かどうか、プレイヤーのバッグに十分なスペースがあるかどうかを確認し、リーダーボードに表示されるアイテムを1つ増やします。

  1. スクリプトには、2 つの条件を満たす if 文が必要です。and キーワードを使って、次の条件に満たす場合のみ実行するようにします。
    • canHarvest.Value == true
    • playerItems.Value < playerSpaces.Value
local function onTouch(partTouched)
    local canHarvest = partTouched.Parent:FindFirstChild("CanHarvest")
    if canHarvest then
        if canHarvest.Value == true and playerItems.Value < playerSpaces.Value then

        end
    end
end
IntValue や BoolValue などのValueオブジェクトの中身にアクセスするには、最後に.Valueと入力します。オブジェクトそのものにアクセスする場合は、そのオブジェクトの名前を取得するだけです。
  1. if 文内に「playerItems.Value = playerItems.Value + 1」と入力して、プレーヤーのアイテムに追加します。
if canHarvest then
    if canHarvest.Value == true and playerItems.Value < playerSpaces.Value then
        playerItems.Value = playerItems.Value + 1

    end
end
  1. テストプレイします。ツールを使用してアイテムを収穫し、アイテム数が増えたことを確認します。
現在は、アイテムを1つ収穫すると、Itamsが即満タンになります。次のセクションでは、プレイヤーが各アイテムから1つのアイテムしか得られないように、アイテムのリセットを行います。

アイテムのリセット

アイテムが収穫されると、2つの方法でリセットされます。

  • アイテムが消えて操作できなくします。
  • CanHarvest を false に設定します。

そして、しばらくすると元のアイテムに戻ります。この方法では、プレイヤーは1回の収穫で1つのアイテムしか得られず、元がリセットされる間、さらにアイテムを探し回る必要があります。

  1. アイテムが追加される場所で、canHarvest を false に設定します。プレイヤーがアイテムを収穫した時点でcanHarvest の値を false にすることで、1回のクリックで2つ以上のアイテムを与えることはできなくなります。
if canHarvest then
    if canHarvest.Value == true and playerItems.Value < playerSpaces.Value then
        playerItems.Value = playerItems.Value + 1
        canHarvest.Value = false
    end
end
  1. 値を false に設定した後、パーツの透明度を 1 (非表示) に設定し、CanCollide を false に設定します。これでパーツは消え、プレイヤーはパーツに触れることもできなくなります。
if canHarvest.Value == true and playerItems.Value < playerSpaces.Value then
    playerItems.Value = playerItems.Value + 1
    canHarvest.Value = false
    partTouched.Transparency = 1
    partTouched.CanCollide = false
end
  1. wait(5) と入力して、項目がリセットされるまでの時間を与えます。5 は推奨数であり、ご自分がちょうどいいと思う数字に設定してください。
if canHarvest.Value == true and playerItems.Value < playerSpaces.Value then
    playerItems.Value = playerItems.Value + 1
    canHarvest.Value = false
    partTouched.Transparency = 1
    partTouched.CanCollide = false
    wait(5)
end
  1. 待機後、前のコードと逆に、CanHarvest を true に設定し、Transparency と CanCollide を元の値に戻します。
    wait(5)
    canHarvest.Value = true
    partTouched.Transparency = 0
    partTouched.CanCollide = true
end
  1. テストプレイして動作確認します。
    • プレイヤーは、アイテムを収穫しても1個しか手に入りません。
    • アイテムが消え、5秒後に再表示されます。

トラブルシューティング

この時点で、正しく動作しなかった場合は以下のいずれかを確認してください。

  • TransparencyとCanCollideのスペルと大文字が正確であることを確認してください。
  • canHarvest = true ではなく、canHarvest.Value を使用していることを確認してください。

完成したToolScript

スクリプトの完成版は、以下の通りです。

local tool = script.Parent
local handle = tool.Handle

local backpack = tool.Parent
local player = backpack.Parent
local playerStats = player:FindFirstChild("leaderstats")
local playerItems = playerStats:FindFirstChild("Items")
local playerSpaces = playerStats:FindFirstChild("Spaces")

local function onTouch(partTouched)
    local canHarvest = partTouched:FindFirstChild("CanHarvest")
    if canHarvest then
        if canHarvest.Value == true and playerItems.Value < playerSpaces.Value then
            playerItems.Value = playerItems.Value + 1
            canHarvest.Value = false
            -- 収穫物したアイテムを非表示にし通り抜けられるようにする
            partTouched.Transparency = 1
            partTouched.CanCollide = false

            wait(5)
            -- 収穫したアイテムを再び出現させ、使用できるようにする
            canHarvest.Value = true
            partTouched.Transparency = 0
            partTouched.CanCollide = true
        end
    end
end

handle.Touched:Connect(onTouch)
2 thoughts on “3.アイテムを集める”
  1. ToolScriptの中の  canHarvest.Value == true and playerItems.Value < playerSpaces.Value then の所で
    08:51:05.687 Players.keita102938.Backpack.StarterTool.ToolScript:27: attempt to index nil with 'Value' – サーバー – ToolScript:27
    というエラーが出てしまうのですが自力では解決法がわかりませんでした。解決策を教えていただけたら幸いです。

    1. playerItems が nil、つまり空になっているというエラーです。
      変数の大文字小文字が間違っているなどが考えられますので、まずは上記のプログラムをコピペしてみてください。
      それでも動作しない場合は、プレイした状態で、Players の keita102938 の leaderstats の中に Gold、Items、Spaces が入っているかどうかを確認してください。入っていた場合、ゲーム構築のタイミングの問題も考えられますので以下のように、FindFirstChild を WaitForChild に変更してみてください。
      local playerStats = player:WaitForChild(“leaderstats”)
      local playerItems = playerStats:WaitForChild(“Items”)
      local playerSpaces = playerStats:WaitForChild(“Spaces”)

コメントを残す