I have a useful function I use for VFX.
This is a multiply number sequence function that can change the size of Particle Emitters in code.
local function multnumseq(sequence,Scale)
local numberKeypoints2 = {}
for i = 1, #sequence.Keypoints do
local currKeypoint = sequence.Keypoints[i]
table.insert(numberKeypoints2, NumberSequenceKeypoint.new(currKeypoint.Time,currKeypoint.Value*Scale))
end
return NumberSequence.new(numberKeypoints2)
end
In my game one thing I did was create like 30 different ball style attacks.
Then wrote one function that handles all of them.
function dfg.Energyball(Subject,Target,Type,Damage,Scale)
local charging
local Subject=Subject
local Target=Target
local Type=Type
local Damage=Damage
local Scale=Scale
local Human=nil
if Scale==nil then Scale=1 end
local Player,Player2=nil
if Target~=nil and Subject~=nil then
Human=Subject.Parent:FindFirstChildOfClass("Humanoid")
if Human==nil then
Human=Subject.Parent.Parent:FindFirstChildOfClass("Humanoid")
end
local Angular
Player=game.Players:GetPlayerFromCharacter(Human.Parent)
local Rotate=false
if Player==nil and Target then
if Human.Parent:FindFirstChild("HumanoidRootPart"):FindFirstChildOfClass("BodyGyro")==nil then
Angular=Instance.new("BodyGyro")
Angular.CFrame=CFrame.new(Human.Parent:FindFirstChild("HumanoidRootPart").Position,Target.Position)
Angular.Parent=Human.Parent:FindFirstChild("HumanoidRootPart")
Debris:AddItem(Angular,.6)
if Human.AutoRotate==true then
Rotate=true
Human.AutoRotate=false
spawn(function() task.wait(.6) Human.AutoRotate=true end)
else Human.AutoRotate=false end
end
end
local Comp=false
local Core=Type.Parent.Core:Clone()
local EFX=Type:Clone()
--local simmodel=Instance.new("Model")
--Core.Parent=simmodel
-- Core.Parent
local w
local Speed=Type.MagicID:GetAttribute("Speed")
local DamageScript=repspell.Damage.DmgRoll:Clone()
DamageScript.Value=Damage
DamageScript.Parent=Core
local Obj=Instance.new("ObjectValue")
Obj.Value=Subject
Obj.Name="Owner"
Obj.Parent=Core
EFX.Parent=Core
Core.Size=Type.MagicID:GetAttribute("Size")
Core.CFrame=Subject.CFrame:ToWorldSpace(CFrame.new(0, 0,(-1*(Core.Size.Z/2+Subject.Size.Z/2))))
Core.Massless=true
Core.Anchored=false
Core.Parent=Subject.Parent
--simmodel:Destroy()
if Human~=nil then
if Human.Parent:FindFirstChild("UpperTorso") then
local AR=mathrandom(1,7)
local Anim=Human:LoadAnimation(script.Animations:FindFirstChild("Energyball"..AR))
Anim:Play()
task.delay(Anim.Length,function() Anim:Stop() end)
end
end
if Player then
Core:SetNetworkOwner(Player)
elseif Target then
Player2=game.Players:GetPlayerFromCharacter(Target.Parent)
if Player2 then
Core:SetNetworkOwner(Player2)
end
end
--task.delay(1.2,function() dfg.Deflect(Core) end)
---local Core2=Core:Clone()
local DamageCharacter=Core
--Core2.CanCollide=false
--Core2.CanQuery=false
--Core2.CanTouch=false
--.Anchored=true
local hittable={}
local function checktable(hit)
for i,v in pairs(hittable) do
if v==hit.Parent then
return true
end
end
return false
end
local Hits = 0
local tcon=nil tcon=Core.Touched:Connect(function(hit)
dfg.ExplosionConditions(hit,Core,Type.MagicID)
if hit.Parent~=Subject and tostring(hit.Parent)~=tostring(Subject) and hit.Parent~=Human.Parent and hit.Parent~=Core.Parent then Core.CanTouch=false
local arrow = Core
local Owner
local Character=nil
local damage
if arrow:FindFirstChild("Owner")==nil then
Owner=Instance.new("ObjectValue")
Owner.Value=arrow.Parent
end
Owner = arrow.Owner
local DMG =repspell.DMG:clone()
Debris:AddItem(DMG,7)
local humanoid = hit.Parent:findFirstChild("Humanoid")
local Protect=hit.Parent:findFirstChild("Protect")
if (humanoid~=nil and Protect~=nil) and humanoid.Parent~=Subject then
if humanoid.Parent ~= Obj.Value then
if checktable(hit)==false then
Comp=true
arrow.CanTouch=false
if game.Players:FindFirstChild(Owner.Value.Name)~=nil then
Character = game.Players:FindFirstChild(Owner.Value.Name).Character
Core.DmgRoll.Value= game.Players:FindFirstChild(Owner.Value.Name).PlayerGui.Bonus.MAG.Value
else
pcall(function() Core.DmgRoll.Value = Damage end)
end
if hit.Parent.Protect.Value ~= 2 then
if Core.DmgRoll.Value>=80 then
damage = (mathrandom(0,Core.DmgRoll.Value/1.1))
Core.DmgRoll.Value= damage
elseif Core.DmgRoll.Value<=80 then
damage = (mathrandom(0,Core.DmgRoll.Value))
Core.DmgRoll.Value= damage
end
elseif hit.Parent.Protect.Value == 2 then
if Core.DmgRoll.Value>=80 then
damage = (mathrandom(0,Core.DmgRoll.Value/3))
elseif Core.DmgRoll.Value<=80 then
damage = (mathrandom(0,Core.DmgRoll.Value/2))
end
end
if Character~=nil then
if Character:FindFirstChild("Staff") ~= nil or Character:FindFirstChild("Scythe") ~= nil or Character:FindFirstChild("ScytheX") ~= nil then
Core.DmgRoll.Value= damage+ damage*.15
damage=Core.DmgRoll.Value
end
end
damage =math.floor(damage)
dfg.DealDamage(humanoid,damage,2,hit,Type.MagicID:GetAttribute("Element"),Subject)
table.insert(hittable,hit.Parent)
--humanoid.Health = humanoid.Health - damage
--Hits = Hits + 1
--DMG.HitSplat.Hit.Text = ""..(damage)..""
-- if humanoid.Parent:FindFirstChild("Head")~=nil then
--DMG.Parent = humanoid.Parent.Head
-- else humanoid.Parent:FindFirstChild("HumanoidRootPart")
-- end
-- DMG.HitSplat.Hit.Server.Disabled = false
else
arrow.CanTouch=false
end
-- explosion = game.Lighting.Bewm:clone()
-- explosion.Position = hit.Position
-- explosion.Mesh.Scale = Vector3.new(0.25, 0.25, 0.25)
-- explosion.Parent = workspace
task.wait()
end
end
end
if Hits<1 then
Core.CanTouch=true
else tcon:Disconnect()
tcon=nil
end
end)
if (Subject) then
w = Instance.new("Weld")
w.Part0,w.Part1 = Subject,Core
w.C0 = Core.CFrame:toObjectSpace(Subject.CFrame):inverse()
w.Parent = Subject
end
for _,v in pairs(EFX:GetDescendants()) do
local v=v
if v:IsA("Sound") then
TweenSound(v)
if v.Looped==true then
spawn(function()
v.RollOffMaxDistance*=Scale
repeat task.wait(.05) until Comp==true
local goal = {}
goal.Volume = 0
local tweenInfo = TweenInfo.new(.5)
local tween = TweenService:Create(v, tweenInfo, goal)
tween:Play()
end)
end
end
if v:IsA("PointLight") then
spawn(function()
local v=v
local goal = {}
goal.Brightness = v.Brightness
goal.Range= v.Range*Scale
local tweenInfo = TweenInfo.new(2)
local tween = TweenService:Create(v, tweenInfo, goal)
v.Brightness=0
v.Range=0
tween:Play()
end)
end
if v:IsA("ParticleEmitter") then
spawn(function()
local Bubbleb=v
local PrevTrans=Bubbleb.Transparency
local Prevsize=dfg.multnumseq(Bubbleb.Size,Scale)
local Steps=15
local CSteps=0
local fram=.0333
local deftimes=Bubbleb.TimeScale
Bubbleb.TimeScale=Bubbleb.TimeScale/3
repeat
v.TimeScale=deftimes*(CSteps/5)
CSteps=CSteps+1
--local Ratio=CSteps/Steps
--local numberKeypoints2 = {
-- NumberSequenceKeypoint.new(0, 1-Ratio), -- At t=0, size of 0
-- NumberSequenceKeypoint.new(1, 1), -- At t=1, size of 10
--}
Bubbleb.Size = dfg.multnumseq(Prevsize,CSteps/15)
Bubbleb.TimeScale=deftimes*(CSteps/15)
Bubbleb.Transparency = dfg.multnumseq(PrevTrans,17/CSteps+2)
task.wait(fram)
until CSteps+2>=Steps
Bubbleb.TimeScale=deftimes
Bubbleb.Transparency=PrevTrans
Bubbleb.Size=Prevsize
local Steps=60
local CSteps=0
local fram=3/30
--local c
repeat
CSteps=CSteps+1
if Comp==true and CSteps<30 then
CSteps=30
else CSteps=CSteps+1
end
if CSteps>=45 or Comp==true then
if CSteps<45 then
CSteps=45
end
task.wait(fram)
local Ratio=CSteps/Steps
local numberKeypoints2 = {
NumberSequenceKeypoint.new(0, Ratio), -- At t=0, size of 0
NumberSequenceKeypoint.new(1, 1), -- At t=1, size of 10
}
Bubbleb.Transparency = dfg.multnumseq(PrevTrans,(CSteps-44)*1)
end
task.wait(fram)
until CSteps>=Steps
Bubbleb.Enabled=false
end)
end
end
if Target~=nil then
local goal = {}
local tweenInfo
local Tick
local tween
task.wait(.75)
local Vectir=nil
if Target then
Vectir=(Target.Position-Subject.Position).Magnitude
else
Vectir=80
end
local B=Instance.new("BodyPosition")
B.Position=Core.Position
w:Destroy()
Core.Anchored=true
if Vectir<40 and Vectir>12.5 then
tweenInfo = TweenInfo.new(Vectir/10,Enum.EasingStyle.Linear)
Tick=Vectir/10
elseif Vectir>=40 then
tweenInfo = TweenInfo.new(4,Enum.EasingStyle.Linear)
Tick=4
elseif Vectir<=12.5 then
Tick=1.25
tweenInfo = TweenInfo.new(1,Enum.EasingStyle.Linear)
end
if Vectir>8 and Target then -- follow the target
goal.Position = Target.Position
tween = TweenService:Create(B, tweenInfo, goal)
tween:Play()
spawn(function()
local Cero=0
repeat
Cero=Cero+.25
if (Target.Position-Core.Position).Magnitude<2 then
Comp=true
end
local tweenInfo
if Tick-Cero>0 then
tweenInfo=TweenInfo.new(Tick-Cero,Enum.EasingStyle.Linear)
else
tweenInfo=TweenInfo.new(.4,Enum.EasingStyle.Linear)
end
goal.Position = Target.Position
local tween2 = TweenService:Create(Core, tweenInfo, goal)
tween:Pause()
tween=tween2
tween:Play()
task.wait(.25/Speed)
until Cero>=Tick or Comp==true
Comp=true
task.wait(.6)
Core.CanTouch=false
task.wait(1.5)
if Player and Core.Parent~=nil then
Core.Anchored=false
Core:SetNetworkOwner(nil)
end
Core:Destroy()
tcon:Disconnect()
end)
else
tweenInfo = TweenInfo.new(1/Speed,Enum.EasingStyle.Linear)
goal.Position = Target.Position
local tween = TweenService:Create(B, tweenInfo, goal)
tween:Play()
tween.Completed:Wait()
Comp=true
task.wait(.6)
Core.CanTouch=false
task.wait(1.5)
if Player then
Core:SetNetworkOwner(nil)
end
Core:Destroy()
tcon:Disconnect()
--if Core2~=nil then
-- Core2:Destroy()
--end
end
end
end
end
This is definitely the way to go about creating simple and effective systems. So donāt worry! Less is more!
They also utilize this neat object that determines their behavior.