Issue with player-input to laser-movement system

  1. What do you want to achieve? I’m currently working on a system in which whenever the player presses any of the WASD keys while in a seat (specifics not that important), their WASD movement is translated into the movement of two perpendicular lasers, one of the lasers moving when W or S is pressed, and the other moving when A or D is pressed. Whenever the player stops holding one of the keys I want the movement of the lasers to stop immediately. This movement is accomplished using tweening by the way.

  2. What is the issue? Whenever the player stops holding onto one of the WASD keys, rather than the movement immediately ceasing it continues for upwards of 10 minutes while maintaining roughly the same speed as it did whilst it was being pushed.

  3. What solutions have you tried so far? I’ve tried to make it so that when none of the keys are being pressed, the tweened movement stops, however that resulted in one of the lasers breaking completely and becoming unresponsive to movement. I may have implemented said solution incorrectly however I tried another method of doing so with no success.

Heres some code I’ve made thus far:

Serverscript designed to fire remotes that instruct the player clients to update the location of the lasers, used so that it feels more responsive

local CurrentXMovementVector = Vector3.new(0,0,0)
local CurrentZMovementVector = Vector3.new(0,0,0)
local X = 0
local Y = 0
local Z = 0


game["Run Service"].Heartbeat:Connect(function()
	if cooldownDebounce == false then
		cooldownDebounce = true
		if ControllerheldWASDkeys[1] == true then
			X = X + 0.01
		end
		if ControllerheldWASDkeys[2] == true then
			Z = Z - 0.01
		end
		if ControllerheldWASDkeys[3] == true then
			X = X - 0.01
		end
		if ControllerheldWASDkeys[4] == true then
			Z = Z + 0.01
		end
		CurrentZMovementVector = Vector3.new(0,0,Z)
		CurrentXMovementVector = Vector3.new(X,0,0)
		
		if CurrentXMovementVector.X ~= 0 then
			CurrentXMovementVector = Vector3.new(X,0,0)
			updateClientLaserPosition:FireAllClients(WandSLaser, CurrentXMovementVector, CurrentXMovementVector.X, 100)

		end
		if CurrentZMovementVector.Z ~= 0 then
			CurrentXMovementVector = Vector3.new(0,0,Z)
			updateClientLaserPosition:FireAllClients(AandDLaser, CurrentZMovementVector, CurrentZMovementVector.Z, 100)

		end
		if CurrentXMovementVector.X == 0 and CurrentZMovementVector.Z == 0 then
		end
		cooldownDebounce = false
	end
end)

LocalScript which is connected to the remote fired in the previous script and updates the laser’s position

local function updateLaserPosition(LaserToUpdate, MovementVector, DistanceToMove, SpeedInStudsPerSecond)
	
	if AandDLaserdebounce == false and LaserToUpdate == AandDLaser then
		AandDLaserdebounce = true

		if Players.LocalPlayer.Team ~= Teams.Controller then  -- controller being the person in the chair who already updated the position of the lasers on their end
			local updatedCframe = LaserToUpdate.CFrame + MovementVector 
			AandDTween = game.TweenService:Create(LaserToUpdate, TweenInfo.new((DistanceToMove/SpeedInStudsPerSecond),Enum.EasingStyle.Linear,Enum.EasingDirection.In,0,false,0), {CFrame = updatedCframe})
			AandDTween:Play()
			task.wait(DistanceToMove/SpeedInStudsPerSecond)
		end
		AandDLaserdebounce = false
	end

	if WandSLaserdebounce == false and LaserToUpdate == WandSLaser then
		WandSLaserdebounce = true
		if Players.LocalPlayer.Team ~= Teams.Controller then
			local updatedCframe = LaserToUpdate.CFrame + MovementVector
			WandSTween = game.TweenService:Create(LaserToUpdate, TweenInfo.new((DistanceToMove/SpeedInStudsPerSecond),Enum.EasingStyle.Linear,Enum.EasingDirection.In,0,false,0), {CFrame = updatedCframe})
			WandSTween:Play()
			task.wait(DistanceToMove/SpeedInStudsPerSecond)
		end
		WandSLaserdebounce = false
	end
end

Feel free to ask for more info.

I think the problem you are having is that in the server script you are firing off events every frame or possibly 40 times per second yet in your client script you are using task.wait which makes it so the client can’t keep up. How are you setting ControllerheldWASDkeys? I’d think you’d need to get your input from the client so are you getting input from the client, sending it to the server, and then firing movement back to the client or am I missing something?

Remove everything related to the tween feature, and see if that changes anything.

Yes, its data sent from one client to the server and then back to all clients, ControllerHeldWASDKeys is an array that starts off as {false,false,false,false}, with each index represending whether WAS or D is currently being held, in that order. Everytime the status of WAS or D changes for the particular client in control of the lasers, they fire a remote instructing the server to update the array at which particular key. You certainly understand whats going on. But how exactly would you go about delaying the firing of events? I was thinking a debounce and a wait for the serverscript but did you have any other ideas?

So have the laser teleport to its new CFrame instead? That resulted in it moving too fast.

Something you could try is like @Earthraphobic2 suggested, ditch the tween stuff. Spawn a loop on the clients that will lerp the lasers to their target position and have your loop lerp the lasers at the speed you want to their target. The event firing to all clients will simply update that target position for that particular laser.