So I’ve got this script below which updates the players CFrame while the model is moving but when other players see different players, they appear to be stuttering like this -
script-
while true do
local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local RunService = game:GetService('RunService')
local LastHit
local LastTrainCFrame
local Function
local Function2
local Whitelist = {workspace:WaitForChild('Map1', 20)}
Function = RunService.Heartbeat:Connect(function()
local RootPart = player.Character.HumanoidRootPart
local Ignore = player.Character
local ray = Ray.new(RootPart.CFrame.p, Vector3.new(0,-200,0))
local Hit, Position, Normal, Material
if LastHit then
Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,{LastHit})
if not Hit then
Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,Whitelist)
end
else
Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,Whitelist)
end
if Hit then
local Train = Hit
if not LastTrainCFrame then
LastTrainCFrame = Train.CFrame
end
local TrainCF
if Train ~= LastHit and LastHit then
TrainCF = LastHit.CFrame
else
TrainCF = Train.CFrame
end
local Rel = TrainCF * LastTrainCFrame:inverse()
LastTrainCFrame = Train.CFrame
RootPart.CFrame = Rel * RootPart.CFrame
LastHit = Train
if Train ~= LastHit then
LastTrainCFrame = Train.CFrame
end
else
LastTrainCFrame = nil
end
if not Function2 then
Function2 = player.Character.Humanoid.Died:Connect(function()
Function:Disconnect()
Function2:Disconnect()
end)
end
end)
wait(140)
end
Video is a wmv file, nobody can see it and nobody is gonna download it. Try making it .mp4 or another acceptable file type if you wanna get more people to help.
Well when the player sees themselves when they see their own character, it’s not stuttering. When that player is looking at a different player on their screen, they stutter, as you can see in the video.
Run the code on the server (normal script, not localscript), but instead of getting the player from LocalPlayer, try getting it from running an ipairs loop over the table returned Players:GetPlayers() to do it for every player server-side instead of on each individual client. It should still work from what I can tell, but you might have to change some things.
well I’ve tried so far but I’m getting multiple errors
while true do
local Players = game:GetService("Players")
local RunService = game:GetService('RunService')
local LastHit
local LastTrainCFrame
local Function
local Function2
local Whitelist = {workspace:WaitForChild('Map1', 20)}
wait(2)
for _,v in ipairs(game.Players:GetPlayers()) do
Function = RunService.Heartbeat:Connect(function()
local RootPart = game.Players.Character.HumanoidRootPart - **This line errors with Character is not a valid member of Players "Players"**
local Ignore = game.Players.Character
local ray = Ray.new(RootPart.CFrame.p, Vector3.new(0,-200,0)) - **This line also tends to error with CFrame is not a valid member of p.**
local Hit, Position, Normal, Material
if LastHit then
Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,{LastHit})
if not Hit then
Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,Whitelist)
end
else
Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,Whitelist)
end
if Hit then
local Train = Hit
if not LastTrainCFrame then
LastTrainCFrame = Train.CFrame
end
local TrainCF
if Train ~= LastHit and LastHit then
TrainCF = LastHit.CFrame
else
TrainCF = Train.CFrame
end
local Rel = TrainCF * LastTrainCFrame:inverse()
LastTrainCFrame = Train.CFrame
RootPart.CFrame = Rel * RootPart.CFrame
LastHit = Train
if Train ~= LastHit then
LastTrainCFrame = Train.CFrame
end
else
LastTrainCFrame = nil
end
if not Function2 then
Function2 = game.Players.Character.Humanoid.Died:Connect(function()
Function:Disconnect()
Function2:Disconnect()
end)
end
end)
wait(140)
end
end
Instead of using ‘game.Players.Character’ etc., use v.Character, as v is the player in the loop. If you get any more errors after that, screenshot/copy them into here.
right I’ve made the changes but now the whole map stutters and the player can’t move around on the model. I’m not getting any errors though in console. Video of that -
New code -
while true do
local Players = game:GetService("Players")
local RunService = game:GetService('RunService')
local LastHit
local LastTrainCFrame
local Function
local Function2
local Whitelist = {workspace:WaitForChild('Map1', 20)}
wait(2)
for _,v in ipairs(game.Players:GetPlayers()) do
Function = RunService.Heartbeat:Connect(function()
local RootPart = v.Character.HumanoidRootPart
local ignore = v.Character
local ray = Ray.new(RootPart.CFrame.p, Vector3.new(0,-200,0))
local Hit, Position, Normal, Material
if LastHit then
Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,{LastHit})
if not Hit then
Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,Whitelist)
end
else
Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,Whitelist)
end
if Hit then
local Train = Hit
if not LastTrainCFrame then
LastTrainCFrame = Train.CFrame
end
local TrainCF
if Train ~= LastHit and LastHit then
TrainCF = LastHit.CFrame
else
TrainCF = Train.CFrame
end
local Rel = TrainCF * LastTrainCFrame:inverse()
LastTrainCFrame = Train.CFrame
RootPart.CFrame = Rel * RootPart.CFrame
LastHit = Train
if Train ~= LastHit then
LastTrainCFrame = Train.CFrame
end
else
LastTrainCFrame = nil
end
if not Function2 then
Function2 = v.Character.Humanoid.Died:Connect(function()
Function:Disconnect()
Function2:Disconnect()
end)
end
end)
wait(140)
end
end
Are you trying to move a character with an object? Because instead of using CFrame to move both just use a BodyPosition to do that. Also I believe the stutter is just how roblox work and there is no real easy way to fix it.
yeah i am trying to move the player with the model. It worked fine as a local script, but only if that player was only watching themselves. If they saw another player, they would be stuttering.
Is there any reason to wrap the whole file in a while loop. You are creating connections every 140 seconds which do the same thing which may be a reason why it stutters?
Another thing I noticed was that your math for calculating the offset is wrong.
You are currently doing …
CurrentCFrame * lastCFrame:inverse()
This is wrong, we can prove it by deriving it the correct way
Well i thought i needed to do that so that when a new map would spawn in from server storage, this script would be already running for the players when they teleport to the new map, so that they can move with the model. That’s why I’ve got 140 second wait because that’s the length of time per round.
Well those connections are never being cleaned up. IE you have created a memory leak as the only reference to that connection exists inside the scope of the while loop during its current iteration. After the while loop goes to its next iteration, you will lose reference to the connection you have made which you have stored inside the local variable Function.
Could it even be more efficient to just put a BodyVelocity on the characters that matches the train’s velocity? (Especially if the train itself uses one)