I am trying to prevent particle effects from obstructing a player’s view when they are in first person by detecting when the player is in first person and disabling the particle emitters (which are parented in the character’s base parts).
When the player first joins and their character first loads, the CharacterAdded event does not fire, but it fires for subsequent character loads (e.g. respawning). Is there another event I can use to cover this one case?
The code is in a local script in StarterPlayerScripts.
-- Greatly appreciate it if you can also point out bad practices
local function toggleParticleEffects()
local emitters = getParticleEmitters() -- returns a table of particle emitters in the character
if (camera.Focus.Position - camera.CFrame.Position).Magnitude <= 1 then -- check if we're in first person
if emitters then
for i, emitter in pairs(emitters) do
emitter.Enabled = false
end
end
else
if emitters then
for i, emitter in pairs(emitters) do
emitter.Enabled = true
end
end
end
end
local renderSteppedConnection;
localPlayer.CharacterAdded:Connect(function(newCharacter)
-- not sure if this is necessary because I've already defined them at the top
character = newCharacter
humanoid = character:WaitForChild("Humanoid")
renderSteppedConnection = RunService.RenderStepped:Connect(function()
toggleParticleEffects()
end)
end)
humanoid.Died:Connect(function()
if renderSteppedConnection then
renderSteppedConnection:Disconnect()
end
end)
It might be because the character loaded before the script (specifically the event listener) gets fired/called. What we can do is check if the character already exists before adding the listener. A better solution would be to put the localScript in StarterCharacterScripts.
Hey this will fix your code, I made a new function for you because when you first join the game the CharacterAdded is really patient and wants to wait a couple seconds before it detects. While adding the function before the characteradded event (or after it doesn’t matter) it will still count character being added.
local function toggleParticleEffects()
local emitters = getParticleEmitters()
if (camera.Focus.Position - camera.CFrame.Position).Magnitude <= 1 then
if emitters then
for i, emitter in pairs(emitters) do
emitter.Enabled = false
end
end
else
if emitters then
for i, emitter in pairs(emitters) do
emitter.Enabled = true
end
end
end
end
local renderSteppedConnection;
local function characterAdded(newCharacter)
character = newCharacter
humanoid = character:WaitForChild("Humanoid")
renderSteppedConnection = RunService.RenderStepped:Connect(function()
toggleParticleEffects()
end)
end
characterAdded(localPlayer.Character)
localPlayer.CharacterAdded:Connect(characterAdded)
humanoid.Died:Connect(function()
if renderSteppedConnection then
renderSteppedConnection:Disconnect()
end
end)
if localPlayer.Character then
characterAdded(localPlayer.Character)
end
localPlayer.CharacterAdded:Connect(characterAdded)
(So characterAdded doesn’t potentially run with nil as the character.)
Just like in DevFoyRBX’s code, you should just get the character initially in addition to making a connection for future characters. There isn’t another event unless you make one using the same method.
If player joins the game there is no need to check if its in the playeradded event which is not in that script because it’s a client so you are correct there.