Introduction:
Hello Developers!
- I’ve made a pretty cool frozen effect recently . But after checking out the Devforum, I couldn’t find any similar tutorials or open source system so I thought that if I made this a free resource, it would be helpful to some other devs, especially during the current Winter season and future usages!
- This module has been completed! (All features: Create an ice layer , freeze at current animation frame , useful settings and customization )
- Documented , Has examples , Easy customization , Supports both R6 & R15
WORKS ON PLAYERS, NPCS & R6/R15/ALL TYPE OF RIGS!
Thunder’s Freeze Module:
(Has everything listed in this post)
“An incredibly cool, bone-chilling, icy module that creates a frosty, frozen effect”
Thunder’s Modified Freeze Module:
(No duration but it comes with an unfreeze function)
Mvke’s Modified Freeze Module:
(The modified version above but revamped once again. Please check for the one that suits you best! This one is better than Thunder’s modified version btw, although the ice layer is removed. Read his changes in his post)
Showcase (Higher resolution in the video link at the bottom):
Click here to see all!
- This mothod allows us to freeze rigs and it lets Roblox physics do the rest, so it looks more realistic than anchoring the target
- Parts will be covered in a custom ice mesh, MeshPart will be cloned with their properties set to be similar to the ice mesh (You cannot change a MeshPart’s MeshID though a script and this is way cooler) & SpecialMesh will be cloned with its parent (Part) to keep the same shape
- Animation is frozen (stopped) while being frozen (Works on Players/Rigs/NPCs, etc…)
- There are some settings to help you customize the ice layer & effects to whatever you like!
- This post is just a short tutorial for my module, you can modify it however you want but if you have any question, feel free to ask me for help!
Setup!
Everything we have in this Freeze Module include:
1. Set up the function to use it from any scripts
Let the module script stays in a specific place so you can edit once to apply changes to all of them and run the function just by calling it
- First of all, you need to take the module from the link below and insert it into your experience from the Toolbox
This will probably be the last step for the more experienced scripters out there but lets just continue lol - Now put the FreezeModule in somewhere like ServerStorage or ServerScriptService
The module will not run by itself until it’s called by another script - How to call the function and pass arguments into it:
local FreezeModule = require(game:GetService("ServerStorage").FreezeModule)
FreezeModule.Freeze(workspace["Target"], 3)
Insert a new Script and simply require the module (I put the FreezeModule in ServerStorage)
- You need 2 arguments: A target and a duration (Seconds)
In case you need to send a target as an argument but its name has space (Admin command for example), move down to below, this module also has sanity checks for typos or wrong value types so it won’t break if you accidently make a mistake like using an admin command - Target can be a rig, a player’s character, an NPC model, etc… as long as they have a HumanoidRootPart. Make sure to check if the Target’s Health is higher than 0 if neccessary!
2. Stop the target’s movement & the animation
Freeze the animation at the current frame
Stop the movement (Walking/Jumping)
Set HumanoidStateType to Physics so the target can fall down, get pushed, etc…
Disable active scripts in the character (Not necessary but this can prevent some bugs, errors or prevent the target from performing actions while being frozen
3. Create an ice layer that covers the target based on its size
Cover every single body Part & MeshPart with customizable, randomizable ice layer
Use Debris service to clean up the ice (I also have alternative methods here like task.delay())
Tween the ice layer to make it cooler
4. Other freezing effects & sounds based on the freeze duration
Freezing + Ice shattering effect
Sound plays faster if the freezing duration is shorter than its length
Make it even cooler
3/4 Examples (From the examples that come with the module):
Code snippets from the examples in the module!
- #1: Call the Function & Pass the arguments & Target
local Duration = 5
local Target = workspace:WaitForChild("Name", 10)
local FreezeModule = require(game:GetService("ServerScriptService").FreezeModule)
if Target then
FreezeModule.Freeze(Target, Duration)
end
- #2: Freeze on hit
-- Put this in a Part or anything that can use Touched event and modify it to what you want
-- Don't worry about the debounce/cooldown/delay we already check for that in the FreezeModule
-- Want to add time to the freeze duration? Work for it! I'm just a modeler with a bit of scripting experience
local Duration = 2
local FreezeModule = require(game:GetService("ServerScriptService").FreezeModule)
script.Parent.Touched:Connect(function(Hit)
if Hit and Hit.Parent and Hit.Parent:IsA("Model") then
local Target = Hit.Parent
if Target:FindFirstChildOfClass("Humanoid") then
local Humanoid = Hit.Parent:FindFirstChildOfClass("Humanoid")
FreezeModule.Freeze(Target, Duration)
end
end
end)
- #3: Freeze with loop (All rigs, can ignore Players if you want)
-- Don't worry about the debounce/cooldown/delay we already check for that in the FreezeModule
local Duration = 5
local FreezeModule = require(game:GetService("ServerScriptService").FreezeModule)
-- Freeze all models in the workspace if they have a Humanoid & HumanoidRootPart (Both players and NPCS)
for _, v in pairs(workspace:GetChildren()) do
if v:IsA("Model") and v:FindFirstChildOfClass("Humanoid") then
-- if game:GetService("Players"):GetPlayerFromCharacter(v) then return end -- If the child is a Player, it's ignored (Only freeze NPCs)
-- Remove "return end", add "not" above and put another "end" below if it fails to check lol
coroutine.wrap(function() -- Freeze all of them at the same exact time
local Target = v
FreezeModule.Freeze(Target, Duration)
end)()
end
end
-- // Quick notes // --
--[[
Normal version. Want an unfreeze function? Get the modified version from the devforum post
By Thunder (@ThunderDaNub)
DevForum post: https://devforum.roblox.com/t/%E2%9D%86-freeze-module-make-a-cool-frozen-effect-%E2%9D%85/2778467
Showcase video: In the DevForum post
No credits required. Free to use in your experiences. But credits are still appreciated. I'd love to know what cool creations you've made using this!
Notes: Animation is frozen (stopped) while being frozen (Works on Players/Rigs/NPCs, etc....)
]]
-------------------------------------------------------------------------------------
-- // Simple Customizations // --
local AnchorIfNotMoving = false --[[
==> If the Target barely moves or not moving at all (Velocity.Magnitude < 2) then the ice layer will be anchored, making the Target stays in place
- Set AnchorIfNotMoving to false to make the Target moveable, fall down, pushable, etc (Physics stuff, I suggest you to set it to false)
- If AnchorIfNotMoving is true, Players won't be able to rotate around while frozen
]]
local DisableScripts = true --[[
==> Disable Scripts & LocalScripts in the Target to prevent it from performing actions
- Can also prevent some glitches, bugs and errors
- Players' animations can still play if you don't disable the animation script (Player rigs are special lol)
]]
local DisableToolScripts = false --[[
==> Disable Scripts & LocalScripts inside any Tool/Gear that the target is currently holding
- Can break stuff so just set it to FALSE
]]
local ClassNamesToFreeze = {
"Part",
"WedgePart",
"CornerWedgePart",
"TrussPart",
"UnionOperation",
}
--> Types of parts that can be frozen. MeshParts & SpecialMeshes are for another section so please don't add them
local IceSettings = {
IceSize = 1.2;
--> Determine how thick the ice layer is (IceSize * Target's Size)
--| Example: 1 = Same size as the Target's Parts/MeshParts/SpecialMeshes, will create Z-Fighting | 0.5 is half of the Target's size (Smaller) | 1.2 = 20% bigger
SpecialMeshSize = 1.2;
--> Determine how thick the ice layer is (SpecialMeshSize * Target's SpecialMeshes' Scale)
-- Meshes sometimes have really weird shapes so they can make the ice layer look ugly if it's too big
Name = "Ice";
TextureID = "";
--> We don't want the MeshParts to keep their original texture so we set to nothing. You can use your ice texture if you want (Doesn't apply for the IceBlock meshes)
Color = Color3.fromRGB(128, 187, 219);
-- = BrickColor.new("Pastel Blue")
Material = Enum.Material.Ice;
CanCollide = false;
--> Can physically interact with other objects?
CanTouch = false;
--> Can use Touched event?
CanQuery = false;
--> Can interact with Raycast? (Will effect hitbox!)
CastShadow = false;
Massless = true;
--> No mass?
Transparency = 0.5;
--> The ice layer's transparency is set to 1 first, then will be tweened to this value
}
-- Effect customization is near the bottom of the module, it's pretty simple to understand
-------------------------------------------------------------------------------------
local Debris = game:GetService("Debris")
local Running = game:GetService("RunService")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local Module = {}
-- Don't like using Debris service for whatever reason? Use this
--[[task.delay(Duration, function()
Object:Destroy()
end)]]
local function CheckClassName(Object)
for _, ClassName in ipairs(ClassNamesToFreeze) do
if Object:IsA(ClassName) then
return true
end
end
return false
end
-- Create a weak table to store the old walkspeed and jumppower values
local OldValues = setmetatable({}, {__mode = "k"})
-- Function to change the player's walkspeed and jumppower
local function ChangeValues(player, NewWalkspeed, NewJumppower)
-- Store the old walkspeed and jumppower values in the table
OldValues[player] = {
walkspeed = player:FindFirstChildOfClass("Humanoid").WalkSpeed,
jumppower = player:FindFirstChildOfClass("Humanoid").JumpPower
}
-- Change the player's walkspeed and jumppower
player:FindFirstChildOfClass("Humanoid").WalkSpeed = NewWalkspeed
player:FindFirstChildOfClass("Humanoid").JumpPower = NewJumppower
end
-- Function to set the player's walkspeed and jumppower back to the original values
local function SetBackValues(player)
if OldValues[player] then
-- Find the stored old values for the player
local OldWalkspeed = OldValues[player].walkspeed
local OldJumppower = OldValues[player].jumppower
-- Set the walkspeed and jumppower back to the original values
player:FindFirstChildOfClass("Humanoid").WalkSpeed = OldWalkspeed
player:FindFirstChildOfClass("Humanoid").JumpPower = OldJumppower
-- Remove the old values from the table
OldValues[player] = nil
end
end
-- // Functions // --
-- This will check if we sent nothing for the Duration argument to prevent errors
Module.IsArgumentBlank = function(Argument)
-- Remove all spaces from the argument
local TrimmedArgument = string.gsub(Argument, "%s", "")
-- Check if the resulting string is empty
if TrimmedArgument == "" then
return true
else
return false
end
end
-- This will check if we sent number for the Duration argument to prevent errors
Module.IsArgumentNumber = function(Argument)
-- Attempt to convert the argument into a number
local Number = tonumber(Argument)
-- Check if the conversion succeeded
if Number ~= nil then
return true
else
return false
end
end
-- 2 arguments: Target (Model with a Humanoid object & HumanoidRootPart) + Duration (Number - Seconds)
Module.Freeze = function(Target, Duration)
-- Check to prevent errors
if Module.IsArgumentBlank(Duration) then return end
if not Module.IsArgumentNumber(Duration) then return end
if not Duration or not Target then return end
Duration = Duration or 1
--[[
Later on, we'll disable all Scripts & LocalScripts in the Target (Not neccessary)
This is a whitelist (It'll ignore these names, converted to string.lower())
You don't have to worry about uppercase letters (ABC) as we'll use string.lower (ABC --> abc)
]]
local IgnoreList = {"badgereward", "stunscript"}
local DisableList = {}
--Check if the Target is already frozen
local Ignore = false
for i, v in pairs(Target:GetChildren()) do
if v.Name == "FrozenTag" and v:IsA("ObjectValue") and v.Value == Target then
Ignore = true
end
end
-- If not frozen, we'll freeze it
if not Ignore and Target:FindFirstChild("HumanoidRootPart") then
-- Frozen tag so the Target can't be frozen again while being frozen (Yk what I mean)
local Frozen = Instance.new("ObjectValue")
Frozen.Name = "FrozenTag"
Frozen.Value = Target
Frozen.Parent = Target
Debris:AddItem(Frozen, Duration)
-- If the Duration is too short, we'll make the tween time of the ice layer even shorter
local TweenTime
if tonumber(Duration) >= 1 then
TweenTime = 0.5
else
TweenTime = tonumber(Duration)/5
end
-- TweenInfo for all of the ice layer
local TI = TweenInfo.new(TweenTime, Enum.EasingStyle.Quint, Enum.EasingDirection.InOut)
local Root = Target:FindFirstChild("HumanoidRootPart")
-- This is important, if you ONLY want a SINGLE ICE CUBE then this is the size for it. Remove the other parts if so
local CharacterSize = Target:GetExtentsSize().Magnitude
if CharacterSize >= 20 then
CharacterSize = 20
end
--[[
A single ice cube that covers the entire Target model, I make this invisible because I want a cooler frozen effect
You can remove the other parts and keep this for a single ice cube
I'm only creating this for the effects
]]
local CoverPart = Instance.new("Part")
CoverPart.Name = "IceCover"
CoverPart.Color = IceSettings.Color
CoverPart.Material = IceSettings.Material
CoverPart.CanCollide = IceSettings.CanCollide
CoverPart.CanTouch = IceSettings.CanTouch
CoverPart.CanQuery = IceSettings.CanQuery
CoverPart.CastShadow = IceSettings.CastShadow
CoverPart.Massless = IceSettings.Massless
CoverPart.Transparency = 1
CoverPart.Size = Vector3.new(CharacterSize, CharacterSize, CharacterSize)
-- Multiply by a number if you want it to be bigger
CoverPart.Position = Root.Position
CoverPart.Parent = Root
-- Weld it to the HumanoidRootPart
local Weld = Instance.new("WeldConstraint")
Weld.Part0 = CoverPart
Weld.Part1 = Root
Weld.Parent = CoverPart
-- If the Duration is shorter than the time length of the freezing sound, we'll make the sound plays faster (Higher pitch as well)
task.spawn(function()
local FreezingSound = script:FindFirstChild("Freeze"):Clone()
FreezingSound.Parent = CoverPart
if tonumber(Duration) < FreezingSound.TimeLength then
FreezingSound.PlaybackSpeed = FreezingSound.TimeLength / tonumber(Duration)
FreezingSound:Play()
else
FreezingSound:Play()
end
end)
Debris:AddItem(CoverPart, Duration)
-- All ice meshes we need to randomize the ice layer
local IceFolder = script.FreezeEffects["Ice Blocks"]
local IceBlocks = {IceFolder.IceBlock1, IceFolder.IceBlock2}
-- Remember to put the names here if you want to add more ice meshes
for _, v in ipairs(Target:GetDescendants()) do
-- If we find a part, cover it in a randomized ice mesh
if CheckClassName(v) and not v:FindFirstChildOfClass("SpecialMesh") then
if v.Transparency ~= 1 then
coroutine.wrap(function()
local IceBlock = IceBlocks[math.random(1, #IceBlocks)]
local Ice = IceBlock:Clone()
-- If the Target wasn't moving then anchor the ice to make the Target stay in place (Not neccessary)
if Root.Velocity.Magnitude < 2 and AnchorIfNotMoving == true then
Ice.Anchored = true
else
Ice.Anchored = false
end
-- We set the size to (0, 0, 0) then tween it to the actual size we want for a nice effect
Ice.Name = IceSettings.Name
Ice.TextureID = IceSettings.TextureID
Ice.Color = IceSettings.Color
Ice.Material = IceSettings.Material
Ice.CanCollide = IceSettings.CanCollide
Ice.CanTouch = IceSettings.CanTouch
Ice.CanQuery = IceSettings.CanQuery
Ice.CastShadow = IceSettings.CastShadow
Ice.Massless = IceSettings.Massless
Ice.Transparency = 1
Ice.Size = Vector3.new(0, 0, 0)
Ice.Position = v.Position
Ice.Orientation = v.Orientation
Ice.Parent = v
-- Size is a bit bigger so we can see it and prevent Z-Fighting parts
-- Set its orientation and position to be like the Part's, then set its parent to the Part)
local NewSize = Vector3.new(v.Size.X, v.Size.Y, v.Size.Z) * IceSettings.IceSize
local Tween = TweenService:Create(Ice, TI, {Transparency = IceSettings.Transparency, Size = NewSize})
Tween:Play()
-- Weld it to the Part
local Weld = Instance.new("WeldConstraint")
Weld.Part0 = Ice
Weld.Part1 = v
Weld.Parent = Ice
Debris:AddItem(Ice, Duration)
-- The only way to complete stop a player's animation I could find (Only took a few hours because I was editing the wrong script :( bruh)
local Weld2 = Instance.new("WeldConstraint")
Weld2.Part0 = Root
Weld2.Part1 = v
Weld2.Parent = Ice
end)()
end
-- Same as the Part but we clear its children if it's a MeshPart
-- We don't need an ice block here because it'll be too blocky, we make it looks like a thin layer of ice covering instead
elseif v:IsA("MeshPart") and not v:FindFirstChildOfClass("WrapLayer") then
if v.Transparency ~= 1 then
coroutine.wrap(function()
local Ice = v:Clone()
Ice:ClearAllChildren()
Ice.Name = IceSettings.Name
Ice.TextureID = IceSettings.TextureID
Ice.Color = IceSettings.Color
Ice.Material = IceSettings.Material
Ice.CanCollide = IceSettings.CanCollide
Ice.CanTouch = IceSettings.CanTouch
Ice.CanQuery = IceSettings.CanQuery
Ice.CastShadow = IceSettings.CastShadow
Ice.Massless = IceSettings.Massless
Ice.Transparency = 1
Ice.Size = Vector3.new(0, 0, 0)
Ice.Position = v.Position
Ice.Orientation = v.Orientation
Ice.Parent = v
local NewSize = Vector3.new(v.Size.X, v.Size.Y, v.Size.Z) * IceSettings.IceSize
local Tween = TweenService:Create(Ice, TI, {Transparency = IceSettings.Transparency, Size = NewSize})
Tween:Play()
local Weld = Instance.new("WeldConstraint")
Weld.Part0 = Ice
Weld.Part1 = v
Weld.Parent = Ice
Debris:AddItem(Ice, Duration)
local Weld2 = Instance.new("WeldConstraint")
Weld2.Part0 = Root
Weld2.Part1 = v
Weld2.Parent = Ice
end)()
end
-- This is just a bit different
elseif v:IsA("SpecialMesh") then
if v.Parent:IsA("Part") and v.Parent.Transparency ~= 1 then
coroutine.wrap(function()
local Ice = v.Parent:Clone()
for i, v in pairs(Ice:GetChildren()) do
if not v:IsA("SpecialMesh") then
v:Destroy()
end
end
local IceMesh = Ice:FindFirstChildOfClass("SpecialMesh")
Ice.Name = IceSettings.Name
IceMesh.TextureId = IceSettings.TextureID
Ice.Color = IceSettings.Color
Ice.Material = IceSettings.Material
Ice.CanCollide = IceSettings.CanCollide
Ice.CanTouch = IceSettings.CanTouch
Ice.CanQuery = IceSettings.CanQuery
Ice.CastShadow = IceSettings.CastShadow
Ice.Massless = IceSettings.Massless
Ice.Transparency = 1
IceMesh.Scale = Vector3.new(v.Scale.X, v.Scale.Y, v.Scale.Z) * IceSettings.SpecialMeshSize
Ice.Position = v.Parent.Position
Ice.Orientation = v.Parent.Orientation
Ice.Parent = v.Parent
local Tween = TweenService:Create(Ice, TI, {Transparency = IceSettings.Transparency})
Tween:Play()
local Weld = Instance.new("WeldConstraint")
Weld.Part0 = Ice
Weld.Part1 = v.Parent
Weld.Parent = Ice
Debris:AddItem(Ice, Duration)
local Weld2 = Instance.new("WeldConstraint")
Weld2.Part0 = Root
Weld2.Part1 = v.Parent
Weld2.Parent = Ice
end)()
end
--[[
In here, I disable active Scripts & LocalScripts to prevent the Target from performing actions and possible errors
They are added to a list and will be disabled later
Simply remove this and the similar sections below if you don't want this
]]
elseif v:IsA("Script") or v:IsA("LocalScript") then
if DisableScripts == true and not v.Parent:IsA("Tool") then
if v.Enabled == true then
-- Ignore if its name is listed in the mentioned list
if not IgnoreList[string.lower(v.Name)] then
table.insert(DisableList, v.Name)
end
end
end
if DisableToolScripts == true and v.Parent:IsA("Tool") then
if v.Enabled == true then
-- Ignore if its name is listed in the mentioned list
if not IgnoreList[string.lower(v.Name)] then
table.insert(DisableList, v.Name)
end
end
end
end
end
-- Attachment for some of the effects (Like the "Shock Wave", we want it to stay in the center
local Attachment = Instance.new("Attachment")
Attachment.Parent = Root
Debris:AddItem(Attachment, Duration)
-- Customize your own freezing effects
-- EmitCount attribute is a Number value. Edit them from the Properties pannel, higher number = more effect particles
for i, v in pairs(script.FreezeEffects:GetChildren()) do
if v:IsA("ParticleEmitter") then
local EffectClone = v:Clone()
if EffectClone.Name == "Smoke" then
local SizeMultiplier = CharacterSize * 1 -- Line 77 (Actually just use Control + F to search for anything you can't find lol)
EffectClone.Size = NumberSequence.new(0, SizeMultiplier)
EffectClone.Parent = Attachment
EffectClone.Enabled = true
Debris:AddItem(EffectClone, Duration)
elseif EffectClone.Name == "Sparkles" then
EffectClone.Parent = CoverPart
EffectClone.Enabled = true
elseif EffectClone.Name == "Shock Wave" then
local SizeMultiplier = CharacterSize * 1
EffectClone.Size = NumberSequence.new(0, SizeMultiplier)
EffectClone.Parent = Attachment
EffectClone:Emit(EffectClone:GetAttribute("EmitCount")) -- These ParticleEmitters have an attribute called "EmitCount" (Number value)
Debris:AddItem(EffectClone, Duration)
elseif EffectClone.Name == "Specs" then
local SizeMultiplier = CharacterSize * 0.2
EffectClone.Size = NumberSequence.new(SizeMultiplier, SizeMultiplier)
EffectClone.Parent = Attachment
EffectClone:Emit(EffectClone:GetAttribute("EmitCount"))
else
EffectClone.Parent = Root
EffectClone:Emit(EffectClone:GetAttribute("EmitCount"))
Debris:AddItem(EffectClone, Duration)
end
end
end
-- Disable the Scripts and LocalScripts
for i, v in ipairs(DisableList) do
if Target:FindFirstChild(v, true) then
local Object = Target:FindFirstChild(v, true)
if Object:IsA("Script") or Object:IsA("LocalScript") then
Object.Enabled = false
end
end
end
-- I don't need this but you can use a HighLight for the effect
--[[
local Highlight = Instance.new("Highlight")
Highlight.FillColor = Color3.new(0, 1, 1)
Highlight.OutlineTransparency = 1
Highlight.Parent = Target
Debris:AddItem(Highlight, Duration)
]]
-- Save the Target's current WalkSpeed & JumpPower so we can set them back later
if Target:FindFirstChildOfClass("Humanoid") then
local Humanoid = Target:FindFirstChildOfClass("Humanoid")
local Animator = Humanoid:WaitForChild("Animator", 10)
Humanoid.UseJumpPower = true
-- Disable the movement. You can try disabling the local player's controls in another LocalScripts (DevForum to learn more)
ChangeValues(Target, 0, 0)
-- Freeze any playing animation at the current frame
if Animator then
for i, v in pairs(Animator:GetPlayingAnimationTracks()) do
v:AdjustSpeed(0)
v:Stop()
end
end
-- Roblox Creator Hub to learn more about all the HumanoidStateTypes
Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
-- Wait for the duration to end, then set the WalkSpeed & JumpPower back to before
-- This may not be the best way to do it as other scripts can overlap this one but I, ThunderDaNub, is just a modeler with a bit of scripting experience
-- Good luck with creating a new, better system! I hope you can also contribute in this part if you're a more advanced scripter
task.wait(Duration)
Humanoid.UseJumpPower = true
SetBackValues(Target)
-- Continue playing the animation
if Animator then
for i, v in pairs(Animator:GetPlayingAnimationTracks()) do
v:AdjustSpeed(1)
end
end
Humanoid:ChangeState(Enum.HumanoidStateType.Freefall)
elseif Target:FindFirstChildOfClass("AnimationController") then
local AnimationController = Target:FindFirstChildOfClass("AnimationController")
local Animator = AnimationController:WaitForChild("Animator", 10)
if Animator then
for i, v in pairs(Animator:GetPlayingAnimationTracks()) do
v:AdjustSpeed(0)
v:Stop()
end
end
task.wait(Duration)
-- Continue playing the animation
if Animator then
for i, v in pairs(Animator:GetPlayingAnimationTracks()) do
v:AdjustSpeed(1)
end
end
end
task.spawn(function()
local ShatterSound = script:FindFirstChild("Ice Shatter"):Clone()
ShatterSound.Parent = Root
ShatterSound:Play()
Debris:AddItem(ShatterSound, 2)
end)
for i, v in pairs(script.FreezeEffects:GetChildren()) do
if v:IsA("ParticleEmitter") then
local EffectClone = v:Clone()
if EffectClone.Name == "Shock Wave" then
local SizeMultiplier = CharacterSize * 1
EffectClone.Size = NumberSequence.new(0, SizeMultiplier)
local Attachment = Instance.new("Attachment")
Attachment.Parent = Root
EffectClone.Parent = Attachment
EffectClone:Emit(EffectClone:GetAttribute("EmitCount"))
Debris:AddItem(Attachment, Duration)
elseif EffectClone.Name == "Specs" then
local SizeMultiplier = CharacterSize * 0.2
EffectClone.Size = NumberSequence.new(SizeMultiplier, SizeMultiplier)
local Attachment = Instance.new("Attachment")
Attachment.Parent = Root
EffectClone.Parent = Attachment
EffectClone:Emit(EffectClone:GetAttribute("EmitCount"))
Debris:AddItem(Attachment, Duration)
end
end
end
-- Enable the Scripts & LocalScripts we disabled before.
-- Beware that this is not a good way to do so because I'm only checking for the names, some of them may share a similar name and cause issues
task.wait()
for i, v in ipairs(DisableList) do
if Target:FindFirstChild(v, true) then
local Object = Target:FindFirstChild(v, true)
if Object:IsA("Script") or Object:IsA("LocalScript") then
Object.Enabled = true
end
end
end
table.clear(DisableList)
end
end
return Module
Credits:
Feel free to use and modify in your experiences. Any credits are appreciated
- @ThunderDaNub - Creator - I feel so cold
- @kingflippidlyflip - “Anchor” effect with physics
- @iiNeZoXii - Modified version of the modified version
- @Lord_BradyRocks - Contributor (Feedback, bug reporting & testing)
- @VoltenNa - Contributor (Feedback)
Sorry for mass pinging but I appreciate your help!