Sending camera CFrame to other users for spectating system

surf - Roblox (spectating system i’m referencing. game id is 5315066937 if you don’t like links)

In the game I linked above, there’s a way to spectate users by saying “/spectate (username)”. While spectating someone else, it sends their camera’s CFrame to your client.

The only way I could think to have communication between other clients would be to use remote events to fire the CFrame from one user to the server and store that in a CFrame value, but this would require like 60 remote events to be fired a second (for 60 FPS) for each user in the game

Is there a more efficient way to do this, or do I have to fire a remote event 60 times a second for each user?

This is assuming the player being spectated is on 60 FPS, I could use RunService so that someone on 30 frames a second also displays 30 FPS for other users in the game

You could instead try to fire an event 15 times a second, and then use tweenservice to smoothen out the camera movement.

Event Firing:

while task.wait(1/15) do
Event:FireServer(Camera.CFrame)
end

Camera Positioning:

local TweenInf = TweenInfo.new(1/15, Enum.EasingStyle.Linear)

Event.OnClientEvent:Connect(function(ReqCFrame)
game:GetService("TweenService"):Create(Camera, TweenInf, {["CFrame"] = ReqCFrame}):Play()
end

I would like to add on here:
I havent used this for long periods of time, and this may cause a memory leak.
Im still not 100% sure if it will though.

That’s a good idea. Do you think lerping would be better, or would it not matter?

I do not understand lerping, but from what i know its pretty much the same as tweening.
Either one should work

Kk cool, I’ll give this a try some time today or tomorrow and update you after, letting you know if it works

Thank you for the idea

1 Like
game:GetService("RunService").RenderStepped:Connect(function()
	if CameraDelayActive then -- None of the code inside this event runs unless this variable is equal to true
		if Player:FindFirstChild("CameraCFrame") then -- updates Camera CFrame on server
			script.Parent:WaitForChild("CameraUpdater"):FireServer(cam.CFrame)
		end

		if TargetPlayer and TargetPlayer:IsA("Player") and TargetPlayer:FindFirstChild("CameraCFrame") then -- Updates camera CFrame while spectating someone else
			cam.CameraType = Enum.CameraType.Scriptable
			local TweenInf = TweenInfo.new(1/15, Enum.EasingStyle.Linear)
			local CameraTween = game:GetService("TweenService"):Create(cam, TweenInf, {["CFrame"] = TargetPlayer:FindFirstChild("CameraCFrame").Value})
			CameraTween:Play()
			CameraDelayActive = false
			CameraTween.Completed:Connect(function()
				CameraDelayActive = true -- when the tween completes, I want the RunService part of the script to run again
			end)
		end
	end
end)

Here is my current script, it’s a little laggy and I have no idea why. Without the tweening or any delay, it looks a tiny bit laggy but it’s hardly noticeable, so I don’t think it’s the remote event’s delay. Adding the tween made it look more laggy

Basically I have a variable (CameraDelayActive) which determines if the game can update the camera’s CFrame for either the server or the client, I left a few comments to hopefully help

I know it looks complicated, but it’s 1 if statement inside the event just to toggle on and off the code, and then there’s only 2 if statements which are actually important

To keep from getting lag, when you send the cframe position, don’t move the camera to the positon, but rather move the camera from its current position, ‘towards’ the destination
So if the camera reaches it a little before the client gets the next point, it wont stop and wait, it will keep moving and be corrected as it moves to the next point when that point arrives.

So this would be more of a lerp movement (not stopping at a point, but moving at a speed adjusted by time and distance) than one of tweening (smooth movement to a point)

To determine the speed of the cframe, you would check the last server time, with the current server time so you know how long it took for the camera to move from one cframe to another

https://create.roblox.com/docs/reference/engine/classes/Workspace#GetServerTimeNow