Roblox Studioでチェックポイントを作る方法|オブビーの復活地点を設定

Roblox Studioでオブビーを作ると、途中で落ちたプレイヤーが毎回スタート地点へ戻ってしまう問題が出てきます。

そこで必要になるのがチェックポイントです。
プレイヤーがチェックポイントへ触れた位置を記録し、ミスをした後は最後に通過した場所から再開できるようにします。

この記事では、次の機能を作ります。

  • 複数のチェックポイントをコースへ配置する
  • プレイヤーが触れたステージ番号を記録する
  • キャラクターが復活したときに最後の地点へ移動する
  • 同じチェックポイントへ何度触れても重複処理しない

今回はゲームを終了するまで記録が残る基本版です。
ゲームを閉じた後も進行状況を残す方法は、DataStoreの記事で解説します。

目次

完成する仕組み

チェックポイントを次の順番で通過するオブビーを想定します。

スタート
  ↓
Checkpoint1
  ↓
Checkpoint2
  ↓
Checkpoint3
  ↓
ゴール

例えばCheckpoint2へ触れた後に落下すると、復活後のキャラクターはCheckpoint2の少し上へ移動します。

チェックポイントを配置する

まず、Roblox StudioのExplorerで次の構成を作ります。

Workspace
  └─ Checkpoints(Folder)
  ├─ Checkpoint1(Part)
  ├─ Checkpoint2(Part)
  └─ Checkpoint3(Part)
ServerScriptService
  └─ CheckpointServer(Script)

WorkspaceへFolderを追加し、名前をCheckpointsにします。その中へチェックポイント用のPartを入れてください。

各Partでは次のプロパティを設定します。

プロパティ 設定理由
Name Checkpoint1 ステージ番号をコードで取得するため
Anchored true プレイ開始時に落下させないため
CanCollide true 足場として乗れるようにするため
CanTouch trueTouchedイベントを使うため
Color 好きな色通常の足場と区別するため

名前の末尾には必ず数字を付けます。CheckpointAのような名前ではステージ番号を取得できません。

ServerScriptServiceへコードを追加する

ServerScriptServiceへScriptを追加し、名前をCheckpointServerにします。最初から入っているコードを削除して、以下を貼り付けてください。

local Players = game:GetService("Players")

local checkpointsFolder = workspace:WaitForChild("Checkpoints")

local lastCheckpointByPlayer = {}

local function getStageNumber(checkpoint)

    return tonumber(checkpoint.Name:match("%d+$"))

end

local function getPlayerFromHit(hit)

    local character = hit:FindFirstAncestorOfClass("Model")

    if not character then

        return nil

    end

    local humanoid = character:FindFirstChildOfClass("Humanoid")

    if not humanoid then

        return nil

    end

    return Players:GetPlayerFromCharacter(character)

end

local function activateCheckpoint(checkpoint, hit)

    local player = getPlayerFromHit(hit)

    if not player then

        return

    end

    local stageNumber = getStageNumber(checkpoint)

    if not stageNumber then

        warn(checkpoint.Name .. " の末尾に数字がありません")

        return

    end

    local currentStage = player:GetAttribute("Stage") or 0

    if stageNumber <= currentStage then

        return

    end

    player:SetAttribute("Stage", stageNumber)

    lastCheckpointByPlayer[player] = checkpoint

    print(player.Name .. " がステージ " .. stageNumber .. " に到達")

end

local function connectCheckpoint(checkpoint)

    if not checkpoint:IsA("BasePart") then

        return

    end

    checkpoint.Touched:Connect(function(hit)

        activateCheckpoint(checkpoint, hit)

    end)

end

local function setupPlayer(player)

    player:SetAttribute("Stage", 0)

    player.CharacterAdded:Connect(function(character)

        local checkpoint = lastCheckpointByPlayer[player]

        if not checkpoint or not checkpoint.Parent then

            return

        end

        character:WaitForChild("HumanoidRootPart")

        task.wait()

        character:PivotTo(checkpoint.CFrame * CFrame.new(0, 4, 0))

    end)

