I have a script as follows:
local HEIGHT = 20 local ANGLE = -90 local ROTATION = -90 local player = game.Players.LocalPlayer; local runservice = game:GetService("RunService"); local function CameraUpdate() if game.ReplicatedStorage.TankSpawned:InvokeServer() then local character = player.Character; local camera = workspace.CurrentCamera; camera.CameraType = Enum.CameraType.Scriptable local Tank = game.ReplicatedStorage.GetClientTank:InvokeServer() game.Workspace.CurrentCamera.Focus = Tank.CFrame camera.CoordinateFrame = CFrame.new(Tank.Position) * CFrame.Angles(0, math.rad(ROTATION), 0) * CFrame.Angles(math.rad(ANGLE), 0, 0) * CFrame.new(0, 0, HEIGHT); end end runservice:BindToRenderStep("VertCamera", Enum.RenderPriority.Camera.Value, CameraUpdate);
This script works flawlessly in studio, though in-game it lags like crazy. It pretty much teleports the camera right to the player, every milisecond (not fast enough).
If I set the CameraSubject to "Tank", it works flawlessly in studio (again), but in game it doesn't have that nice straight-down camera. It is slightly off center, though it doesn't lag.
First off you need to start thinking of FireServer and InvokeServer as actual internet functions, similar to post buttons on websites. InvokeServer 120 times per second is probably the laggiest thing I can imagine.
Since InvokeServer yields, and RenderStep functions unsync as soon as they yield (render will not wait for you), nothing in that script is synced with cameras. I'm just trying to say find a way to InvokeServer outside of RenderStep!
Besides that, one line can prob be written better as
camera.CFrame = CFrame.new(Tank.Position+Vector3.new(0,0,HEIGHT)) * CFrame.Angles(math.rad(ANGLE), math.rad(ROTATION), 0)