How to end all KeyInputs to fix this problem (HELP!)

I am making a free camera mode spectate script for my game. I am dealing with an issue at the moment when the player dies, or the camera script toggles from the default camera to the flying camera and the player is holding down any of the movement keys (WASDEQ) the camera just goes in that direction when the key is lifted.

I’ve tried setting values for when the keys are pressed and when they aren’t but that hasn’t worked. I’ve tried finding a function to fire when the key isn’t pressed anymore in a “repeat wait() until” but that hasn’t worked. Any suggestions?

local Player = game.Players.LocalPlayer
repeat wait() until Player.Character
local Character = Player.Character

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local Humanoid = Character:WaitForChild("Humanoid")
local Toggle = script:WaitForChild("Toggle")

local Camera = workspace.CurrentCamera
local CameraPart = Instance.new("Part", workspace)
CameraPart.CFrame = CFrame.new(0, 40, 0)
CameraPart.Anchored = true
CameraPart.CanCollide = false
CameraPart.Transparency = 1

local Move = CFrame.new(0, 0, 0)

UserInputService.InputBegan:connect(function(Input)
	if Toggle.Value == false then return end
	if Input.KeyCode == Enum.KeyCode.A then
		Move = Move * CFrame.new(-1, 0, 0)
	elseif Input.KeyCode == Enum.KeyCode.D then
		Move = Move * CFrame.new(1, 0, 0)
	elseif Input.KeyCode == Enum.KeyCode.W then			
		Move = Move * CFrame.new(0, 0, -1)
	elseif Input.KeyCode == Enum.KeyCode.S then
		Move = Move * CFrame.new(0, 0, 1)
	elseif Input.KeyCode == Enum.KeyCode.E then
		Move = Move * CFrame.new(0, 1, 0)
	elseif Input.KeyCode == Enum.KeyCode.Q then
		Move = Move * CFrame.new(0, -1, 0)
	end
end)

UserInputService.InputEnded:connect(function(Input)
	if Toggle.Value == false then return end
	if Input.KeyCode == Enum.KeyCode.A then
		Move = Move * CFrame.new(1, 0, 0)
	elseif Input.KeyCode == Enum.KeyCode.D then
		Move = Move * CFrame.new(-1, 0, 0)
	elseif Input.KeyCode == Enum.KeyCode.W then
		Move = Move * CFrame.new(0, 0, 1)
	elseif Input.KeyCode == Enum.KeyCode.S then
		Move = Move * CFrame.new(0, 0, -1)
	elseif Input.KeyCode == Enum.KeyCode.E then
		Move = Move * CFrame.new(0, -1, 0)
	elseif Input.KeyCode == Enum.KeyCode.Q then
		Move = Move * CFrame.new(0, 1, 0)
	end
end)

RunService.RenderStepped:connect(function()
	if Toggle.Value == false then return end
	Camera.CameraSubject = CameraPart
	
	local Rotation = Camera.CFrame - Camera.CFrame.p
	CameraPart.CFrame = (Rotation + CameraPart.CFrame.p)
	CameraPart.CFrame = CameraPart.CFrame * Move
end)

Toggle.Changed:connect(function()
	if Toggle.Value == false then
		Move = Move * CFrame.new(0, 0, 0)
		Humanoid.WalkSpeed = 14	
		Camera.CameraSubject = Character.Humanoid
		Camera.CFrame = Character.Head.CFrame
	elseif Toggle.Value == true then
		CameraPart.CFrame = Character.Head.CFrame
		Move = Move * CFrame.new(0, 0, 0)
	end
end)

Here is a video of the problem:
robloxapp-20211127-0850310.wmv (2.9 MB)

Its being caused because when your toggle is off and you start a input the InputBegan event is ignored and when InputEnded is fired the move value is opposite of the normal input(so W is S and S is W).

You’ll likely need to add a value for when each button is pressed.
I believe you’ve tried this but you might not have done it correctly.

