So, right now, I am currently making an obby game. Now one of the obstacles in the obby is a spinner that spins around. To make the spinner, I used the same tutorial on the devhub(hinge constraints) and it works fine when I test with 1 player. The problem is, once I get multiple players to start playing, the spinners lag and get out of sync as seen in the image below.
I have tried other solutions such as changing the orientation via script, but that wouldn’t move the players along with it. How would I make the spinner not lag but players can still ride on the spinner. I’m not asking for scripts, but if anybody could point me in the right direction I would appreciate it.
The problem with physics parts is that, to save resources, roblox has the nearest client calculate the physics for the individual parts. This means that players with slower connections can slow down the physics, which is why your spinner seem to be de synced.
Your fix may be as simple as setting the parts network ownership to the server, spinner:SetNetworkOwner(nil)
, so the spinners won’t be slowed down by poor connections. I think that network ownership is then given to a client that touches the spinner, so this may not work.
If this doesn’t work, and you want to move the parts via not physics-related methods (such as the orientation method you mentioned), you can use a script that will CFrame the player with the moving part.
I have personally used this exact (but slightly modified) script for a few things in my own games, and it works perfectly, and raycasting isn’t very expensive. I quickly checked and it works fine with parts being spun by changing it’s orientation.
This should be a LocalScript in StarterPlayer > StarterCharacterScripts
.
This is the exact code I used. I'm only putting this here because it maintains indentations, unlike the original code I linked
-- Original code by Kord_K, modified by MayorGnarwhal
--// Services
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
--// Variables
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local LastPlatformCFrame, Function, Function2
--// Move Player with tweening moving platforms
Function = RunService.Heartbeat:Connect(function()
local RootPart = Character.LowerTorso
local ray = Ray.new(RootPart.CFrame.p, Vector3.new(0, -50 ,0))
local hitPart = workspace:FindPartOnRayWithIgnoreList(ray, {Character})
if hitPart and CollectionService:HasTag(hitPart, "MovingPlatform") then -- this is where you detect the spinners. I prefer CollectionService over using .Name
local Platform = hitPart
if LastPlatformCFrame == nil then
LastPlatformCFrame = Platform.CFrame
end
local PlatformCF = Platform.CFrame
local Rel = PlatformCF * LastPlatformCFrame:inverse()
LastPlatformCFrame = Platform.CFrame
RootPart.CFrame = Rel * RootPart.CFrame
else
LastPlatformCFrame = nil
end
Function2 = Character.Humanoid.Died:Connect(function()
Function:Disconnect()
Function2:Disconnect()
end)
end)
Hello, thank you for your detailed response. Your answer has helped me a lot but I still have a question. If I have 10-20 spinners in a place lets say, would it be better to use BodyAngularVelocity or tweenservice. Currently, I am using tweenservice and changing part rotating using CFrame.Angles() on the client. Will there be a better way to do this? Also if I want to do it with physics, will there be another way?
It depends on your personal preference. BodyAngularVelocity would the simpler approach, but at the cost of some reliability due to finicky physics.
Personally, for reliability I would use the TweenService method and the CFrame script I linked above to give the illusion of physics.