Need Help With Camera! [Solved]

Need Help With Camera Shake Bug!

Hello there! Some time ago I added a nice shake effect to my Lobby Camera it has a bug though! Whenever you stay in the lobby for around a minute or so the camera begins to point in a random direction which is probably because the math is set as math.random
so I tried to fix this bug by setting the math to something else than random I didn’t get any good results though.

local function shakeCamera(length)

	local startTime = tick()

	while true do

		if tick() - startTime >= length then break end

		local x = math.random(-200, 200) / 1000
		local y = math.random(-200, 200) / 1000
		local z = math.random(-200, 200) / 1000
	
		script.Parent.Humanoid.CameraOffset = Vector3.new(x, y)
		workspace.CurrentCamera.CFrame *= CFrame.Angles(x / 100, y / 100, z / 100)

		wait(0.01)
	end

	script.Parent.Humanoid.CameraOffset = Vector3.new(0, 0, 0)
end

shakeCamera(999999999)

Thanks for reading!

1 Like

Instead of setting the Camera’s CFrame by multiplying it by some factor, set an “origin” for the camera and every frame offset it by some random amount (Camera.CFrame = originCFrame * randOffsetCFrame). This will keep the camera locked at the same approximate looking direction. Your other option would be to define constraints for the camera in terms of how far it is allowed to rotate off from some starting point - then whenever setting its CFrame you could just clamp it to remain within these bounds

2 Likes

So I tried using clamp but I don’t think I’m doing this right also where does The origin go?

local function shakeCamera(length)

	local startTime = tick()

	while true do
		if tick() - startTime >= length then break end

		local x = math.clamp(0, -200, 200) / 1000
		local y = math.clamp(0, -200, 200) / 1000
		local z = math.clamp(0, -200, 200) / 1000

		script.Parent.Humanoid.CameraOffset = Vector3.new(x, y)
		workspace.CurrentCamera.CFrame *= CFrame.Angles(x / 100, y / 100, z / 100)

		wait(0.01)
	end

	script.Parent.Humanoid.CameraOffset = Vector3.new(0, 0, 0)
end

shakeCamera(999999999)

I recommend changing the quaternions using math.rad then plugging in math.random to the radian that way there’s no gradual increase and you can establish an origin using the original angle + or - the range in the math.random

1 Like

Can you show me how that is done?

well I’m on phone right now so I can’t really write it out but I’ll refer you to the cframe doc. math.rad is basically the angle like 360 stuff and the origin is just the original angle of the camera so wherever you have that stored make sure it stays the same then for the math.random you’d do (origin-(range/2), origin+(range/2))

https://developer.roblox.com/en-us/api-reference/datatype/CFrame

1 Like

Alright, thanks! I’ll try it out!

Thanks a lot for all the help though I’m not able to figure this out since I have no understanding of math and Cframe. I would love to know how all of this is put together.

1 Like

I have made a beautiful camera shake script just for you, feel free to ask any questions. Make sure to read the Explanation!

Explination
ShakeCamera(Origin, StudRange, DegreeRange, Seconds, Intensity)

Origin : CFrame
The Origin is where your camera is maily located and which direction its facing.
The shake script will use this information to shake the camera along this origin.

StudRange : NumberValue
The StudRange is the offset in studs will shake.
E.g 0.5 Studs

DegreeRange : NumberValue
The DegreeRange is the offset in Degrees will shake.
E.g 45 Degrees

Seconds : NumberValue
The Seconds is time the camera will shake for.

Intensity : NumberValue
The Intensity is how fast the camera will shake.

local Camera = game.Workspace.Camera

local function ShakeCamera(Origin : CFrame, StudRange : NumberValue, DegreeRange : NumberValue, Seconds : NumberValue, Intensity : NumberValue)

	local function Dimension() : NumberValue
		return math.random(-StudRange, StudRange)
	end
	local function Radian() : NumberValue
		return math.rad(math.random(-DegreeRange, DegreeRange))
	end

	repeat wait() 
		Camera.CameraType = Enum.CameraType.Scriptable 
	until Camera.CameraType == Enum.CameraType.Scriptable
	Camera.CFrame = Origin 
	local Start = tick()
	local CurrentCF = Origin
	local LastChanged = 0

	local Lerp1 = Origin
	local Lerp2 = Origin
	local Lerp3 = Origin

	repeat
		if tick() - LastChanged >= (0.2 / Intensity) then
			LastChanged = tick()
			local Offset_Position = Vector3.new(Dimension(), Dimension(), Dimension())
			local Offset_Rotation = CFrame.Angles(Radian(), Radian(), Radian())
			CurrentCF = Offset_Rotation * Origin + Offset_Position
		end
		Lerp1 = Lerp1:Lerp(CurrentCF, 0.05 * Intensity)
		Lerp2 = Lerp2:Lerp(Lerp1, 0.05 * Intensity)
		Lerp3 = Lerp3:Lerp(Lerp2, 0.05 * Intensity)
		Camera.CFrame = Lerp3
		wait()
	until tick() > (Start + Seconds)
	Camera.CameraType = Enum.CameraType.Custom
end

ShakeCamera(CFrame.new(), 3, 5, 5, 1) --Demo Parameters
3 Likes

Thanks a lot everything works really well and the explanation made much sense though it doesn’t connect to my CameraPart is there a way to make move the Orgin?

Never mind I figured out that I can just place a part and save its position. Thanks a lot for the help!

No problem, I’m glad this helped!

1 Like

Oh yeah also is there a way to change the Orientation of the Origin?

Yes, its as simple as this.

local Rotation = Vector3.new(0, 0, 0)
local Position = Vector3.new(0, 0, 0)
local Origin = CFrame.new(Position) * CFrame.new(math.rad(Rotation.X), math.rad(Rotation.Y), math.rad(Rotation.Z))
1 Like

Alright, thanks! I got it to work!