Camera Shaking Function

Made a custom shake controller in 2 minutes. Where do you guys think I could improve?

local function shake(length, power) -- e.g shake(3, .5)
	local currentTime = 0
	spawn(function()
		local random = Random.new() -- creating a Random
		while wait(.05) do
			if currentTime < length then
				local randomPos = Vector3.new(random:NextNumber(-power,power), random:NextNumber(-power,power), random:NextNumber(-power,power)) -- using power to get random decimals
				game:GetService("TweenService"):Create(game.Players.LocalPlayer.Character.Humanoid, TweenInfo.new(.1, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {CameraOffset = randomPos}):Play() -- shake camera
			end
		end
	end)
	for i = 1, length do
		wait(1)
		currentTime += 1 -- time of the shake
	end
	game:GetService("TweenService"):Create(game.Players.LocalPlayer.Character.Humanoid, TweenInfo.new(.1, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {CameraOffset = Vector3.new(0,0,0)}):Play() -- original position
end

wait(5)
shake(5, .3) -- (length, power (using either + or - values of original value))
3 Likes

Its short and easy to understand, love it!

1 Like

Task.wait.

Task.spawn

task.wait

Try replacing this with heartbeats.

I like the simplicity!

Does the while loop need to be longer to let the tween finish? Or should there be a completed:wait() in there?

Also, does this while loop ever end?

The reason I didn’t wait for the tween to end is because it will cause it to not look like shaking. The way I have it however will cause another shake in between a separate shake to create a consistent shaking effect.

none of those things are really necessary but I will look more into the task library to see where I can improve there.

Your while loop never ends, you should probably put an exit in that:

It will keep going forever. And if you call this function again, each call will spawn a while loop that will go on forever.

You could add a variable to stop the while loop, like this:

local StopCamShake = false
local function shake(length, power) -- e.g shake(3, .5)
	local currentTime = 0
	spawn(function()
		local random = Random.new() -- creating a Random
		while StopCamShake == false do 
			task.wait(.05)
			if currentTime < length then
				local randomPos = Vector3.new(random:NextNumber(-power,power), random:NextNumber(-power,power), random:NextNumber(-power,power)) -- using power to get random decimals
				game:GetService("TweenService"):Create(game.Players.LocalPlayer.Character.Humanoid, TweenInfo.new(.05, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {CameraOffset = randomPos}):Play() -- shake camera
			end
		end
		StopCamShake = false
	end)
	for i = 1, length do
		wait(1)
		currentTime += 1 -- time of the shake
	end
	StopCamShake = true
	game:GetService("TweenService"):Create(game.Players.LocalPlayer.Character.Humanoid, TweenInfo.new(.1, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {CameraOffset = Vector3.new(0,0,0)}):Play() -- original position	
end

wait(15)
shake(5, .3) -- (length, power (using either + or - values of original value))

output(with added prints):
20:03:26.295 :arrow_forward: while loop shake .05, stop= false (x81) - Client - LocalScript:8
20:03:31.230 play stop shake tween… - Client - LocalScript:22
20:03:31.230 while loop shake .05, stop= true - Client - LocalScript:8
20:03:31.231 while ended - Client - LocalScript:15

When using the ‘stopcamshake’ variable, you don’t even need the ‘currenttime’ varable, very simple short script with not infinite looping:

local StopCamShake = false

local function shake(length, power) -- e.g shake(3, .5)
	spawn(function()
		local random = Random.new() -- creating a Random
		while StopCamShake == false do 
				local randomPos = Vector3.new(random:NextNumber(-power,power), random:NextNumber(-power,power), random:NextNumber(-power,power)) -- using power to get random decimals
				game:GetService("TweenService"):Create(game.Players.LocalPlayer.Character.Humanoid, TweenInfo.new(.05, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {CameraOffset = randomPos}):Play() -- shake camera
				task.wait(.05)
		end
		StopCamShake = false
	end)
	task.wait(length)
	StopCamShake = true
	game:GetService("TweenService"):Create(game.Players.LocalPlayer.Character.Humanoid, TweenInfo.new(.1, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {CameraOffset = Vector3.new(0,0,0)}):Play() -- original position	
end

wait(15)
shake(5, .3) -- (length, power (using either + or - values of original value))

you can also end the loop simply with:

else
    break;

I was just too lazy to add it.

1 Like