I’m planning on using this effect for a game, so I spent a few hours messing with it and made my own module with type checking. It’s based from the Bubble Module - Distortion Effect. Thought it may be useful to share it with other developers.
note that your graphics need to be level 8 or higher or the effect won't work
Here is a baseplate thats already setup if u dont want to follow the steps below
Distortion.rbxl (97.0 KB)
Setting Up The Module
Required:
Parent a ModuleScript named “Distortion” to ReplicatedStorage and paste the code below.
Optional:
If you want a mesh that already works well with this effect then Parent one named “DefaultDistortion”. Then change the color of the mesh to fully white and change the MeshID to rbxassetid://10691561431. After that add the mesh to a variable that we can fetch through the module.
Here is an example that fetches our mesh, add it under the “Distortion” table:
Distortion.DefaultDistortion = script:WaitForChild("DefaultDistortion")
--!strict
local MIN_CLAMPED_TIME = 0.1
export type TransitionInfo = {
TransparencyStart:number,
TransparencyEnd:number,
SizeStart:Vector3,
SizeEnd:Vector3,
}
local Debris = game:GetService("Debris")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local distortionFolder = Instance.new("Folder")
distortionFolder.Name = "DistortionEffect"
distortionFolder.Parent = workspace
local Distortion = {}
Distortion.DefaultDistortion = script:WaitForChild("DefaultDistortion")
function Distortion.DefaultTweenInfo(tweenTime:number?):TweenInfo
return TweenInfo.new(
tweenTime or 1,
Enum.EasingStyle.Sine,
Enum.EasingDirection.Out,
0,
false,
0
)
end
function Distortion.DefaultTransitionInfo(tStart:number?, tEnd:number?, sStart:Vector3?, sEnd:Vector3?):TransitionInfo
return {
TransparencyStart = tStart or 0.5,
TransparencyEnd = tEnd or 1,
SizeStart = sStart or Vector3.new(0.1,0.1,0.1),
SizeEnd = sEnd or Vector3.new(5,5,5),
}
end
function Distortion.CreateDistortion(distortion:BasePart, track:CFrame|BasePart, tweenInfo:TweenInfo, transitionInfo:TransitionInfo):number
local function distortionPart()
local part = distortion:Clone()
part.CastShadow = false
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
part.Massless = true
part.Material = Enum.Material.Glass
part.Size = transitionInfo.SizeStart
part.Transparency = transitionInfo.TransparencyStart
local highlight = Instance.new("Highlight")
highlight.Enabled = false
highlight.Parent = part
return part
end
local function tweenPart(part:BasePart)
local fullTweenTime = math.clamp(tweenInfo.Time + tweenInfo.DelayTime, MIN_CLAMPED_TIME, math.huge)
Debris:addItem(part, fullTweenTime)
local propertyInfo = {
Transparency = transitionInfo.TransparencyEnd,
Size = transitionInfo.SizeEnd
}
TweenService:Create(part, tweenInfo, propertyInfo):Play()
return fullTweenTime
end
if typeof(track) == "CFrame" then
local part = distortionPart()
part.CFrame = track
part.Anchored = true
part.Parent = distortionFolder
return tweenPart(part)
elseif typeof(track) == "Instance" and track:IsA("BasePart") then
local part = distortionPart()
part.CFrame = track.CFrame
part.Anchored = false
part.Parent = distortionFolder
local weld = Instance.new("WeldConstraint")
weld.Part0 = part
weld.Part1 = track
weld.Parent = part
return tweenPart(part)
else
return MIN_CLAMPED_TIME
end
end
function Distortion.CreateContinuousDistortion(distortion:BasePart, track:CFrame|BasePart, tweenInfo:TweenInfo, transitionInfo:TransitionInfo, rate:number?):RBXScriptConnection
local clampedRate = math.clamp(rate or 0, MIN_CLAMPED_TIME, math.huge)
local prevTime = time()
local waitTime = 0
return RunService.Heartbeat:Connect(function()
if time() - prevTime < waitTime then return end
prevTime = time()
local tweenTime = Distortion.CreateDistortion(distortion, track, tweenInfo, transitionInfo)
waitTime = rate and clampedRate or tweenTime
end)
end
return Distortion
After that the module should be all good to go, now you just need to require it.
Usage Example
If you want to see the effect in game put this code below into a LocalScript in StarterPlayerScripts. If you didn’t do the optional part for setting up the module then replace the first parameter of the CreateContinuousDistortion Function to the mesh you want it to use.
--!strict
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Distortion = require(ReplicatedStorage.Distortion)
local tweenInfo = Distortion.DefaultTweenInfo(10)
local transistionInfo = Distortion.DefaultTransitionInfo()
Distortion.CreateContinuousDistortion(Distortion.DefaultDistortion, CFrame.new(0,5,0), tweenInfo, transistionInfo, 1)