end

for _, checkpoint in ipairs(checkpointsFolder:GetChildren()) do

    connectCheckpoint(checkpoint)

end

checkpointsFolder.ChildAdded:Connect(connectCheckpoint)

Players.PlayerAdded:Connect(setupPlayer)

for _, player in ipairs(Players:GetPlayers()) do

    setupPlayer(player)

end

Players.PlayerRemoving:Connect(function(player)

    lastCheckpointByPlayer[player] = nil

end)

コードの仕組み

チェックポイント番号を取得する

return tonumber(checkpoint.Name:match("%d+$"))

`%d+`は連続する数字、`$`は名前の末尾を表します。`Checkpoint12`なら`12`を取得します。

Partに触れたプレイヤーを特定する

Touchedイベントのhitには、足、腕、アクセサリなど、実際に触れたパーツが入ります。そのため`hit.Parent`だけを見るのではなく、上位のModelを探してHumanoidがあるか確認しています。

Attributeへステージ番号を入れる

player:SetAttribute("Stage", stageNumber)

Attributeを使うと、ExplorerのPlayerから現在のステージ番号を確認できます。将来UIへステージ数を表示するときにも利用できます。

復活後にキャラクターを移動する

character:PivotTo(checkpoint.CFrame * CFrame.new(0, 4, 0))

チェックポイントと同じ位置へ移動するとPartへ埋まる可能性があるため、Y方向へ4 studs上げています。

動作確認の手順

  1. Studio上部のPlayを押す
  2. Checkpoint1へ触れる
  3. ExplorerでPlayerのAttributeが`Stage = 1`になったか確認する
  4. キャラクターをリセットするか、コースから落下する
  5. Checkpoint1の上から再開できるか確認する
  6. Checkpoint2とCheckpoint3でも同じ手順を試す

Outputへ「プレイヤー名 がステージ 1 に到達」と表示されれば、通過判定は動いています。

チェックポイントが動かない原因

Folder名が違う

コードでは`workspace:WaitForChild(“Checkpoints”)`を探しています。Folder名が`Checkpoint`や`checkpoints`になっていないか確認してください。

Scriptを置く場所が違う

このコードはLocalScriptではなく、`ServerScriptService`内のScriptで動かします。

CanTouchがオフになっている

チェックポイントPartの`CanTouch`がfalseだと、`Touched`イベントが発生しません。

Part名の末尾に数字がない

`Checkpoint1`、`Checkpoint2`のように命名します。数字がない場合はOutputへ警告を表示します。

復活位置がPartへ埋まる

キャラクターの大きさに合わせて、`CFrame.new(0, 4, 0)`の`4`を`5`や`6`へ変更してください。

ゲームを閉じた後も保存するには

この記事の`lastCheckpointByPlayer`は、現在のサーバー内だけで使うデータです。プレイヤーがゲームを終了すると消えます。

進行状況を次回のプレイでも復元するには、`Stage`の数値をDataStoreへ保存します。最初は今回の基本版だけで動作を確認し、その後に保存機能を追加するとエラーを切り分けやすくなります。

まとめ

Robloxのチェックポイントは、次の3つを組み合わせて作れます。

  • Partの`Touched`で通過を検知する
  • PlayerのAttributeへステージ番号を記録する
  • `CharacterAdded`で最後のPartへキャラクターを移動する

これで、オブビーを途中から再開できるようになりました。
次はコース上にコインを置き、プレイヤーごとの獲得数を画面へ表示してみましょう。

関連記事

参考資料

Roblox Creator Hub: Spawn and respawn

Roblox Creator Hub: Player

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

現役のゲーム会社サーバーエンジニア。

HTML・CSS・JavaScript、PHP・MySQL、Robloxを使い、初心者でも実際に動かせるゲーム制作・プログラミング記事を執筆しています。

掲載コードは公開前に動作確認し、完成コードだけでなく「なぜ動くのか」「どこでつまずきやすいか」まで解説します。

Google Cloud Professional Cloud Architect取得。

コメント

コメントする

目次