Client input for a remote controlled drone being sticky

howdy howdy

basically the goal is to get a smooth mixable control scheme for a drone

previously i have used a while true do type loop to do this which spammed remote events causing lag, and i had no idea why, simplifying it to this fixes the lag however it now won’t allow mixing of controls and trying to do multiple inputs at a time can feel “sticky” or holding down a input will be registered then overwritten

any idea how to do something like this better preferably without a while true do loop?

(current none laggy code)


UserInputService.InputBegan:Connect(function(input, typing)
    if not typing then
        if input.KeyCode == Enum.KeyCode.W then
            DroneEvent:FireServer("forward")
        elseif input.KeyCode == Enum.KeyCode.S then
            DroneEvent:FireServer("backward")
        elseif input.KeyCode == Enum.KeyCode.D then
            DroneEvent:FireServer("right")
        elseif input.KeyCode == Enum.KeyCode.A then
            DroneEvent:FireServer("left")
        elseif input.KeyCode == Enum.KeyCode.G then
            DroneEvent:FireServer("flip")
        elseif input.KeyCode == Enum.KeyCode.Q then
            DroneEvent:FireServer("RFID_PING")
                end
            end
        end)
    end    
end)

link to the game if you are having trouble understanding the issue (just try moving around)

3 Likes

Here is an example of what you could try for a smooth mixable control system:


local activeInputs = {}

-- Function to update drone based on active inputs
local function updateDrone()
    if activeInputs[Enum.KeyCode.W] then
        -- move forward logic
    end
    if activeInputs[Enum.KeyCode.S] then
        -- move backward logic
    end
    -- Add similar checks for other inputs

    -- Example: Mix moving forward and right
    if activeInputs[Enum.KeyCode.W] and activeInputs[Enum.KeyCode.D] then
        -- move forward-right logic
    end

    -- Consider implementing a throttling mechanism to reduce the frequency of server calls
end

-- Detect when a key is pressed
UserInputService.InputBegan:Connect(function(input, typing)
    if not typing and input.UserInputType == Enum.UserInputType.Keyboard then
        activeInputs[input.KeyCode] = true
        updateDrone()
    end
end)

-- Detect when a key is released
UserInputService.InputEnded:Connect(function(input, typing)
    if not typing and input.UserInputType == Enum.UserInputType.Keyboard then
        activeInputs[input.KeyCode] = nil
        updateDrone()
    end
end)

-- Regularly update the drone (consider using RenderStepped for smooth updates)
game:GetService("RunService").RenderStepped:Connect(function()
    updateDrone()
end)

3 Likes

Rather than using a table, can’t you rather use attributes? Not sure which is faster, just saying this as I’ve made a simular thing using attributes rather than a table.

2 Likes

Yeah, you’re right. Using attributes works too, but I don’t think there is much of a performance change. Using attributes has more advantages and is more manageable.

3 Likes

I remember when I was a starter scripter and I would always use instances for so many things, never attributes. I missed out of a ton of performance from it, but at least I learn from my mistakes!

3 Likes

The problem has to do with how you handle the drone’s movement rather than the inputs from the client. The code on the client is ok, but could pass over more useful information such as the change in direction. In addition to listening for when an input has begun, you’ll want to account for when an input has ended.

2 Likes

If you want multiple inputs at a time you can add up the inputs togethet like the script below as a vector.

Specifically this part

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

local player = game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
local character = player.Character or player.CharacterAdded:Wait()

player.CharacterAdded:Connect(function(_character)
	character = _character
end)

local walkKeyBinds = {
	Forward = { Key = Enum.KeyCode.W, Direction = Enum.NormalId.Front },
	Backward = { Key = Enum.KeyCode.S, Direction = Enum.NormalId.Back },
	Left = { Key = Enum.KeyCode.A, Direction = Enum.NormalId.Left },
	Right = { Key = Enum.KeyCode.D, Direction = Enum.NormalId.Right }
}

local function getWalkDirectionCameraSpace()
	local walkDir = Vector3.new()

	for keyBindName, keyBind in pairs(walkKeyBinds) do
		if InputS:IsKeyDown(keyBind.Key) then
			walkDir += Vector3.FromNormalId( keyBind.Direction )
		end
	end

	if walkDir.Magnitude > 0 then --(0, 0, 0).Unit = NaN, do not want
		walkDir = walkDir.Unit --Normalize, because we (probably) changed an Axis so it's no longer a unit vector
	end
	
	return walkDir
end
2 Likes

Try to set the drones network ownership to the players client.

1 Like

thanks for the help everyone i got it working now

happy holidays
(:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.