Custom Car from scratch

Hello, I have a little problem, I am creating a custom car from scratch and I would like to know how can I avoid to “stop” the model when I remove or press another key.

Let’s imagine, you have W to move forward and you press A or D to turn right, well… that stops the model. And the same if we start with W+D and remove W for example, it stops.

local UserInputService = game:GetService("UserInputService")

local Car = script.Parent.Parent

local seat = Car:FindFirstChild("MainSeat")

local rotationSpeed = 1
local Moving = false
local waitTime = 0.05 

local pressedKeys = {}

local function registerKey(key)
	if not pressedKeys[key] then
		pressedKeys[key] = true
	end
end
local function removeKey(key)
	pressedKeys[key] = false
end

local function clearKeys()
	for key, v in pairs(pressedKeys) do
		pressedKeys[key] = nil
	end
end
local function action()
	if pressedKeys["W"] and pressedKeys["D"] then
		if Moving then return end 
		Moving = true
		while Moving == true do
			Car:PivotTo(Car:GetPivot() * CFrame.new(0,0,1) * CFrame.Angles(0,-math.rad(rotationSpeed),0))
			task.wait(0.01)
		end
		clearKeys()
	elseif pressedKeys["W"] and pressedKeys["A"] then
		if Moving then return end 
		Moving = true
		while Moving == true do
			Car:PivotTo(Car:GetPivot() * CFrame.new(0,0,1) * CFrame.Angles(0,math.rad(rotationSpeed),0))
			task.wait(0.01)
		end
		clearKeys()
	elseif pressedKeys["S"] and pressedKeys["D"] then
		if Moving then return end 
		Moving = true
		while Moving == true do
			Car:PivotTo(Car:GetPivot() * CFrame.new(0,0,-1) * CFrame.Angles(0,-math.rad(rotationSpeed),0))
			task.wait(0.01)
		end
		clearKeys()
	elseif pressedKeys["S"] and pressedKeys["A"] then
		if Moving then return end 
		Moving = true
		while Moving == true do
			Car:PivotTo(Car:GetPivot() * CFrame.new(0,0,-1) * CFrame.Angles(0,math.rad(rotationSpeed),0))
			task.wait(0.01)
		end
		clearKeys()
	elseif pressedKeys["W"] then
		if Moving then return end 
		Moving = true
		while Moving == true do
			Car:PivotTo(Car:GetPivot() * CFrame.new(0,0,1))
			task.wait(0.01)
		end
		clearKeys()
	elseif pressedKeys["S"] then
		if Moving then return end 
		Moving = true
		while Moving == true do
			Car:PivotTo(Car:GetPivot() * CFrame.new(0,0,-1))
			task.wait(0.01)
		end
		clearKeys()
	elseif pressedKeys["A"] then
		if Moving then return end 
		Moving = true
		while Moving == true do
			Car:PivotTo(Car:GetPivot() * CFrame.Angles(0,math.rad(rotationSpeed),0))
			task.wait(0.01)
		end
		clearKeys()
	elseif pressedKeys["D"] then
		if Moving then return end 
		Moving = true
		while Moving == true do
			Car:PivotTo(Car:GetPivot() * CFrame.Angles(0,-math.rad(rotationSpeed),0))
			task.wait(0.01)
		end
		clearKeys()
	end
end	


UserInputService.InputBegan:Connect(function(input, isTyping)
	if not isTyping and seat.Occupant then
		if input.KeyCode == Enum.KeyCode.W then
			registerKey("W")
		elseif input.KeyCode == Enum.KeyCode.S then
			registerKey("S")
		elseif input.KeyCode == Enum.KeyCode.A then
			registerKey("A")
		elseif input.KeyCode == Enum.KeyCode.D then
			registerKey("D")
		end
		task.wait(waitTime)
		action()
	end
end)

UserInputService.InputEnded:Connect(function(input, isTyping)
	if not isTyping then
		if not Moving then return end
		Moving = false
		if input.KeyCode == Enum.KeyCode.W then
			removeKey("W")
		elseif input.KeyCode == Enum.KeyCode.S then
			removeKey("S")
		elseif input.KeyCode == Enum.KeyCode.A then
			removeKey("A")
		elseif input.KeyCode == Enum.KeyCode.D then
			removeKey("D")
		end
		task.wait(waitTime)
		action()
	end
end)
2 Likes

Seems like what you are after would be to put a loop at the bottom that executes your action function and doesn’t alter the pressedKeys but lets the InputEnded do that. You’d also take the action call out of InputBegan and InputEnded.

2 Likes

Can you give more details please?

1 Like

if you would add a while true do task.wait(0.2) end to the action() function and later add the rest of the code
for example:

local function action()
 while true do
  -- action function code
  task.wait(0.2)
 end
end)

