For context, I’m coding a tower defense enemy system. They follow a set amount of points along the path only on the client. For the server, to reduce memory usage and ping, it is simply a folder with values. The primary values at hand here is the Speed value and the CFrame value. The speed value is used in a formula that is the same on the server and client to move it accordingly.
SERVER: It measures the time it will take from each point to the next (they are equally spaced apart) and it cuts it in half. Once it waits half of the time, it sets the CFrame value to the midpoint between the two parts, once it waits the other half it sets it to the destination. The half transparent part in the clip is the server side part.
CLIENT: It measures the time it will take from each point to the next and tweens the enemy object to the next point via CFrame on the root part. Everytime the CFrame value from the server changes, if it is too far away it will correct itself once it reaches the next checkpoint.
The issue: The time values are the exact same and I’ve tried multiple fixes. I’ve noticed that the Client object goes faster than the server object, both ending at different times.
CLIENT CODE:
local function setUpTweeningConnection()
repeat wait() until disconnectTweens == false
if connection then
connection:Disconnect()
end
if deathConnection then
deathConnection:Disconnect()
end
connection = cframe:GetPropertyChangedSignal("Value"):Connect(function()
local mag = (root.Position - (cframe.Value).Position).Magnitude
if mag >= maxDist.Value then
print(mag)
disconnectTweens = true
setUpTweeningConnection()
end
--root.CFrame = cframe.Value * CFrame.new(0,root.Size.Y * 1.5,0)
end)
deathConnection = game.Workspace.ServerEnemies.ChildRemoved:Connect(function(child)
if child == EnemyData then
if cleaned == false then
cleaned = true
disconnectTweens = true
enemy:Destroy()
connection:Disconnect()
deathConnection:Disconnect()
end
end
end)
for waypoint = currentNode.Value, #pathFolder:GetChildren() do
local mag = (pathFolder[waypoint].Position - pathFolder[waypoint - 1].Position).Magnitude
local TimeToWait = 4/speed.Value
print(TimeToWait)
ts:Create(root,TweenInfo.new(TimeToWait,Enum.EasingStyle.Linear),{CFrame = pathFolder[waypoint].CFrame * CFrame.new(0,root.Size.Y * 1.5,0) * offset}):Play()
wait(TimeToWait)
if waypoint == #pathFolder:GetChildren() then
cleaned = true
disconnectTweens = true
enemy:Destroy()
if connection then
connection:Disconnect()
end
if deathConnection then
deathConnection:Disconnect()
end
break
end
if disconnectTweens == true then
disconnectTweens = false
break
end
end
end
setUpTweeningConnection()
SERVER CODE:
for waypoint = 2, #pathFolder:GetChildren() do
if newEnemy and newEnemy:FindFirstChild("cframe") and newEnemy:FindFirstChild("Speed") and newEnemy:FindFirstChild("Health") and newEnemy:FindFirstChild("CurrentNode") then
local mag = (pathFolder[waypoint].Position - pathFolder[waypoint - 1].Position).Magnitude
local TimeToWait = 4/enemySpeed
print(TimeToWait)
print(TimeToWait/2)
if destroyed == true then break end
wait(TimeToWait/2)
newEnemy.cframe.Value = CFrame.new(pathFolder[waypoint - 1].Position,pathFolder[waypoint].Position)
if destroyed == true then break end
newEnemy.cframe.Value *= CFrame.new(0,0,-mag/2)
wait(TimeToWait/2)
if destroyed == true then break end
newEnemy.cframe.Value *= CFrame.new(0,0,-mag/2)
--[[local mid = getMid(pathFolder[waypoint].Position, pathFolder[waypoint - 1].Position)
newEnemy.cframe.Value = CFrame.new(getMid(pathFolder[waypoint - 1].Position, mid),pathFolder[waypoint].Position)
wait(TimeToWait/4)
if destroyed == true then break end
newEnemy.cframe.Value = CFrame.new(mid,pathFolder[waypoint].Position)
wait(TimeToWait/4)
if destroyed == true then break end
newEnemy.cframe.Value = CFrame.new(getMid(pathFolder[waypoint].Position, mid),pathFolder[waypoint].Position)
wait(TimeToWait/4)
if destroyed == true then break end
newEnemy.cframe.Value = pathFolder[waypoint].CFrame
wait(TimeToWait/4)--]]
if destroyed == true then break end
newEnemy.CurrentNode.Value = waypoint
end
--ts:Create(newEnemy.Position,TweenInfo.new(TimeToWait,Enum.EasingStyle.Linear),{Value = pathFolder[waypoint].Position}):Play()
end