Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

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

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!

1 comment

0

First, i would recommend you put a second wait(2) after the maroon thing

1 answer

✓ Accepted answer

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.

This discussion is preserved as it was. New answers, comments, and votes are closed.