Simple UI Shake Module [NEW VERSION AVALIABLE!]

I made a simple Module that makes a UI shaking effect
It’s very simple.

Please report any bugs you find, I’d be very thankful

It’s also similar to sleitnick’s EZ Camera Shake

HOW TO USE

Functions

ShakeOnce() function

Example Code:

local Module = require(game.ReplicatedStorage:FindFirstChild('GuiShakerModule'))
local GuiElement = script.Parent.YourText

Module:ShakeOnce(GuiElement, 4, 0.4, 0)
-- The gui object, intensity, fade out time, delay

Result:


As you can see it works very well!
Shake() and ShakeOnce() are pretty different though.

Shake() function

Example Code:

local Module = require(game.ReplicatedStorage:FindFirstChild('GuiShakerModule'))
local GuiElement = script.Parent.YourText

Module:Shake(GuiElement, 4, 2)
-- The gui element, intensity, duration

Result:


You can see the difference, we set the duration to 2, and the text was shaking for 2 seconds!

You are also able to move the object while it has the shaking effect, thats right!

local RunService = game:GetService('RunService')
local Module = require(game.ReplicatedStorage:FindFirstChild('GuiShakerModule'))

RunService.RenderStepped:Connect(function(dt)
	Module:Shake(script.Parent.YourText, 12, 0.1)
	
	local Attribute = script.Parent.YourText:GetAttribute("OriginalPosition")
	
	if Attribute then
		script.Parent.YourText:SetAttribute("OriginalPosition", UDim2.new(math.random(1,2)/10,0,0,0))
	else
		script.Parent.YourText:SetAttribute("OriginalPosition", UDim2.new(math.random(1,2)/10,0,0,0))
	end
end)

The module automatically creates 2 attributes, which are OriginalPosition and OriginalRotation

I’m pretty bad at explaining but I hope you can understand
I hope I helped some people!


NOTE:

  • I might revamp this entire module because of more scripting knowledge I’ve gained over the months!
49 Likes

What would be nicer is if you stored the original position/orientation in the module itself. Nice module though.

9 Likes

Would check this out when I get access to Studio, but thanks for sharing!

2 Likes

Really thanks for all the likes and purchases :smiley:

2 Likes

the game keeps lagging every time the script is played

The lag issue most likely happens because the code keeps creating a new renderstepped event every time you use the shake function, without properly ending the previous ones. To fix this, you can disconnect the event either when it stops or before calling it again.

Note where the renderConnection variable is being disconnected

local renderConnection = nil
function module:ShakeOnce(element, intensity, fadeOutTime, delayTime)
	spawn(function()
		if renderConnection then
			renderConnection:Disconnect()
		end
		local Stopped = false
		local ReferenceIntensityValue = Instance.new('NumberValue', script)
		ReferenceIntensityValue.Value = intensity

		--// Basics \\--

		local OriginalPositionAttribute = element:SetAttribute("OriginalPosition", element.Position)
		local OriginalRotationAttribute = element:SetAttribute("OriginalRotation", element.Rotation)

		local OffsetConvert = 700
		local RotationConvert = intensity/1000

		renderConnection = RunService.RenderStepped:Connect(function(dt)
			if Stopped == false then
				intensity = ReferenceIntensityValue.Value 
				local OriginalPosition = element:GetAttribute("OriginalPosition")

				element.Position = OriginalPosition + UDim2.new(
					math.random(-intensity, intensity)/OffsetConvert,
					0,
					math.random(-intensity, intensity)/OffsetConvert,
					0
				)

			end
		end)

		spawn(function()
			while wait() do
				if Stopped == false then
					element.Rotation = math.random(-intensity, intensity)/2
				end
			end
		end)

		wait(delayTime)

		local CalmTween = TweenService:Create(ReferenceIntensityValue, TweenInfo.new(fadeOutTime, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut, 0, false, 0), {Value = 0})
		CalmTween:Play()
		CalmTween.Completed:Wait()

		Stopped = true
		if renderConnection then
			renderConnection:Disconnect()
		end
		element.Position =  element:GetAttribute("OriginalPosition")
		element.Rotation = element:GetAttribute("OriginalRotation")
		task.wait()
		element:SetAttribute("OriginalPosition", nil)
		element:SetAttribute("OriginalRotation", nil)
		
		ReferenceIntensityValue:Destroy()
	end)
end
2 Likes

image
image

UPDATE

Huge thanks to @WlZ_ONE for letting me know about the lag thats being caused when the module is running :+1:

Hey your latest fix made it so if you did something like

