Having trouble updating part position on server after tween is completed

Hey developers. I have been having trouble with an issue that seems really simple in my eyes. Might just be my lack of experience with tweening.

I am working on a tween-based tram system with multiple stops. I have the system set up so that the tween plays on the client and then updates the position on the server, using RemoteEvents.

The only problem is that the position updating isn’t working. Of course this causes many issues, such as the tram being out of sync for multiple players, leaving and joining, etc.

Server Code

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")

local Remote = ReplicatedStorage.Remotes.tram.sequence
local UpdateRemote = ReplicatedStorage.Remotes.tram.updatePosition
local Tram = game.Workspace.Tram
local TramRoot = Tram.TramRootPart
local TramWaypoints = game.Workspace.TramWaypoints

local distance

local TWEEN_TIME = 15

local TweenInformation = {

	Time = 10,
	Style = Enum.EasingStyle.Sine,
	Direction = Enum.EasingDirection.In,
	Repeat = 0,
	Reverse = false,
	Delay = 0
	
}

local Quadrant4Dictionary = {
	CFrame = TramRoot.CFrame * CFrame.new(TramRoot.Size.X + -(TramRoot.Position.X - TramWaypoints.TramQuadrant4.Position.X),0,0)
}

local ReturnMainDictionary = {
	CFrame = TramRoot.CFrame * CFrame.new(TramRoot.Size.X + (TramRoot.Position.X - TramWaypoints.TramMain.Position.X),0,0)
}

wait(5)
Remote:FireAllClients(TweenInformation,Quadrant4Dictionary,TramRoot)

UpdateRemote.OnServerEvent:Connect(function(player, object)
	TramRoot.Position = object.Position
end)

Client Code

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local Remote = ReplicatedStorage.Remotes.tram.sequence
local UpdateRemote = ReplicatedStorage.Remotes.tram.updatePosition


Remote.OnClientEvent:Connect(function(Info,Dictionary,Object)
	local Information = TweenInfo.new(Info.Time,Info.Style,Info.Direction,Info.Repeat,Info.Reverse,Info.Delay)
	local Tween = TweenService:Create(Object,Information,Dictionary)
	Tween:Play()
	Tween.Completed:Connect(function(Object)
		     UpdateRemote:FireServer(Object)
	end)
end)

Any help would be appreciated. Thank you!

1 Like

Are your remote events functioning correctly have you added a print to test?

Of course. I was thinking the issue might have something to do with the way my variables are set up

Since the changes were done on the client, it will not replicated to the server. Meaning that if the part had a position value of 0, 0, 0, and then the server sends the part to the client, and then on the client edits the position to lets say 0, 1, 0, the server will still think that it is 0, 0, 0.
What you would have to do is set it to an already existing variable on the server, in this case, it’s, Quadrant4Dictionary.

UpdateRemote.OnServerEvent:Connect(function(player, object)
	TramRoot.Position = Quadrant4Dictionary.CFrame
end)

This one is just a nitpick on your code:

local TweenInformation = {

	Time = 10,
	Style = Enum.EasingStyle.Sine,
	Direction = Enum.EasingDirection.In,
	Repeat = 0,
	Reverse = false,
	Delay = 0
	
}

You don’t have to do that, you can do:

local TweenInfo = TweenInfo.new(

	10,
	Enum.EasingStyle.Sine,
	Enum.EasingDirection.In,
	0,
	false,
	0
	
)

And corresponding to the client, the code would look much simpler. From this:

Remote.OnClientEvent:Connect(function(Info,Dictionary,Object)
	local Information = TweenInfo.new(Info.Time,Info.Style,Info.Direction,Info.Repeat,Info.Reverse,Info.Delay)
	local Tween = TweenService:Create(Object,Information,Dictionary)
	Tween:Play()
	Tween.Completed:Connect(function(Object)
		 UpdateRemote:FireServer(Object)
	end)
end)

To this:

Remote.OnClientEvent:Connect(function(Info,Dictionary,Object)
	local Tween = TweenService:Create(Object,Info,Dictionary)
	Tween:Play()
	Tween.Completed:Connect(function(Object)
		 UpdateRemote:FireServer(Object)
	end)
end)

This solution does fix your problem, however, the remote could be abused by exploiters as well as cause problems if laggy players’ tweens finish at different times.

That’s not the problem with my code. I just tried to solve it for them, not add extra things. But, sice you said that, I’ll try to do it.


@Leigh_ton
Instead of doing:

UpdateRemote.OnServerEvent:Connect(function(player, object)
	TramRoot.Position = object.Position
end)

Do:

wait(10) -- wait the amount of time needed to finish the tween
TramRoot.Position = object.Position

And then in the local script you can remove these lines:

Remote.OnClientEvent:Connect(function(Info,Dictionary,Object)
	local Information = TweenInfo.new(Info.Time,Info.Style,Info.Direction,Info.Repeat,Info.Reverse,Info.Delay)
	local Tween = TweenService:Create(Object,Information,Dictionary)
	Tween:Play()
	Tween.Completed:Connect(function(Object) -- This
		 UpdateRemote:FireServer(Object) -- This
	end) -- Me too!
end)