I am working on a birds-eye placement system for my game. This system will be able to place the player’s camera in the sky, and then reposition itself around the map. The issue with this is that the player will be able to (should be able to) move their camera far enough that the camera is outside the streaming radius of their character. To fix this, I have the game request streaming around the camera once every 10 seconds while the system is active.
The issue with this is that the range is really small, and there is no argument in the function to specify how big we want the radius to be. I could in theory request a grid around the camera to get maximum coverage, but I’m concerned that this may cause performance issues for both the client and server. Is there a better way to do this? I would like to avoid simply teleporting the character itself if possible, as this would cause massive problems for the anticheat.
Edit: We came to a conclusion on the best way to handle this, this is the code below if anyone else has this issue:
Server:
--Services
local rs = game:GetService("ReplicatedStorage")
--Remotes (you need to create and name these in replicatedStorage. Anywhere inside is fine.
--StreamRequest should be a remoteEvent, getPos should be a remoteFunction)
local StreamRequest = rs.ClientCustomStreamRequest
local getPos = rs.RequestStreamLocation
--References
local StreamObjects = Instance.new("Folder")
StreamObjects.Name = "StreamObjects"
StreamObjects.Parent = workspace
--Runtime
local ActiveStreamers = {}
--Connections
StreamRequest.OnServerEvent:Connect(function(plr, status)
if status then
--dont double activate
if ActiveStreamers[plr] then return end
--insert streamer
local focusPart = Instance.new("Part")
focusPart.Size = Vector3.new(0.0001,0.0001,0.0001)
focusPart.CanCollide = false
focusPart.CanQuery = false
focusPart.CanTouch = false
focusPart.Anchored = true
focusPart.Transparency = 1
focusPart.CollisionGroup = "NoColProjectile"
focusPart.Parent = StreamObjects
--apply focus
ActiveStreamers[plr] = focusPart
plr.ReplicationFocus = focusPart
--stream function
task.spawn(function()
while ActiveStreamers[plr] do
task.wait(2)
local pos = getPos:InvokeClient(plr)
if typeof(pos) ~= "Vector3" then return end
pos = pos * Vector3.new(1,0,1)
focusPart.Position = pos
print("updated stream")
end
end)
else
--remove streamer
if not ActiveStreamers[plr] then return end
ActiveStreamers[plr]:Destroy()
ActiveStreamers[plr] = nil
plr.ReplicationFocus = nil
end
end)
game.Players.PlayerRemoving:Connect(function(plr)
if ActiveStreamers[plr] then
ActiveStreamers[plr]:Destroy()
ActiveStreamers[plr] = nil
end
end)
Client:
--Remote (same one from before)
local RetrieveRequest = game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("RequestStreamLocation")
--References
local Camera = game.Workspace.CurrentCamera
--Connection
RetrieveRequest.OnClientInvoke = function()
return Camera.CFrame.Position
end
To toggle from the client, fire the ClientCustomStreamRequest remote with true or false, depending on if you want to turn it on or off