Better movement?

Hi there, I’ll keep it short and to the point. I’ve currently got the player set as model. With the PrimaryPart as torso with a humanoid. Currently the player controls the model by moving left and right:

MoveEvent.OnServerEvent:Connect(function(player,key)
	
	local bird = game.Workspace:WaitForChild(player.Name):WaitForChild("Torso").Parent
	
	if key == "D" then
		if bird.Torso.Position.X <= -394 then
			bird:SetPrimaryPartCFrame(CFrame.new(bird.PrimaryPart.Position + Vector3.new(.6,0,0)))
		end
		
	elseif key == "A" then

		if bird.Torso.Position.X >= -440 then
			bird:SetPrimaryPartCFrame(CFrame.new(bird.PrimaryPart.Position + Vector3.new(-.6,0,0)))
		end
	end
	
	
end)

They tell the server and the it then sets the object to move. (Only when the key is pressed down)

My question is would there be a smoother way of doing this? Reason being is because it looks chunky since they move .6 of a stud every time.

Thank you!

Do the movement on the client so lag doesn’t affect it.

2 Likes

Don’t move it on server, do it on client, in client it is much smoother.

1 Like

I’ve worked with client-controlled parts and understand how frustrating RemoteEvents can be.

As @Pokemoncraft5290 said, you should probably display the movement on the client.

However, that poses a security risk. Instead, you could do the movement on both the client and server.

The client will send input data to the server (like how it does already) BUT right after your remote event you will update the bird’s position on the client. You will still update the position on the server, but by updating it on the client you’re allowing the client to have seamless movement unhindered by latency.

The important thing to keep in mind is that you use the server to police the client’s movement. Never fully trust the client.


For extra smoothing, you should use CFrame:Lerp().

Lerp stands for linear interpolation, it basically calculates a point a % between two points. So you could do:

bird.PrimaryPart.CFrame = bird.PrimaryPart.CFrame:Lerp(CFrame.new(bird.PrimaryPart.Position + Vector3.new(.6,0,0)), .5)

Notice the .5; this is called the alpha and can be thought of as a percentage of distance. It’s 50% of the distance away from its original position.


You may also want to change how you fire remote events!

I can’t see your LocalScript, but as a warning:

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

local remoteEvent = ...

RS.Heartbeat:Connect(function()
	if UIS:IsKeyDown(Enum.KeyCode.A) then
		remoteEvent:FireServer("A")
	elseif UIS:IsKeyDown(Enum.KeyCode.D) then
		remoteEvent:FireServer("D")
	end
end)

Don’t do what I wrote above. Sending events to the server every heartbeat from every client will slow down the server. Heartbeat fires 60 times a second, with 5 players that would entail 300 events per second!

Instead, you will want to fire the event whenever the player presses and releases the key. Like in the following script:

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

local remoteEvent = ...

UIS.InputBegan:Connect(function(input, gp)
	if gp then return end
	if input.KeyCode == Enum.KeyCode.A then
		remoteEvent:FireServer(0, true)
	elseif input.KeyCode == Enum.KeyCode.D then
		remoteEvent:FireServer(1, true)
	end
end)

UIS.InputEnded:Connect(function(input, gp)
	if gp then return end
	if input.KeyCode == Enum.KeyCode.A then
		remoteEvent:FireServer(0, false)
	elseif input.KeyCode == Enum.KeyCode.D then
		remoteEvent:FireServer(1, false)
	end
end)

When the player presses down and holds the key we let the server continuously move to that direction using a .Heartbeat on the server. Once the key is released we’ll get another event that signals the server to stop moving the bird.

As you might have noticed, I have opted to send a number and a boolean (true or false) to the server.
Numbers are cheaper than strings: 0 = left (A); 1 = right (D)
The true/false is used to signal whether the key is held or not.

I hope this helps! :slight_smile:

3 Likes