For more context I'm moving a plane (just one part for now) ahead every loop depending on your speed using Heartbeat service, and as far as I've read, Heartbeat should be as fast as your FPS but the movement is still jittery, whether or not you're attached to the plane (the player is attached with a weld, maybe not the best idea but the plane is still really snappy when nobody is in it), my FPS appears to be locked at 60, while the plane looks like its moving at 15-30 fps.
I started this project by making the plane so there is only 2 scripts rn
Server script in the plane object
--Roblox Services local RunService = game:GetService("RunService") --Script Variables local Taken = false local Camera = nil local Checked = false local Character = nil local Player = nil local VStep = 0 local speed = 1 local speedmin = 0.5 local speedregmax = 1 local speedmax = 5 local acceleration = 10 local deceleration = 20 local dirX = 0 local dirY = 0 local dirZ = 0 script.Parent.Touched:Connect(function(obj) print(obj) if obj.Parent:FindFirstChild("Humanoid") then --Is Human if Taken == false then Taken = true local Humanoid = obj.Parent.Humanoid Character = obj.Parent Player = game.Players:GetPlayerFromCharacter(Character) local Weld = Instance.new("Weld") Weld.Parent = Character.HumanoidRootPart Weld.Part0 = Weld.Parent Weld.Part1 = script.Parent Weld.C0 = Weld.C0 + Vector3.new(0,Humanoid.HipHeight + 0.2,0) Humanoid.PlatformStand = true Camera = Character.ClientPoll.CameraPoll:InvokeClient(Player) print(Camera) end end end) RunService.Stepped:Connect(function(time, step) print(speed) if speed < speedmin then speed = speedmin end if Taken == true then if math.floor(time * 10)%2==0 then if Checked == false then Checked = true Camera = Character.ClientPoll.CameraPoll:InvokeClient(Player) end else Checked = false end end --Most of this can be ignored as it is just calculating speed in a janky way, but there is a few important parts here if Camera ~= nil then print(Camera.lookVector.Y) if Camera.lookVector.Y < 0 then if speed + Camera.lookVector.Y < speedmax * -Camera.lookVector.Y then speed = speed - Camera.lookVector.Y / acceleration else speed = speed + Camera.lookVector.Y / (acceleration * 4) end else print("A") local decel = math.clamp((Camera.lookVector.Y / deceleration),0.01,10000) local cap = (speedmin / math.clamp(Camera.lookVector.Y,0.5,1)) if speed - decel < cap then speed = cap else speed = speed - decel end end local dirA = Vector3.new(dirX, dirY, dirZ):Lerp(Camera.lookVector,0.5) dirX, dirY, dirZ = dirA.X, dirA.Y, dirA.Z end --where the plane actually gets moved script.Parent.CFrame = script.Parent.CFrame:Lerp(script.Parent.CFrame + Vector3.new(dirX * speed, dirY * speed, dirZ * speed), 0.025 / step) end)
local script in character
local Camera = workspace.CurrentCamera script:WaitForChild("CameraPoll") script.CameraPoll.OnClientInvoke = function() return Camera.CFrame end
Use body gryo or whatever it is called please correct me. But basically.
local bodyGryo = script.workspace.BodyGyro local position = bodyGyro.Position --I think it is called position may be called something else if speed = >4 then position = mouse.cursor end)
Make sure the BodyGryo is in the model and not just in the plane model/union if this doesnt work reply