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)
Because this topic was based around the code in the original post, I’d recommend changing the solution back to what was previously marked as the solution.
Even though the posts here and in the other topic you linked provided the exact same solution of using Player:RequestStreamAroundAsync(), it’d be a bit misleading for developers who read through this topic in the future to see that the marked solution is for a completely different spectating system from 2 months after the initial post, when the posts here provided code revisions that were specific to the codeblock within the original post.
Oh, I must have misremembered then; I thought one of the posts was marked as a solution and that you just didn’t reply to any of them afterwards. Especially since it went a long time without any new posts (I also never got a notification for the update 2 months later), after a while I presumed that the issue outlined in the initial post as it pertains to the original codeblock was eventually resolved.
So that means that you had tried to implement the suggestions in the following two posts and neither ended up working for the original code?
If that was the case, do you remember if any errors appeared in the Output, or if there was any unexpected behavior when testing out those changes, as well as what led you to decide to create a new spectating system, instead?
That may be useful to know for other developers who are planning on creating a spectating system in a game that has StreamingEnabled turned on, especially for understanding what made the difference between the original spectating system and the newer one, given that Player:RequestStreamAroundAsync() was recommended in both topics.
Whichever reply most accurately answered the initial question (based on what was included in the original post, since that is what the topic was created around) should be marked as the solution, which is up to you.
But if none of the posts in this topic ended up being a solution for the original code, which is what you mentioned earlier, then please refer to the questions I asked at the end of my last post:
Um you could also change the ReplicationFocus to the players RootPart that you are spectating. Just add a remote through which the player will fire to the server to change the ReplicationFocus. If you want to set the ReplicationFocus back to the your player, just set it as nil.