StreamingEnabled ruins my spectate script but I need it for the game I’m making so it won’t be laggy. So is there any way to make the script work while StreamingEnabled is on?
ClientScript:
local toggle = script.Parent.DeathFrame.SpectateButton
local frame = script.Parent.Bar
local previous = frame.Previous
local nextbutton = frame.Next
local status = frame.Title
local camera = game.Workspace.CurrentCamera
local num = 1
local players = game:GetService("Players")
local plr = players.LocalPlayer
local char = plr.Character
local hum = char:WaitForChild("Humanoid")
local function SetCam(n)
local p = workspace.AlivePlayers:GetChildren()[n]
status.Text = p.Name
workspace.CurrentCamera.CameraSubject = p.Value.Character.Humanoid
end
local function unlockMouse()
local thing = Instance.new("TextButton")
thing.Parent = script.Parent
thing.Modal = true
thing.Size = UDim2.new(0,0,0,0)
thing.Name = "Unlocker"
thing.Text = ""
end
hum.Died:connect(function()
print("died")
script.Parent.Enabled = true
unlockMouse()
end)
status.Text = game.Players.LocalPlayer.Name
toggle.MouseButton1Click:Connect(function()
frame.Visible = not frame.Visible
script.Parent.DeathFrame.Visible = false
end)
previous.MouseButton1Click:Connect(function()
if num > 1 then
num = num - 1
else
num = #workspace.AlivePlayers:GetChildren()
end
SetCam(num)
end)
nextbutton.MouseButton1Click:Connect(function()
if num < #workspace.AlivePlayers:GetChildren() then
num = num + 1
else
num = 1
end
SetCam(num)
end)
With StreamingEnabled, you need to explicitly request certain parts of the game to load, particularly the character models and their components.
local toggle = script.Parent.DeathFrame.SpectateButton
local frame = script.Parent.Bar
local previous = frame.Previous
local nextbutton = frame.Next
local status = frame.Title
local camera = game.Workspace.CurrentCamera
local num = 1
local players = game:GetService("Players")
local plr = players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local function SetCam(n)
local alivePlayers = workspace:WaitForChild("AlivePlayers"):GetChildren()
if #alivePlayers > 0 then
local p = alivePlayers[n]
status.Text = p.Name
local character = p:WaitForChild("Character", 10)
if character then
-- Request to stream around the target player
p:RequestStreamAroundAsync()
-- Wait for the character and humanoid to be fully loaded
character:WaitForChild("Humanoid", 10)
-- Set the camera subject to the target player's humanoid
workspace.CurrentCamera.CameraSubject = character.Humanoid
else
warn("Character not found for player " .. p.Name)
end
else
warn("No alive players found")
end
end
local function unlockMouse()
local thing = Instance.new("TextButton")
thing.Parent = script.Parent
thing.Modal = true
thing.Size = UDim2.new(0,0,0,0)
thing.Name = "Unlocker"
thing.Text = ""
end
hum.Died:Connect(function()
print("died")
script.Parent.Enabled = true
unlockMouse()
end)
status.Text = game.Players.LocalPlayer.Name
toggle.MouseButton1Click:Connect(function()
frame.Visible = not frame.Visible
script.Parent.DeathFrame.Visible = false
end)
previous.MouseButton1Click:Connect(function()
local alivePlayers = workspace:WaitForChild("AlivePlayers"):GetChildren()
if #alivePlayers > 0 then
if num > 1 then
num = num - 1
else
num = #alivePlayers
end
SetCam(num)
else
warn("No alive players to spectate")
end
end)
nextbutton.MouseButton1Click:Connect(function()
local alivePlayers = workspace:WaitForChild("AlivePlayers"):GetChildren()
if #alivePlayers > 0 then
if num < #alivePlayers then
num = num + 1
else
num = 1
end
SetCam(num)
else
warn("No alive players to spectate")
end
end)
That is not true 100% of the time. Streaming is dynamic and it happens automatically. One of the exceptions for this would be if you used the Player:RequestStreamAroundAsync() method with a specific Vector3, which can be called manually to try to stream in a specific area of the game (although this is not necessary for streaming to function at all times).
*Important to note that :RequestStreamAroundAsync() doesn’t work unless you specify a Vector3.
You can set the ModelStreamingMode to Persistent for each player’s Character model when it spawns in. This will ensure that from the perspective of each player, all other Character models will always be streamed in / visible in the Workspace, no matter how far away they are.
As a result, when the spectating system tries to update the CameraSubject to another player’s Character, it’ll be able to do so, and then it’ll stream in the area around them if it wasn’t loaded already.
In order to do this, listen for the CharacterAdded event to fire for each player in a singular server-sided script:
Example
-- Code for a Server Script in the ServerScriptService
local Players = game:GetService("Players")
local function onPlayerJoin(player)
if player.Character then
player.Character.ModelStreamingMode = Enum.ModelStreamingMode.Persistent
end
player.CharacterAdded:Connect(function(Character)
Character.ModelStreamingMode = Enum.ModelStreamingMode.Persistent
end)
end
for _, player in Players:GetPlayers() do
task.spawn(onPlayerJoin, player)
end
Players.PlayerAdded:Connect(onPlayerJoin)
(Optional LocalScript change)
In addition to this, the spectating system code in the LocalScript could be slightly modified to make use of Player:RequestStreamAroundAsync(), so that when the camera is about to go to the next player’s Character, the game can begin to stream in that area of the map so it takes less time for the map to appear from the perspective of the spectating player:
-- Optional changes to the "SetCam" function in the LocalScript from original post
local function SetCam(n)
local alivePlayers = workspace.AlivePlayers:GetChildren()
local otherPlayer = alivePlayers[n]
if not otherPlayer then return end
local otherCharacter = otherPlayer.Character or otherPlayer.CharacterAdded:Wait()
local otherHumanoid = otherCharacter:FindFirstChildOfClass("Humanoid")
if otherHumanoid then
status.Text = otherPlayer.Name
local newCFrame = otherCharacter:GetPivot()
local newPosition = newCFrame.Position
plr:RequestStreamAroundAsync(newPosition)
workspace.CurrentCamera.CameraSubject = otherHumanoid
end
end
Hello, I had the first ever support topic covering this issue, the easiest solution is what bigeman suggested,
you can just add a script on starterplayer → startercharacterscripts like so:
local character = script.Parent
character.ModelStreamingMode = Enum.ModelStreamingMode.Persistent
--[[
this solution is enough for it to work again,
but consider upgrading it by using a remote
to set the .ReplicationFocus to the target,
as well as :RequestStreamAroundAsync()
]]
alternatively, you can use PersistentPerPlayer for a more customizable solution (control which specific players have that model streamed in, instead of having everyone streaming in everyone)
I now have a different spectate system script but still how can I do it with streaming enabled?
local toggle = script.Parent.DeathScreen.Spectate
local frame = script.Parent.SpectateFrame
local previous = frame.Prev
local next = frame.Next
local status = frame.Status.CurrentPlayer
local camera = game.Workspace.CurrentCamera
local num = 1
status.Text = game.Players.LocalPlayer.Name
toggle.MouseButton1Click:Connect(function()
frame.Visible = not frame.Visible
script.Parent.DeathScreen.Visible = false
end)
previous.MouseButton1Click:Connect(function()
local players = game.Players:GetChildren()
local max = #players
num = num - 1
if num < 1 then
num = max
end
local player = players[num]
camera.CameraSubject = player.Character.Humanoid
status.Text = player.Name
end)
next.MouseButton1Click:Connect(function()
local players = game.Players:GetChildren()
local max = #players
num = num + 1
if num > max then
num = 1
end
local player = players[num]
camera.CameraSubject = player.Character.Humanoid
status.Text = player.Name
end)
frame.Changed:Connect(function()
if not frame.Visible then
camera.CameraSubject = game.Players.LocalPlayer.Character.Humanoid
status.Text = game.Players.LocalPlayer.Name
end
end)