Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How to create a part that changes color when one walks on it?

Asked by 4 years ago

Hi. I'm just learning to code with Roblox Lua, and I am creating an obstacle course as my first small project. I have these checkpoints (parts with some scripts) that are red originally, but turn green when stepped on, and red again when the player gets off:

script.Parent.Touched:connect(function()
    script.Parent.BrickColor = BrickColor.new("Camo")
wait (2)
    script.Parent.BrickColor = BrickColor.new("Maroon")
end)

However, this is really buggy and often changes between the colors back and forth randomly. I would like to improve upon this by making it so it changes green, and stays green. I would also like it to only be visible for the player who did the action, not everyone else. I believe this has something to do with local scripts and variables, but I do not really understand them. Any insight, help, or solutions are greatly appreciated!

0
First, i would recommend you put a second wait(2) after the maroon thing IAmSoloz 14 — 4y

1 answer

Log in to vote
2
Answered by 4 years ago
Edited 4 years ago

Explanation

The Touched event usually requires a "debounce" - a variable used to prevent repetition of an event - since it will fire anytime it is touched even if a player has already been touching it. Below, I've named it "db" and essentially it prevents further calls to the event from running the remainder of the code unless the variable is a specific value.

Next, I performed some calculations to determine the region of the Part the player would have to be standing in to keep it "Camo". Although it is longer than a wait statement, it allows you to be sure the player is no longer on the part. The "delta" variable is to account for error so that if the player stood on the edges of the Part the condition to change to "Maroon" would not be met (making a glitch-like aesthetic).

After setting the BrickColor, I use a repeat loop with a wait(), where the loop will end when its condition is met (in this case if the player's HumanoidRootPart is outside of the bounds of the Part on the X or Z axis).

Finally, since the player is no longer touching the part, we set the Part color back to "Maroon" and reset "db" so the event can be run again.

Revised Local Script

local player = game:GetService("Players").LocalPlayer
local part = game:GetService("Workspace"):WaitForChild("Part")
local delta = 1.5
local db = false

part.Touched:Connect(function()
    if db == false then
        db = true

        local x1 = part.Position.X - (part.Size.X / 2) - delta
        local z1 = part.Position.Z - (part.Size.Z / 2) - delta
        local x2 = part.Position.X + (part.Size.X / 2) + delta
        local z2 = part.Position.Z + (part.Size.Z / 2) + delta

        local root = player.Character:WaitForChild("HumanoidRootPart")
        part.BrickColor = BrickColor.new("Camo")

        repeat
            wait(0.05)
        until (root.Position.X > x2 or root.Position.X < x1) or (root.Position.Z > z2 or root.Position.Z < z1)

        part.BrickColor = BrickColor.new("Maroon")
        db = false
    end
end)

Also you are right to use a LocalScript since any changes on the Client are only visible for that player, while changes on the Server are visible to all players.

Ad

Answer this question