Hello. I am trying to make a blinker script for a car using the a-chassis.
When I click 'E'it turns on the blinker but the light dosen't blink, it just stays on until I click 'E' again. It is the same problem for the 'Q' key.
It is a local script inside the plugins folder of the a-chassis.
LocalScript:
local UIS = game:GetService("UserInputService") local car = script.Parent.Car.Value local RRightBlinker = car.Body.blinkersright rightblinkeron = false local RLightBlinker = car.Body.blinkersleft leftblinkeron = false UIS.InputBegan:connect(function(input) if (input.KeyCode == Enum.KeyCode.E) then if (rightblinkeron == false) then rightblinkeron = true repeat RRightBlinker.Material = Enum.Material.Neon wait(.9) RRightBlinker.Material = Enum.Material.SmoothPlastic until rightblinkeron == false elseif (rightblinkeron == true) then rightblinkeron = false RRightBlinker.Material = Enum.Material.SmoothPlastic end end if (input.KeyCode == Enum.KeyCode.Q) then if (leftblinkeron == false) then leftblinkeron = true repeat RLightBlinker.Material = Enum.Material.Neon wait(.7) RLightBlinker.Material = Enum.Material.SmoothPlastic until leftblinkeron == false elseif (leftblinkeron == true) then leftblinkeron = false RLightBlinker.Material = Enum.Material.SmoothPlastic end end end)
This was really messy , I tried putting my own vars you can change them if you want. Lights will blink 10 times before going off with a cooldown of 1 second before they can be turned on again.
local UIS = game:GetService("UserInputService") local car = script.Parent:waitForChild("Car").Value local RRightBlinker = car.Body.blinkersright Rblinking = false local RLightBlinker = car.Body.blinkersleft Lblinking = false local cdR = false local cdL = false UIS.InputBegan:connect(function(input, GPE) if input.KeyCode == Enum.KeyCode.E and cdR == false then if Rblinking == false then cdR = true for i = 1,10 do wait(.5) RRightBlinker.Material = Enum.Material.Neon wait(.25) RRightBlinker.Material = Enum.Material.SmoothPlastic wait(.5) end wait(1) Rblinking = true cdR = false end end if input.KeyCode == Enum.KeyCode.E and cdR == false then if Rblinking == true then wait() cdR = true RRightBlinker.Material = Enum.Material.SmoothPlastic Rblinking = false wait(1) cdR = false end end if input.KeyCode == Enum.KeyCode.Q and cdL == false then if Lblinking == false then cdL = true for i = 1,10 do wait(.5) RLightBlinker.Material = Enum.Material.Neon wait(.25) RLightBlinker.Material = Enum.Material.SmoothPlastic wait(.5) end wait(1) Lblinking = true cdL = false end end if input.KeyCode == Enum.KeyCode.Q and cdL == false then if Lblinking == true then wait() cdL = true RLightBlinker.Material = Enum.Material.SmoothPlastic Lblinking = false wait(1) cdL = false end end end)
Thank you for reading! Goodluck while scripting !
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 --pause smooth neon --pause 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) -- blinker is the part to blink, blinkTime is the number of seconds to wait before blinking on/off local self = {} local on = false -- true if the blink loop is supposed to be running local calls = 0 -- number of calls to Stop that have occurred function self:Blink() -- start the blink loop if on then return end -- already blinking 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() -- stop the blink loop on = false calls = calls + 1 blinker.Material = Enum.Material.SmoothPlastic end function self:Toggle() -- toggle the blink loop on/off 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) -- TODO is the .7 supposed to be different than .9? --Note: you can now do things like right:Blink(), right:Stop(), and right:Toggle(). You cannot do right.on = true to change the "on" variable because it was declared "local". If you want to make a variable available outside of the class, you must use "self.var = 5" instead of "var = 5" in the class. In this case, however, you don't need to access those variables outside of the Blinker class - you are meant to only use the functions. 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)