Custom Camera doesn't reset on Death

I’ve been working with a 2D Custom Camera script and the camera doesn’t go back to the player when they die as a result

I’ve looked into this issue everywhere and no solution has worked, what’s strange is that workspace.Camera says it reset the Cam type to Custom and the Camera Subject to Humanoid again, but it doesn’t actually physically reset

this is fixed by resetting character a second time or resetting the camera subject to humanoid again manually

Any ideas on how to fix this?

Edit: here’s the camera script so you can try fixing this in Studio by yourself (StarterCharacterScripts):

local cam = workspace.CurrentCamera

local char = script.Parent
local hrp = char:WaitForChild("HumanoidRootPart")


local cas = game:GetService("ContextActionService")

game:GetService("RunService").RenderStepped:Connect(function()
	
	if script.toggle.Value == false then
		cam.CameraType = Enum.CameraType.Custom
	else
		cam.CameraType = Enum.CameraType.Scriptable
		cam.CFrame = cam.CFrame:Lerp(CFrame.new(hrp.Position + Vector3.new(0, 5, 15), hrp.Position), .5)
	end
	
end)

(there’s a boolvalue called toggle inside the script which activates the camera when a player hits a part, you can remove the toggle parts of the script for simplicity)

4 Likes

I can’t seem to replicate your issues, here’s my test camerareset.rbxl (34.6 KB), do you have a simple example to demonstrate?
I put it in StarterCharacterScripts in a LocalScript and started the game then reset and the camera went back the player

1 Like

You should put it in StarterPlayerScripts instead, as advised on the wiki:

2 Likes

I’m not entirely sure but creating this variable outside the RenderStepped loop could be the problem. Not entirely sure what happens on death but if the Player’s Character gets recreated then this HumanoidRootPart won’t exist anymore.

1 Like

The script was in StarterCharacterScripts so a new copy would be made every time the character is loaded (and the old script would be destroyed) so that variable would always have the correct value

2 Likes

I’ve been working with a ModuleScript this whole time but I watered it down for the sake of simplicity and the fact I didn’t think it was relevant

I’ve put the scripts in StarterPlayerScripts but the ModuleScript is having a hard time finding playerscripts

local cammodule = {}

function cammodule.toggleon(hit)
	
	local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
	local playerscripts = player:FindFirstChild("PlayerScripts")
	
	if player then
		
		local camscript = playerscripts:WaitForChild("2DCamera")
		camscript.toggle.Value = true
		
	end
	
end

I get “Attempt to Index nil with” both the findfirst and waitfor child, I tried both lines with findfirst and waitfor child instead but I got the same result

I also tried just referencing it with .PlayerScripts but it told me that it doesn’t exist, can ModuleScripts not access PlayerScripts?

1 Like

Since its now in StarterPlayerScripts you want to use the LocalPlayer for your player variable:

local player = game:GetService("Players").LocalPlayer
1 Like

Still getting attempt to index nil when trying to find PlayerScripts

1 Like

Are you sure it’s not finding PlayerScripts? What’s the error message? I just tried it in Studio myself and it worked.

1 Like

“Attempt to index nil with ‘PlayerScripts’”

referring to local playerscripts = player:FindFirstChild(“PlayerScripts”)

That means your player is returning nil, this function is being called on the client correct? The only reason it would return nil is because you aren’t calling it on the client.

No, the module is in ServerScriptService, is there an easy way to change this other than moving the module to a client service?

Use a RemoteEvent to send an update from the Server to the Client. When the RemoteEvent is fired on the client you can get the CamereScript you have from PlayerScripts and enable it or change some value in it.

I tried moving it to Replicated Storage but still nothing. There’s no error message now

I don’t think it can actually find the player

function cammodule.toggleon(hit)

	local player = game:GetService("Players").LocalPlayer
	
	if player then
		
		print("success")
		
		local playerscripts = game.Players.LocalPlayer.PlayerScripts
		local camscript = playerscripts:FindFirstChild("2DCamera")
		
		if playerscripts then
			print("success2")
		end
		
		camscript.toggle.Value = true

	end

end

Neither success nor success2 is printed

1 Like
function cammodule.toggleon(hit)
	
	local playerscripts = game.Players.LocalPlayer.PlayerScripts
	local camscript = playerscripts:FindFirstChild("2DCamera")
		
	if playerscripts then
		print("success2")
	end
		
	camscript.toggle.Value = true


end


“attempt to index nil with ‘PlayerScripts’” it’s really strange how it’s struggling to find playerscripts in every service

1 Like

ReplicatedStorage just replicates the script to the client. It doesn’t replicate any calls to any of the functions, or even the values. They are two separate copies: the server and the client.

Refer to my last response:

There’s documentation for Remote Events and Function here! :smiley:

Thank you! Trying this now

Just to clarify, Module and Event is in ServerScriptService?

The RemoteEvent should be in ReplicatedStorage so that both the client and server can access it. Then use RemoteEvent:FireClient(player) inside your module on the server (ServerScriptService or ServerStorage). On the client, you will connect a function to RemoteEvent.OnClientEvent so when the server runs the FireClient function on your RemoteEvent it will run whatever function you connected.

Alright I’ve changed that

How should I access the player with the ModuleScript? I wouldn’t be able to access it because it’s on the client right?

I tried using the hit.parent thing from before but I get the error “attempt to index boolean with “Parent””

Inside your CamModule script (Server):

local RemoteEvent = game:GetService("ReplicatedStorage"):WaitForChild("RemoteEvent") -- Path to RemoteEvent

function cammodule.toggleon(hit)
	local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
	RemoteEvent:FireClient(player, true) -- First parameter is the player you are sending the event to, everything after is data you are sending
end

Inside your Script or ModuleScript (StarterPlayerScripts):

local RemoteEvent = game:GetService("ReplicatedStorage"):WaitForChild("RemoteEvent") -- Path to RemoteEvent
local toggle = false -- Value to change

RemoteEvent.OnClientEvent:Connect(function (toggleValue)
	toggle = toggleValue -- Change the value of your variable(s) using the parameters
end)