local Player = game.Players.LocalPlayer
repeat wait() until Player.Character
local Character = Player.Character

local keys_pressed = {
	[Enum.KeyCode.A] = false;
	[Enum.KeyCode.D] = false;
	[Enum.KeyCode.W] = false; -- Make a table for the keys
	[Enum.KeyCode.S] = false;
	[Enum.KeyCode.Q] = false;
	[Enum.KeyCode.E] = false;
}

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local Humanoid = Character:WaitForChild("Humanoid")
local Toggle = script:WaitForChild("Toggle")

local Camera = workspace.CurrentCamera
local CameraPart = Instance.new("Part", workspace)
CameraPart.CFrame = CFrame.new(0, 40, 0)
CameraPart.Anchored = true
CameraPart.CanCollide = false
CameraPart.Transparency = 1

local Move = CFrame.new(0, 0, 0)

UserInputService.InputBegan:connect(function(Input)
	if Toggle.Value == false then return end
	if Input.KeyCode == Enum.KeyCode.A then
		Move = Move * CFrame.new(-1, 0, 0)
	elseif Input.KeyCode == Enum.KeyCode.D then
		Move = Move * CFrame.new(1, 0, 0)
	elseif Input.KeyCode == Enum.KeyCode.W then			
		Move = Move * CFrame.new(0, 0, -1)
	elseif Input.KeyCode == Enum.KeyCode.S then
		Move = Move * CFrame.new(0, 0, 1)
	elseif Input.KeyCode == Enum.KeyCode.E then
		Move = Move * CFrame.new(0, 1, 0)
	elseif Input.KeyCode == Enum.KeyCode.Q then
		Move = Move * CFrame.new(0, -1, 0)
	end
	keys_pressed[Input.KeyCode] = true -- If any other key is pressed and added to the table it shouldn't matter since you don't use them
end)

UserInputService.InputEnded:connect(function(Input)
	if Toggle.Value == false then return end
	if keys_pressed[Input.KeyCode] == false then return end -- Just exit if the key being pressed hasn't been toggled by the above function
	if Input.KeyCode == Enum.KeyCode.A then
		Move = Move * CFrame.new(1, 0, 0)
	elseif Input.KeyCode == Enum.KeyCode.D then
		Move = Move * CFrame.new(-1, 0, 0)
	elseif Input.KeyCode == Enum.KeyCode.W then
		Move = Move * CFrame.new(0, 0, 1)
	elseif Input.KeyCode == Enum.KeyCode.S then
		Move = Move * CFrame.new(0, 0, -1)
	elseif Input.KeyCode == Enum.KeyCode.E then
		Move = Move * CFrame.new(0, -1, 0)
	elseif Input.KeyCode == Enum.KeyCode.Q then
		Move = Move * CFrame.new(0, 1, 0)
	end
    keys_pressed[Input.KeyCode] = false -- sorry forgot this part
end)

RunService.RenderStepped:connect(function()
	if Toggle.Value == false then return end
	Camera.CameraSubject = CameraPart

	local Rotation = Camera.CFrame - Camera.CFrame.p
	CameraPart.CFrame = (Rotation + CameraPart.CFrame.p)
	CameraPart.CFrame = CameraPart.CFrame * Move
end)

Toggle.Changed:connect(function()
	if Toggle.Value == false then
		Move = Move * CFrame.new(0, 0, 0)
		Humanoid.WalkSpeed = 14	
		Camera.CameraSubject = Character.Humanoid
		Camera.CFrame = Character.Head.CFrame
	elseif Toggle.Value == true then
		CameraPart.CFrame = Character.Head.CFrame
		Move = Move * CFrame.new(0, 0, 0)
	end
end)

Also

repeat wait() until Player.Character

Don’t do this use a event instead:

local Character = Player.Character or Player.CharacterAdded:Wait() -- :Wait() Will return the character when it gets added

Also don’t use :connect() use its capital instead :Connect() since the lowercase version is depriciated.

1 Like

Thank you man, I really appreciate it!