--[[
Name: EffectManager
Author: TypicalUsername
Desc: Simple multi-purpose effect module for ROBLOX scripts and games. Made for Client and Server.
Please keep these credits in when used.
]]
local module = {}
local TweenService = game:GetService("TweenService")
local HttpService = game:GetService("HttpService")
local Debris = game:GetService("Debris")
local rad = math.rad(1)
local GarbageRandomColor = {}
function module.GenerateGUID(wrapInCurlyBraces)
return HttpService:GenerateGUID(wrapInCurlyBraces or false)
end
function module.Change(instance : Instance, props : table)
props = props or {}
table.foreach(props, function(i,v) instance[i] = v end)
end
function module.Create(class : string, props)
local part = Instance.new(class)
module.Change(part,props)
return part
end
function module.Remove(item, time)
if string.lower(typeof(item)) == "instance" then
game:GetService("Debris"):AddItem(item, time or 0)
elseif string.lower(typeof(item)) == "table" then
table.foreach(item, function(i,v) game:GetService("Debris"):AddItem(v, time or 0) end)
end
end
function module.Raycast(pos, v3, ignore)
local Ray = Ray.new(pos,v3)
local RayPart, RayPosition, Normal = workspace:FindPartOnRayWithIgnoreList(Ray, ignore, false, true)
return RayPart, RayPosition, Normal
end
function module.Tween(Data : {EaseStyle : Enum.EasingStyle, EaseDirection : Enum.EasingDirection, Object : Instance, Time : number, Properties : table}, WaitOnComplete : boolean)
if not Data.Object then return warn("Couldn't tween. No object?") end
if not Data.Properties then return warn("Couldn't tween. No properties?") end
local EasingStyle = Data.EaseStyle or Enum.EasingStyle.Sine
local EasingDirection = Data.EaseDirection or Enum.EasingDirection.InOut
local Time = Data.Time or 1
TweenService:Create(Data.Object, TweenInfo.new(Time, EasingStyle, EasingDirection), Data.Properties):Play()
if WaitOnComplete then
task.wait(Time)
end
end
function module.SoundEffect(Id,Volume,Pitch,Parent, Looped)
local sound = module.Create("Sound", {SoundId = "rbxassetid://"..tostring(Id), Volume = Volume or 1, Pitch = Pitch or 1, Parent = Parent or nil, Looped = Looped or false})
sound:Play()
task.spawn(function() if Looped then return end sound.Loaded:Connect(function() module.Remove(sound,sound.TimeLength/sound.Pitch) end) if sound.IsLoaded then module.Remove(sound,sound.TimeLength/sound.Pitch) end end)
return sound
end
function module.FileMesh(Parent, MeshId, TextureId, Scale, Offset)
return module.Create("SpecialMesh",{
Parent = Parent;
MeshType = "FileMesh";
MeshId = "rbxassetid://"..tostring(MeshId);
TextureId = TextureId or nil;
Scale = Scale or nil;
Offset = Offset or nil;
})
end
function module.CreateEffect(Data : {Time : number, Transparency : number, GoalTransparency : number, Shape : Enum.PartType, Color : Color3, GoalColor : Color3, Material : Enum.Material, CFrame : CFrame, GoalCFrame : CFrame, Size : Vector3, GoalSize : Vector3, TweenDirection : Enum.EasingDirection, TweenStyle : Enum.EasingStyle, RandomRotation : boolean, Mesh : string, RandomColors : table})
local Data = Data
local SpecialMesh = Data.Mesh or "nil"
local Shape = Data.Shape or Enum.PartType.Block
local Material = Data.Material or Enum.Material.SmoothPlastic
local CF = Data.CFrame
local Color = Data.Color or BrickColor.new("Medium stone grey").Color
if Data.RandomColors then
Color = Data.RandomColors[math.random(1,#Data.RandomColors)]
end
local Size = Data.Size or Vector3.one
local Part = Instance.new("Part", workspace:FindFirstChildOfClass("Terrain"))
local ActualMesh
if Shape == Enum.PartType.Ball then
Shape = Enum.PartType.Block
module.Create("SpecialMesh",{
Parent = Part;
MeshType = Enum.MeshType.Sphere;
})
end
module.Change(Part,{
Name = module.GenerateGUID();
Anchored = true;
CanCollide = false;
Transparency = Data.Transparency or 0;
Color = Color;
CFrame = CF;
Shape = Shape;
Material = Material;
Size = Size;
})
if SpecialMesh:lower() == "wave" then
ActualMesh = module.FileMesh(Part,20329976,nil,Size,Vector3.new(0,0,-Size.X/8))
elseif SpecialMesh:lower() == "ring" then
ActualMesh = module.FileMesh(Part,559831844,nil,Vector3.new(Size.X,Size.X,0.1),nil)
elseif SpecialMesh:lower() == "slash" then
ActualMesh = module.FileMesh(Part,662586858,nil,Vector3.new(Size.X/10,0.01,Size.X/10),nil)
elseif SpecialMesh:lower() == "round slash" then
ActualMesh = module.FileMesh(Part,662585058,nil,Vector3.new(Size.X/10,0.01,Size.X/10),nil)
elseif SpecialMesh:lower() == "swirl" then
ActualMesh = module.FileMesh(Part,168892432,nil,Size,nil)
elseif SpecialMesh:lower() == "skull" then
ActualMesh = module.FileMesh(Part,4770583,nil,Size,nil)
elseif SpecialMesh:lower() == "crystal" then
ActualMesh = module.FileMesh(Part,9756362,nil,Size,nil)
end
if ActualMesh then
local uh = SpecialMesh:lower()
local death = (Data.GoalSize or Size * 2)
module.Tween({
EaseStyle = Data.TweenStyle;
EaseDirection = Data.TweenDirection;
Time = Data.Time;
Object = ActualMesh;
Properties = {
Scale = (uh == "wave" and death or uh == "ring" and Vector3.new(death.X,death.X,0.1) or uh == "slash" and Vector3.new(death.X/10,0,death.X/10) or uh == "round slash" and Vector3.new(death.X/10,0,death.X/10) or death)
}
})
end
module.Tween({
EaseStyle = Data.TweenStyle;
EaseDirection = Data.TweenDirection;
Time = Data.Time;
Object = Part;
Properties = {
Transparency = Data.GoalTransparency;
Color = Data.Color;
Size = Data.GoalSize or Size * 2;
CFrame = (Data.GoalCFrame or CF) * (Data.RandomRotation and CFrame.Angles(math.random(-360,360) * rad,math.random(-360,360) * rad,math.random(-360,360) * rad) or CFrame.new());
}
})
Debris:AddItem(Part,Data.Time or 1)
end
function module.Lightning(Data : {Position1 : Vector3; Position2 : Vector3; Offset : number; Color : Color3; Time : number; LineSize : number; RandomColors : table}) -- Based off WACKYEFFECT
if not Data.Position1 or not Data.Position2 then return warn("Missing a position.") end
local Position1 = Data.Position1
local Position2 = Data.Position2
local Offset = Data.Offset or 2
local Color = Data.Color or Color3.new(1,1,1)
local Time = Data.Time or 1
local LineSize = Data.LineSize or .25
if Data.RandomColors then
Color = Data.RandomColors[math.random(1,#Data.RandomColors)]
end
local Magnitude = (Position1-Position2).Magnitude
local MagnitudeDivided = Magnitude/10
local Amount = math.round(math.clamp(MagnitudeDivided,2,30))
module.CreateEffect({
Time = Time;
CFrame = CFrame.new(Position1);
Size = Vector3.one*1.5;
GoalSize = Vector3.zero;
GoalTransparency = 0;
Color = Color;
Material = Enum.Material.Neon;
})
module.CreateEffect({
Time = Time;
CFrame = CFrame.new(Position2);
Size = Vector3.one*1.5;
GoalSize = Vector3.zero;
GoalTransparency = 0;
Color = Color;
Material = Enum.Material.Neon;
})
local CurrentPosition = Position1
for index = 1,Amount do
local ActualOffset = Vector3.new((math.random(1,2) == 1 and -Offset or Offset),(math.random(1,2) == 1 and -Offset or Offset),(math.random(1,2) == 1 and -Offset or Offset))
local RandomPosition = CFrame.new(CurrentPosition,Position2)*Vector3.new(0,0,Magnitude/Amount)+ActualOffset
local CoolSize
local CoolCFrame
if index == Amount then
local SecondMagnitude = (CurrentPosition-Position2).Magnitude
CoolSize = Vector3.new(LineSize,LineSize,SecondMagnitude)
CoolCFrame = CFrame.new(CurrentPosition,Position2)*CFrame.new(0,0,-SecondMagnitude/2)
else
CoolSize = Vector3.new(LineSize,LineSize,Magnitude/Amount)
CoolCFrame = CFrame.new(CurrentPosition,RandomPosition)*CFrame.new(0,0,Magnitude/Amount/2)
end
CurrentPosition = CoolCFrame * Vector3.new(0,0,Magnitude/Amount/2)
module.CreateEffect({
Time = Time;
CFrame = CoolCFrame;
GoalCFrame = CoolCFrame;
Size = CoolSize;
GoalSize = Vector3.new(0,0,CoolSize.Z);
GoalTransparency = 0;
Color = Color;
Material = Enum.Material.Neon;
})
end
end
return module