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!
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.