Create a Checkpoint System

Checkpoints for obbies that only require scripting one time.

by MooMooManager

Author Avatar

WARNING: I'm not good making optimized scripts, so don't attack me or anything if my code is inefficient.

This is a tutorial on how to make an easy-to-use checkpoint system that only requires that you change the name of a part when creating a new checkpoint. This requires a fair amount of setup to get it to work. Say goodbye to using team spawnlocations. You may want to read the entire thing. If you don't, you might miss something and it won't work. This tutorial assumes that you know about the game services, hierarchy and part properties.

The Checkpoint

Start off by creating a folder under Workspace. Name it "Checkpoints" (no quotations), it will contain your checkpoints. Create a part under your folder that will represent your checkpoint. Customize it how you want, but make sure it's anchored. Name the checkpoint "1" (no quotations). Next, create another part. This part needs a lot of modifying, so it will be listed in steps.

  1. Make the part Anchored = true, CanCollide = false, and Transparency = 1.
  2. Make the part 1x1x1 in size (or smaller). Name the part "SpawnPoint" (no quotations).
  3. Child the part under your checkpoint named 1. Place your new part 3 studs above the top face of the checkpoint. The new part is going to be your SpawnPoint for the checkpoint (more on it later). Your checkpoint and hierarchy should now look something like this:

img|65x45

Scripting

Under ServerScriptService, create a new script. Name does not matter. In the script, type (or copy) in this code:

local function PlayerJoined(NewPlayer)
    local LeaderStats = Instance.new("Folder")
    local Stage = Instance.new("IntValue")
    LeaderStats.Name = "LeaderStats"
    Stage.Name = "Stage"
    LeaderStats.Parent = NewPlayer
    Stage.Parent = LeaderStats
    Stage.Value = 1
end
game.Players.PlayerAdded:Connect(PlayerJoined)

This code should give your game a leaderboard with the statistic "Stage." Back to your checkpoint, create a new script under 1 (name of the script does not matter) and put in this code:

ParentValue = tonumber(script.Parent.Name)
local function Touched(OtherPart)
    local Humanoid = OtherPart.Parent:FindFirstChildWhichIsA("Humanoid")
    if Humanoid then
        local Player = game.Players:FindFirstChild(OtherPart.Parent.Name)
        if Player then
            local Stage = Player.LeaderStats.Stage.Value
            if Stage < ParentValue then
                Player.LeaderStats.Stage.Value = ParentValue
            end 
        end
    end
end
script.Parent.Touched:Connect(Touched)

This code checks if it should change the stage number of the player when it is touched. First, when the touch event is triggered, it checks if the toucher is a humanoid and that the toucher's name is in the player list. If it is, then it checks if the player's stage is lower than the checkpoint's stage and changes the player's stage to the checkpoint's stage if it is (sorry if that's confusing). Finally, before you can start, go back to your script in ServerScriptService and add in this code:

local function NewObject(Object)
    local Humanoid = Object:FindFirstChildWhichIsA("Humanoid")
    if Humanoid then
        local Player = game.Players:FindFirstChild(Object.Name)
        if Player then
            wait(0.5)
            local Stage = Player.LeaderStats.Stage.Value
            local StringConvert = tostring(Stage)
            local Checkpoint = game.Workspace.Checkpoints:FindFirstChild(StringConvert)
            Object.Torso.CFrame = CFrame.new(Checkpoint.SpawnPoint.Position)
        end
    end
end
game.Workspace.ChildAdded:Connect(NewObject)

This is the code that brings the player to their checkpoint upon respawning. A function activates when a new child is added to Workspace (a new model is created for your character upon respawning). The script checks if this new model is a player in the player list, and if it is, it finds the player's stage number. The stage number is used by the script to look for the checkpoint in Workspace with the matching number. When it finds it, it (waits half a second as it wouldn't work if it started too fast, then) sends the player to the SpawnPoint of the checkpoint (if it were to be sent to the checkpoint itself, the player would probably get stuck in the ground). CFrame must be used to change the position instead of Position because of random things that would probably take too long to explain (I don't actually know why).

Here is a recap of this entire system: A script detects when a child is added to Workspace. If the new child is a player, then it finds the player's stage value, then finds the checkpoint with the stage value and sends the player there. When a checkpoint is touched, it detects if the toucher is a player, and if it is, the script compares the checkpoint's value and the player's value. If the player's value is lower than the checkpoint's, it sets the player's value to the checkpoint value.

Creating New Checkpoints

To make a new checkpoint, select your checkpoint, duplicate it with Ctrl + D, move the new checkpoint somewhere else, then rename your new checkpoint to the stage number you want it to represent. It's that simple. Make sure you duplicate the checkpoint instead of copy and pasting, as all checkpoints have to be under the Checkpoints folder.

img|5x5

img|75x50

Hopefully you found this tutorial useful.