What do you want to achieve? Keep it simple and clear!
-If a player touch a part, everyone in the server will get the jumpscare
What is the issue? Include screenshots / videos if possible!
-The jumpscare worked, but after that the camera of Player1 changed to Player2 camera. (the camera returned to wrong player)
What solutions have you tried so far? Did you look for solutions on the Developer Hub? -Yes
-I also tried something with FireClient, FireAllClients and player.
After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
this is the server script of the part
local debounce = false
local Players = game:GetService("Players")
local ghostCamera = workspace.Cameras.JumpscareCamera
local ghostAnim = script.Animation
local jumpscareDuration = 0.6
local dieAfter = false
script.Parent.Touched:connect(function(hit)
if not debounce then
debounce = true
for _,player in ipairs(Players:GetPlayers()) do
local JumpscareDummy = workspace.JumpscareDummy
local dummyHum = JumpscareDummy.Humanoid
local scare = JumpscareDummy.Head.scarysound
local camRemote = game.ReplicatedStorage.ChangeCamera
camRemote:FireAllClients(player,ghostCamera,jumpscareDuration)
dummyHum:LoadAnimation(ghostAnim):Play()
scare:Play()
wait(jumpscareDuration)
if dieAfter then
player.Character:BreakJoints()
end
end
wait()
script.Parent:Destroy()
debounce = false
end
end)
this is the local script in the StarterGUI
local camera = workspace.CurrentCamera
game.ReplicatedStorage.ChangeCamera.OnClientEvent:Connect(function(player,camera2,duration)
local character = player.Character
camera.CameraType = "Scriptable"
camera.CFrame = camera2.CFrame
wait(1)
camera.CameraSubject = character:WaitForChild("Humanoid")
camera.CameraType = "Custom"
camera.CFrame = character.Head.CFrame
end)
Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category. -Yes, I knew, any help would be appreciate!
You’re calling camRemote:FireAllClients() within a for-each player loop. This means that you’re firing all of the clients for each client in the server. Since FireAllClients already fires a signal to each client, you should have no need to nest it in the for loop that runs through all of the players. This also applies to the animation part. Given n is the amount of players currently in the server, you are playing the scare sound and ghostAnim animation a total of n times, which I don’t see the purpose of. You should only need to call it once. If I’m missing something and you’re trying to do something specific, let me know.
The reason your camera is going to the wrong player is because you’re passing in a specific player in your FireAllClients() call and using it. Because of this, the variable character in your LocalScript refers to the player passed through the FireAllClients call (whichever player is the current player in your for loop) instead of the player local to that client.
I see that you added a wait function in the for-each loop. The problem with this is that for each iteration, the code is yielded the specified amount of time, meaning when the script reaches the last player, it will have taken jumpscareDuration * (n-1) seconds, which I’m sure is not what you intended. I have combatted this with a task.spawn() approach.
Also, note that there is no need to set debounce back to false once you’ve already deleted the parent and established that the function is a one-and-done function.
Here is a suggested revamp of your scripts:
Server script:
local debounce = false
local Players = game:GetService("Players")
local ghostCamera = workspace.Cameras.JumpscareCamera
local ghostAnim = script.Animation
local jumpscareDuration = 0.6
local dieAfter = false
script.Parent.Touched:connect(function(hit)
if not debounce then
debounce = true
local JumpscareDummy = workspace.JumpscareDummy
local dummyHum = JumpscareDummy.Humanoid
local scare = JumpscareDummy.Head.scarysound
local camRemote = game.ReplicatedStorage.ChangeCamera
camRemote:FireAllClients(ghostCamera,jumpscareDuration)
dummyHum:LoadAnimation(ghostAnim):Play()
scare:Play()
for _,player in ipairs(Players:GetPlayers()) do
task.spawn(function()
wait(jumpscareDuration)
if dieAfter then
player.Character:BreakJoints()
end
end)
end
task.wait()
script.Parent:Destroy()
end
end)
LocalScript:
local players = game:GetService("Players")
local player = players.LocalPlayer
repeat task.wait() until player.Character
local character = player.Character
local camera = workspace.CurrentCamera
game.ReplicatedStorage.ChangeCamera.OnClientEvent:Connect(function(camera2,duration)
camera.CameraType = "Scriptable"
camera.CFrame = camera2.CFrame
task.wait(1)
camera.CameraSubject = character:WaitForChild("Humanoid")
camera.CameraType = "Custom"
camera.CFrame = character.Head.CFrame
end)
I cannot accurately test your scripts because, obviously, I don’t have access to your place or any of the other required assets in it, so there may be errors. If so, please let me know.
Hopefully this helped. If you have any questions or further issues, feel free to reach out.
hello! I tested it out and the camera issued fixed, I thought the error Player argument must be a player object will appear because I did something like this before, but it didn’t! However, I tried to mute sound from Player1 and I used Player2 to touch the part (player2’s volume was maxed), I didn’t hear the sound! Which I heard when I play-solo mode. Thanks for your help anyways!
For this issue, I suggest you move the scare object sound into a folder called “Sounds” in the Workspace. Then, play the sound locally from the LocalScript once the ChangeCamera RemoteEvent is fired.
I have recreated your scenario in my own workspace.
Here is a picture of the Sounds folder in the workspace, containing a sound object.
Here is the updated LocalScript.
local players = game:GetService("Players")
local sounds = workspace:WaitForChild("Sounds")
local scarysound = sounds:WaitForChild("scarysound")
local player = players.LocalPlayer
repeat task.wait() until player.Character
local character = player.Character
local camera = workspace.CurrentCamera
game.ReplicatedStorage.ChangeCamera.OnClientEvent:Connect(function(camera2,duration)
camera.CameraType = "Scriptable"
camera.CFrame = camera2.CFrame
scarysound:Play()
task.wait(1)
camera.CameraSubject = character:WaitForChild("Humanoid")
camera.CameraType = "Custom"
camera.CFrame = character.Head.CFrame
end)
Delete the workspace folder with the sound inside it and try the following.
local players = game:GetService("Players")
local soundService = game:GetService("SoundService")
local sound = Instance.new("Sound")
sound.Parent = soundService
sound.SoundId = "rbxassetid://1836983505" --change this to id of sound
local player = players.LocalPlayer
repeat task.wait() until player.Character
local character = player.Character
local camera = workspace.CurrentCamera
game.ReplicatedStorage.ChangeCamera.OnClientEvent:Connect(function(camera2,duration)
camera.CameraType = "Scriptable"
camera.CFrame = camera2.CFrame
soundService:PlayLocalSound(sound)
task.wait(1)
camera.CameraSubject = character:WaitForChild("Humanoid")
camera.CameraType = "Custom"
camera.CFrame = character.Head.CFrame
end)
Oh no! Maybe your solutions worked at first, I found out that whenever I tab out, the studio will be mute, so that’s why I thought I couldn’t hear the sound. Thank you so much!