then it should keep checking for the keys (you can change the task.wait() to a smaller value so it detects more often

1 Like

It does not fix anything?

local UserInputService = game:GetService("UserInputService")

local Car = script.Parent.Parent

local seat = Car:FindFirstChild("MainSeat")

local rotationSpeed = 1
local Moving = false
local waitTime = 0.05 

local pressedKeys = {}

local function registerKey(key)
	if not pressedKeys[key] then
		pressedKeys[key] = true
	end
end
local function removeKey(key)
	pressedKeys[key] = false
end

local function clearKeys()
	for key, v in pairs(pressedKeys) do
		pressedKeys[key] = nil
	end
end

local function action()
	while true do 
		if pressedKeys["W"] and pressedKeys["D"] then
			if Moving then return end 
			Moving = true
			while Moving do
				Car:PivotTo(Car:GetPivot() * CFrame.new(0,0,1) * CFrame.Angles(0,-math.rad(rotationSpeed),0))
				task.wait(0.001)
			end
			clearKeys()
		elseif pressedKeys["W"] and pressedKeys["A"] then
			if Moving then return end 
			Moving = true
			while Moving do
				Car:PivotTo(Car:GetPivot() * CFrame.new(0,0,1) * CFrame.Angles(0,math.rad(rotationSpeed),0))
				task.wait(0.001)
			end
			clearKeys()
		elseif pressedKeys["S"] and pressedKeys["D"] then
			if Moving then return end 
			Moving = true
			while Moving do
				Car:PivotTo(Car:GetPivot() * CFrame.new(0,0,-1) * CFrame.Angles(0,-math.rad(rotationSpeed),0))
				task.wait(0.001)
			end
			clearKeys()
		elseif pressedKeys["S"] and pressedKeys["A"] then
			if Moving then return end 
			Moving = true
			while Moving do
				Car:PivotTo(Car:GetPivot() * CFrame.new(0,0,-1) * CFrame.Angles(0,math.rad(rotationSpeed),0))
				task.wait(0.001)
			end
			clearKeys()
		elseif pressedKeys["W"] then
			if Moving then return end 
			Moving = true
			while Moving do
				Car:PivotTo(Car:GetPivot() * CFrame.new(0,0,1))
				task.wait(0.001)
			end
			clearKeys()
		elseif pressedKeys["S"] then
			if Moving then return end 
			Moving = true
			while Moving do
				Car:PivotTo(Car:GetPivot() * CFrame.new(0,0,-1))
				task.wait(0.001)
			end
			clearKeys()
		elseif pressedKeys["D"] then
			if Moving then return end 
			Moving = true
			while Moving do
				Car:PivotTo(Car:GetPivot() * CFrame.Angles(0,-math.rad(rotationSpeed),0))
				task.wait(0.001)
			end
			clearKeys()
		elseif pressedKeys["A"] then
			if Moving then return end 
			Moving = true
			while Moving do
				Car:PivotTo(Car:GetPivot() * CFrame.Angles(0,math.rad(rotationSpeed),0))
				task.wait(0.001)
			end
			clearKeys()
		end
		task.wait(0.01)
	end
end	


UserInputService.InputBegan:Connect(function(input, isTyping)
	if not isTyping and seat.Occupant then
		if input.KeyCode == Enum.KeyCode.W then
			registerKey("W")
		elseif input.KeyCode == Enum.KeyCode.S then
			registerKey("S")
		elseif input.KeyCode == Enum.KeyCode.A then
			registerKey("A")
		elseif input.KeyCode == Enum.KeyCode.D then
			registerKey("D")
		end
		task.wait(waitTime)
		action()
	end
end)

UserInputService.InputEnded:Connect(function(input, isTyping)
	if not isTyping then
		if not Moving then return end
		Moving = false
		if input.KeyCode == Enum.KeyCode.W then
			removeKey("W")
		elseif input.KeyCode == Enum.KeyCode.S then
			removeKey("S")
		elseif input.KeyCode == Enum.KeyCode.A then
			removeKey("A")
		elseif input.KeyCode == Enum.KeyCode.D then
			removeKey("D")
		end
		task.wait(waitTime)
	end
end)

If you’re looking for something that slows the vehicle down and then stops it, you should use a variable to handle the speed of the object

local Increment = .2 -- How fast it moves
local maxSpeed = 10

task.spawn(function()
   while true do
     task.wait()
     if UIS:IsKeyDown(Enum.KeyCode.W) then
       Speed = math.clamp(Speed + Increment, 0, maxSpeed) -- Increases the speed and uses math.clamp to stop it from exceeding infinitely
   else
      Speed = math.clamp(Speed - Increment, 0, maxSpeed) -- Slowers the speed when W isn't pressed
   end
end)

So instead of using a fixed value to move the car in your code, replace it with a variable that decreases when W isn’t pressed. That should solve your problem.

1 Like

I don’t search it, I am just asking why my model is stopping when I remove one of key when I press W+D, W+A or with S.

1 Like

Your model stops moving when you leave the keys because once you leave the keys, you’re setting Moving = false, which means that there is no code running for moving the car in that direction, so it stops. You’re applying a certain speed as long as Moving = true and once Moving = false, the speed is 0 because no speed is applied.

1 Like

I should check if there is a key given in the dict and no with Moving ?

1 Like

I only provided an explanation of why your model is stopping abruptly.

That code should help you prevent it

1 Like