guiShaker:ShakeOnce(YouDied, 20, 1.2, 0)
guiShaker:ShakeOnce(DeathText, 20, respawnTime + 1, 0)

it wouldnt work as intended because RunService.RenderStepped would get cancelled if the function got called, so i made this

local module = {}

local RunService = game:GetService('RunService')
local TweenService = game:GetService('TweenService')

local ShakeOnceConnections = {}
local ShakeConnections = {}

function module:ShakeOnce(element, intensity, fadeOutTime, delayTime) -- Smoothing
	task.spawn(function()
		local Stopped = false
		local ReferenceIntensityValue = Instance.new('NumberValue', script)
		local tablePos = ShakeOnceConnections[#ShakeOnceConnections + 1]
		ReferenceIntensityValue.Value = intensity

		--// Basics \\--

		local OriginalPositionAttribute = element:SetAttribute("OriginalPosition", element.Position)
		local OriginalRotationAttribute = element:SetAttribute("OriginalRotation", element.Rotation)

		local OffsetConvert = 700
		local RotationConvert = intensity/1000

		tablePos = RunService.RenderStepped:Connect(function(dt)
			if Stopped == false then
				intensity = ReferenceIntensityValue.Value 
				local OriginalPosition = element:GetAttribute("OriginalPosition")

				element.Position = OriginalPosition + UDim2.new(
					math.random(-intensity, intensity)/OffsetConvert,
					0,
					math.random(-intensity, intensity)/OffsetConvert,
					0
				)

			end
		end)

		task.spawn(function()
			while task.wait() do
				if Stopped == false then
					element.Rotation = math.random(-intensity, intensity)/2
				end
			end
		end)

		task.wait(delayTime)

		local CalmTween = TweenService:Create(ReferenceIntensityValue, TweenInfo.new(fadeOutTime, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut, 0, false, 0), {Value = 0})
		CalmTween:Play()
		CalmTween.Completed:Wait()

		Stopped = true
		
		element.Position =  element:GetAttribute("OriginalPosition")
		element.Rotation = element:GetAttribute("OriginalRotation")
		task.wait()
		element:SetAttribute("OriginalPosition", nil)
		element:SetAttribute("OriginalRotation", nil)
		tablePos = nil
		ReferenceIntensityValue:Destroy()
	end)
	
end

function module:Shake(element, intensity, length)
	task.spawn(function()
		local Stopped = false
		local tablePos = ShakeOnceConnections[#ShakeOnceConnections + 1]

		--// Basics \\--

		local OriginalPositionAttribute = element:SetAttribute("OriginalPosition", element.Position)
		local OriginalRotationAttribute = element:SetAttribute("OriginalRotation", element.Rotation)

		local OffsetConvert = 700
		local RotationConvert = intensity/1000
		
		tablePos = RunService.RenderStepped:Connect(function(dt)
			if Stopped == false then
				local OriginalPosition = element:GetAttribute("OriginalPosition")

				element.Position = OriginalPosition + UDim2.new(
					math.random(-intensity, intensity)/OffsetConvert,
					0,
					math.random(-intensity, intensity)/OffsetConvert,
					0
				)

			end
		end)

		task.spawn(function()
			while task.wait() do
				if Stopped == false then
					element.Rotation = math.random(-intensity, intensity)/2
				end
			end
		end)

		task.wait(length)
		
		Stopped = true
		intensity = 0
		
		element.Position =  element:GetAttribute("OriginalPosition")
		element.Rotation = element:GetAttribute("OriginalRotation")
		task.wait()
		tablePos = nil
		element:SetAttribute("OriginalPosition", nil)
		element:SetAttribute("OriginalRotation", nil)
	end)
end

return module
1 Like

On an unrelated note, this is a very cool module i like it very much, heres a basic deathscreen i made out of it

2 Likes

i like your avatar :smile: its very prutty good

Hi, I used the “shakeOnce” function but I got an error. I assume its because the attribute can’t take the position number??

Here is what I did

guiShaker.ShakeOnce(playerBarHealthLeft, 4, 0.4, 0)

It errors:
“Attempted to index number with position”

What is playerBarHealthLeft? The first argument passed MUST be a UI Object (Frame for example)

:heart:


It’s a frame indeed. Idk why it broke

Ngl yours its actually cooler but i actually used it for a game over screen aswell LOL since i was using a pretty unpolished way to do shaking but then found out this module, pretty well made both your game over screen and this module ngl

In case you wanna see mine, here it is

External Media
1 Like

Awesome!
I’m developing a new version, which is almost ready, just requires bug fixes

It will contain more features than the current one!