This code generates frame data for animating parts (3d vfx), its a bit of a mess but im not here for looks, this function gets called 10-100s of times per frame depending on the situation, so its important that it is as fast as possible regardless of readability.
I have spent a long time looking at this trying little things to make it faster, with very little success. It could simply be that it is as fast as it can be, however I would like to see some others take a look at it and maybe come up with a few ideas I haven’t thought of.
Currently it runs quite well on its own
but once you add many of these up it gets slow
Here’s the actual code
-- these are at the top of the script
local v3 = Vector3.new
local cf = CFrame.new
local angles = CFrame.Angles
local rad = math.rad
local clamp = math.clamp
local floor = math.floor
local c3 = Color3.new
local FrameSkip = 1 -- for adjustable frame rate of effects, used for quality settings
-- actual frame generation
Effect = function(Type: string,StartData,...)
debug.profilebegin("Generate Frames")
local newEff: BasePart = GetFromPool(Type) or Effects:FindFirstChild(Type):Clone()
if newEff then
local daCF: CFrame = StartData.CFrame
newEff.CFrame = StartData.CFrame
newEff.Transparency = StartData.Transparency1
newEff.Size = StartData.Size1
newEff.Color = StartData.Color
newEff.Material = StartData.Material or Neon
newEff.Parent = EffFolder
local Frames = {
{
StartData.CFrame,
StartData.Size1,
StartData.Transparency1,
StartData.Color
},
}
local TotalLife: number = 1
for i,Data in pairs({StartData,...}) do
debug.profilebegin("Frame Data")
local daCF = newEff.CFrame
local tr = Data.Transparency1 or 0
local siz = Data.Size1
local col = Data.Color
local Life: number = math.ceil((Data.Life or 16)/FrameSkip)
local TransparencyDif = ((Data.Transparency2 or 1) - tr)/Life
local SizeDif = ((Data.Size2 or siz) - siz)/Life
local Velocity = Data.Velocity or {0,0,0}
local Rotation = Data.Rotation or {0,0,0}
Velocity = cf(Velocity[1]/Life,Velocity[2]/Life,Velocity[3]/Life)
Rotation = CFA(Rotation[1]/Life,Rotation[2]/Life,Rotation[3]/Life)
local MoveTo = Data.MoveTo
if MoveTo then
local StartPos = newEff.CFrame.Position
local MovePos = MoveTo.Position
MoveTo = v3((MovePos.X-StartPos.X),(MovePos.Y-StartPos.Y),(MovePos.Z-StartPos.Z))/Life
end
local FirstFrame = true
local colDif
if Data.Color2 then
colDif = {(col.R-Data.Color2.R)/Life,(col.G-Data.Color2.G)/Life,(col.B-Data.Color2.B)/Life}
end
debug.profileend()
debug.profilebegin("Generate Frame "..i)
for i = TotalLife,(TotalLife-1)+Life do
local FrameData = {}
if FirstFrame then
FrameData[1] = daCF
FrameData[2] = siz
FrameData[3] = tr
FrameData[4] = col
FirstFrame = false
else
local PrevFrame = Frames[i]
FrameData[1] = PrevFrame[1]*Velocity*Rotation
FrameData[2] = PrevFrame[2]+SizeDif
FrameData[3] = PrevFrame[3]+TransparencyDif
if colDif then
local PrevCol = PrevFrame[4]
FrameData[4] = c3(clamp(PrevCol.R-colDif[1],0,1),clamp(PrevCol.G-colDif[2],0,1),clamp(PrevCol.B-colDif[3],0,1))
else
FrameData[4] = col
end
end
if MoveTo then
FrameData[1] = cf(MoveTo)*FrameData[1]
end
Frames[i+1] = FrameData
end
debug.profileend()
TotalLife+=Life
end
table.insert(EpicEffect2.ActiveEffects,{newEff,TotalLife,Frames,1})
else
warn("EpicEffect2: Effect '"..Type.."' Not Found!")
end
debug.profileend()
end
I don’t expect much can be done to make it faster, but if anyone wants to suggest optimizations I open to suggestions.