Localscript only runs when there is delay at the beggining

Hello, I am trying to make a earthquake effect, but for some reasons, the only time it works is when I put a delay at the beginning of the localscript.

There is a serverscript that is firing to all clients. This is what the earthquake localscript looks like

wait(10) -- this makes it work
print("apply earthquake")
local applyEarthquake = game.ReplicatedStorage:WaitForChild("ApplyEarthquake")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
print("replicated")
local RunService = game:GetService("RunService")
print("runservice")
local Players = game:GetService("Players")

print("hallo i exist ye")

local player = Players.LocalPlayer
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")

wait(10)

print("hallllllooo")

local function shakeCamera()
	local now = tick()
	local bobbleX = math.cos(now * 24) / 3
	local bobbleY = math.abs(math.sin(now * 40)) / 2
	
	local bobble = Vector3.new(bobbleX, bobbleY, 0) 
	humanoid.CameraOffset = humanoid.CameraOffset:Lerp(bobble, 0.25)
	
end 

applyEarthquake.OnClientEvent:Connect(function(isShaking)
	if isShaking then

		RunService:BindToRenderStep("CameraShake", Enum.RenderPriority.Camera.Value + 1, shakeCamera)
	else
		
		RunService:UnbindFromRenderStep("CameraShake")
	end
end)

This localscript only works and prints when I add the wait(10) at the beginning. The localscript is in replicatedFirst.

What could be the problem?

Thanks :slight_smile:

print("apply earthquake")
local applyEarthquake = game.ReplicatedStorage:WaitForChild("ApplyEarthquake")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
print("replicated")
local RunService = game:GetService("RunService")
print("runservice")
local Players = game:GetService("Players")

print("hallo i exist ye")

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

task.wait(10)

print("hallllllooo")

local function shakeCamera()
	local now = tick()
	local bobbleX = math.cos(now * 24) / 3
	local bobbleY = math.abs(math.sin(now * 40)) / 2
	
	local bobble = Vector3.new(bobbleX, bobbleY, 0) 
	humanoid.CameraOffset = humanoid.CameraOffset:Lerp(bobble, 0.25)
end 

applyEarthquake.OnClientEvent:Connect(function(isShaking)
	if isShaking then
		RunService:BindToRenderStep("CameraShake", Enum.RenderPriority.Camera.Value + 1, shakeCamera)
	else
		RunService:UnbindFromRenderStep("CameraShake")
	end
end)

I am guessing it is how you defined the character

2 Likes

Hey @mariohead13!

This issue plagued me as a beginner for MONTHS! I’m so glad I’m finally able to pass down my widsom aquired through pain.

So like with what @D0RYU said, the initial issue was in fact that you were attempting to save the character in a variable before the character exists.

His solution will work, expect in one case. What if the character dies?

The solution to that is just as simple luckily!

local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
Player.CharacterAdded:Connect(function(Char) Character = Char end)

With this simple addition to the code we can ensure that the character will always be set correctly regardless of outside conditions.

However we’re not done yet… Because you are also setting the humanoid to a variable, which is a child of the character meaning it too will be changed when the character dies.
So you could either include the humanoid in the new CharacterAdded event we made, or the solution I suggest is that you simply re-get the humanoid every time you need it like so:

local function shakeCamera()
    local humanoid = Character:FindFirstChild("Humanoid")
    if not humanoid then return end
	local now = tick()
    local bobbleX = math.cos(now * 24) / 3
    local bobbleY = math.abs(math.sin(now * 40)) / 2

    local bobble = Vector3.new(bobbleX, bobbleY, 0) 
    humanoid.CameraOffset = humanoid.CameraOffset:Lerp(bobble, 0.25)
end

Thus making every instance in which players could break your code fixed! You simply make the humanoid variable in your function, and then test if the humanoid is a real thing, if it isn’t then return.

This may seem like it’s way too over engineered but with a larger player base these issues will be found, and they will be found many many MANY times. This all basically future proofs your code and ensures that it will never break!

Hope this helped!

3 Likes

oh yea I never added that, my bad

Thank you for the help! It works :slight_smile: