I just finished making a system that takes in a sequence of tweens on the server side, calculates the tweens, plays them on the client side, and then makes sure they completed on the server, and it is pretty disorganized and complex. Serverside module:
local EntranceRoomModule = {}
--INFO--
--Written: false--
--Optimized: false--
--Organized: false--
--VARIABLES--
--Services--
local tS = game:GetService("TweenService")
--Metatables--
local EntranceRoomMetatable = {}
--Objects--
--Values--
--Events--
local animateSequenceEvent = game.ReplicatedStorage.OtherEvents.AnimateSequenceEvent
--Animations--
local doorAnimations = {
["standard"] = {
},
["advanced"] = {
{0, 3, 2.5, 2.75, CFrame.Angles(0, 0, math.rad(90)), true},
{0, 0, 2.5, 2.75, CFrame.Angles(0, 0, math.rad(-90)), true},
{0, 0, 2.5, 2.75, CFrame.Angles(0, 0, math.rad(90)), true},
{3, 0, 2.5, 2.75, CFrame.Angles(0, 0, math.rad(-90)), true},
{0, 5.5, 5, 5.25, CFrame.new(12, 0, 0), false},
{5.5, 0, 5, 5.25, CFrame.new(-12, 0, 0), false},
},
["magnetized"] = {
},
["advancedMagnetized"] = {
}
}
--FUNCTIONS--
--EntranceRoomMetatable--
--EntranceRoomModule--
function EntranceRoomModule.AnimateDoor(doorType : string, direction : boolean, parts : {})
for index = direction and 1 or table.maxn(doorAnimations[doorType]), direction and table.maxn(doorAnimations[doorType]) or 1, direction and 1 or -1 do
local animation = {}
local animationInfo = doorAnimations[doorType][index]
local tweenInstance = parts[index]
local tweenInfo = {animationInfo[3], Enum.EasingStyle.Quart, Enum.EasingDirection.InOut, 0, false, 0}
local tweenDestination = {CFrame = tweenInstance:GetPivot() * (direction and animationInfo[5] or animationInfo[5]:Inverse())}
table.insert(animation, tweenInstance)
table.insert(animation, tweenInfo)
table.insert(animation, tweenDestination)
table.insert(animation, {})
if animationInfo[6] then
table.insert(animation[4], true)
end
animateSequenceEvent:FireAllClients(animation)
local timeOne = direction and animationInfo[1] or animationInfo[2]
local timeTwo = animationInfo[3]
task.delay(timeTwo - math.clamp(timeTwo - animation[2][1], 0, math.abs(timeTwo - animation[2][1])) / 2, function()
for propertyIndex, destination in animation[3] do
if propertyIndex == "CFrame" then
if animation[4][1] then
animation[1].Anchored = true
animation[1].WeldConstraint:Destroy()
end
end
animation[1][propertyIndex] = destination
if propertyIndex == "CFrame" then
if animation[4][1] then
local newWeld = Instance.new("WeldConstraint")
newWeld.Part0 = animation[1].Parent.PrimaryPart
newWeld.Part1 = animation[1]
newWeld.Parent = animation[1]
animation[1].Anchored = false
end
end
end
end)
if timeOne > 0 then
task.wait(timeOne)
end
end
end
return EntranceRoomModule
The remote event passes info the the clientside animation function.
Clientside module:
--INFO--
--Written: false--
--Optimized: false--
--Organized: false--
--VARIABLES--
--Services--
local tS = game:GetService("TweenService")
--Metatables--
local ClientEffectsMetatable = {}
--Objects--
--Values--
--FUNCTIONS--
--EntranceRoomMetatable--
--EntranceRoomModule--
function ClientEffectsModule.AnimateObject(animation : {})
local tweenInstance : BasePart = animation[1]
if animation[4][1] then
tweenInstance.Anchored = true
tweenInstance.WeldConstraint:Destroy()
end
local tweenInfo : TweenInfo = TweenInfo.new(animation[2][1], animation[2][2], animation[2][3], animation[2][4], animation[2][5], animation[2][6])
local tweenDestination = animation[3]
tS:Create(tweenInstance, tweenInfo, tweenDestination):Play()
if animation[4][1] then
task.wait(tweenInfo.Time)
local newWeld = Instance.new("WeldConstraint")
newWeld.Part0 = tweenInstance.Parent.PrimaryPart
newWeld.Part1 = tweenInstance
newWeld.Parent = tweenInstance
tweenInstance.Anchored = false
end
end
function ClientEffectsModule.AnimateParticles()
end
return ClientEffectsModule
Any tips on how I could optimize this would be much appreciated.