Tip: Use print statements to see what's going on, like this (this is just part of your script):
if (input.KeyCode == Enum.KeyCode.E) then
if (rightblinkeron == false) then
rightblinkeron = true
print("e turning on")
repeat
print"about neon"
RRightBlinker.Material = Enum.Material.Neon
wait(.9)
print"aft wait, smooth"
RRightBlinker.Material = Enum.Material.SmoothPlastic
until rightblinkeron == false
print"loop done"
elseif (rightblinkeron == true) then
print"e turning off"
rightblinkeron = false
RRightBlinker.Material = Enum.Material.SmoothPlastic
end
end
The output was this (and where I put '--pause', I mean there was a pause before the output continued):
e turning on
neon
smooth
neon
smooth
neon
Clearly, it is turning the brick smooth, but it is immediately turning it back to neon! You forgot a wait command after setting the material to smooth.
Tip: You don't need ()s around an if statement. ex, you can just do if rightblinkeron == false then. Also, val == false is the same as not val (if you don't care about the difference between false and nil), and val == true is identical to val
Also, stylistically, variables should be capitalized with lowerCamelCase -- that is, every word except the first should be capitalized. Function names often use UpperCamelCase, where every word including the first is capitalized.
Problem: while the blinker is blinking but in the 'off' state (ie it's Smooth material but still in the repeat loop), if you tap 'e' twice very quickly, you will cause it to start blinking faster -- this is because you will create two coroutines that are both in the repeat loop (the first repeat never exited because when it checked to see if it should keep on blinking, the answer is "yes"). To fix this, you can keep track of the number of times the player has stopped the blinking light and then exit the loop early if they've pressed it more times than when the loop started.
So that you don't have to write the same code twice, I've turned it into a basic "class". Improved script:
local UIS = game:GetService("UserInputService")
local car = script.Parent.Car.Value
local function Blinker(blinker, blinkTime)
local self = {}
local on = false
local calls = 0
function self:Blink()
if on then return end
on = true
local startCalls = calls
repeat
blinker.Material = Enum.Material.Neon
wait(blinkTime)
if startCalls ~= calls then break end
blinker.Material = Enum.Material.SmoothPlastic
wait(blinkTime)
until not on or startCalls ~= calls
end
function self:Stop()
on = false
calls = calls + 1
blinker.Material = Enum.Material.SmoothPlastic
end
function self:Toggle()
if on then
self:Stop()
else
self:Blink()
end
end
return self
end
local right = Blinker(car.Body.blinkersright, .9)
local left = Blinker(car.Body.blinkersleft, .7)
UIS.InputBegan:connect(function(input)
if input.KeyCode == Enum.KeyCode.E then
right:Toggle()
elseif input.KeyCode == Enum.KeyCode.Q then
left:Toggle()
end
end)
2 comments
This is inferior to the OP's script (bugs aside), which allowed the user to turn on/off the lights at will. You should have an 'if' statement before each Material change to see if the user wants to turn off the blinking. Also, if the user press E, waits a second, then presses it twice more, I would expect the light to be on, but due to cdR, it will remain off (assuming you fix the 1st bug).
On the other hand, cdR is an improvement compared to the OP's script in the sense that it prevents multiple coroutines from going into each loop. (Note: I have not +1/-1ed your answer, just letting you know.)