Help with arrow script

I am trying to make an obby and I want to make a system where there’s an arrow over the next checkpoint you need to reach. I’m a builder and designer who is trying to learn Roblox LUA so I’m not very experienced. I searched through the forums for help and I wrote this line of code:

local Arrow = game.Workspace.Arrow

script.Parent.Touched:connect(function(touched)  
    local Character = touched.Parent
    if Character.Name = game.Players:GetPlayerFromCharacter(Character) then 
        Arrow.Position = ?
else
    return
    end
end)

So I need help with this code. I don’t know how to get the arrow to be over the next checkpoint you need to reach. I am using a folder in the Workspace called “Checkpoints” and I have not coded my datastore yet for the checkpoints.

Can someone help me finish this code where the Arrow.Position is over the next checkpoint you must reach? Could you give me an explanation as well? Thanks…

2 Likes

This can go in a Script in ServerScriptService

-- workspace is a default variable, you don't need to say game.Workspace
local Arrow = workspace.Arrow
local checkpoints = workspace.Checkpoints

for _, checkpoint in ipairs(checkpoints:GetChildren()) do
    -- The connect function is capitalized, not lowercase
    checkpoint.Touched:Connect(function(otherPart)
        local character = otherPart:FindFirstAncestorOfClass("Model")
        local humanoid = character:FindFirstChildOfClass("Humanoid")
        if humanoid then
            -- Vector3.new is basically an x, y, and z value.
            -- If you want the arrow to be higher, change the middle number.
            Arrow.Position = checkpoint.Position + Vector3.new(0, 10, 0)
        end
    end
end

Let me know if this gives any errors.

Whoops, I was putting the arrow over the checkpoint that got hit.
Are the checkpoints numbered? If they are, try this:

-- workspace is a default variable, you don't need to say game.Workspace
local Arrow = workspace.Arrow
local checkpoints = workspace.Checkpoints

for i, checkpoint in ipairs(checkpoints:GetChildren()) do
    -- The connect function is capitalized, not lowercase
    checkpoint.Touched:Connect(function(otherPart)
        local character = otherPart:FindFirstAncestorOfClass("Model")
        local humanoid = character:FindFirstChildOfClass("Humanoid")
        if humanoid then
            -- Vector3.new is basically an x, y, and z value.
            -- If you want the arrow to be higher, change the middle number.
            Arrow.Position = checkpoints[i + 1].Position + Vector3.new(0, 10, 0)
        end
    end
end

Best is if your checkpoints would be named something like Checkpoint{Index}, where Index stands the order of the checkpoint, so naturally Checkpoint0, Checkpoint1, Checkpoint2, ...
If player touches a checkpoint, select index from the checkpoint and then add 1 to it, so simply, if player touched Checkpoint2, you take the 2 from it and make it 3.
Clever solution would be adding an attribute to all your checkpoint with name Index and the number.
image

local index = script.Parent:GetAttribute("Index")
local nextCheckpoint = game.Workspace:FindFirstChild("Checkpoint" .. (index+1))
Arrow.Position = nextCheckpoint.Position + Vector3.new(0, 10, 0)

You can adjust the vector, 10 is the height distance from the actual checkpoint.

When you said ipairs was this a typo or not? If it’s not could you explain that to me? Or is it just a typo and it’s suppose to be in pairs?

Also I have the different checkpoints numbered 1, 2, 3, etc…

1 Like

pairs and ipairs are separate things. pairs is for dictionaries, and ipairs is for arrays (In this case, looping through a folder of checkpoints). More info here.

Since it’s a script in ServerScriptService, would just the client (the player) be able to see the arrow or would everyone in the game see the arrow?

Good catch, I didn’t think about that.
I think you can put the following code in a LocalScript in StarterCharacterScripts and it should work.

local Arrow = workspace.Arrow
local checkpoints = workspace.Checkpoints

for i, checkpoint in ipairs(checkpoints:GetChildren()) do

    checkpoint.Touched:Connect(function(otherPart)
        local character = otherPart:FindFirstAncestorOfClass("Model")
        if character == script.Parent then
            Arrow.Position = checkpoints[i + 1].Position + Vector3.new(0, 10, 0)
        end
    end
end

For some reason the code is not working but there’s no errors in the output.

Try running this and show me what prints in the output.

local Arrow = workspace.Arrow
local checkpoints = workspace.Checkpoints

for i, checkpoint in ipairs(checkpoints:GetChildren()) do
    print(checkpoint)
    print(checkpoints[i])
    checkpoint.Touched:Connect(function(otherPart)
        local character = otherPart:FindFirstAncestorOfClass("Model")
        print(otherPart)
        print(character)
        if character == script.Parent then
            local nextCheckpoint = checkpoints[i + 1]
            if nextCheckpoint then
                print("It should work if this prints")
                Arrow.Position = checkpoints[i + 1].Position + Vector3.new(0, 10, 0)
            else
                print(checkpoint, "is the last checkpoint")
            end
        else
            print("Part that touched checkpoint isn't player")
            print(character, script.Parent)
        end
    end
end

I got it to work, thank you :slight_smile: characters

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.