So I made this module a couple of days ago, and it was very useful to me.
I don’t know if this is optimized, since I made it.
But I use it alot so I thought I could share it here, you may copy it if use want, I’ll also post a quick guide on how to use the functions.
module:
local Global = {}
local TS = game:GetService("TweenService")
Global.__schedules = {}
Global.__checkers = {}
Global.__MultiAnimations = {}
function Global.After(exe : (...any) -> ...any, aexe : (...any) -> ...any, pause : number, exeArgs : {any}, aexeArgs : {any}) : (boolean, any)
local result, errormsg = pcall(function()
local res1 = exe(table.unpack(exeArgs))
task.wait(pause)
local res2 = aexe(table.unpack(aexeArgs))
return res1, res2
end)
return result, errormsg
end
function Global.CreateMultiAnimation(animName : string,property : string, defaultInfo : TweenInfo, ...)
local anim = {}
anim["Property"] = property
local tweenInfos = {}
for i,v in pairs(table.pack(...)) do--round one
if typeof(v) ~= "TweenInfo" then continue end
table.insert(tweenInfos, v)
end
local curIndex = 1
for i,v in pairs(table.pack(...)) do-- round two
if typeof(v) == "TweenInfo" then continue end
local keyframe = {}
keyframe["Info"] = tweenInfos[curIndex] or defaultInfo
keyframe["Value"] = v
table.insert(anim, keyframe)
curIndex += 1
end
Global.__MultiAnimations[animName] = anim
end
function Global.RunMultiAnimation(animName : string, obj : Instance, repeats : number, reverse : boolean)
local anim = Global.__MultiAnimations[animName]
if not anim then return false end
for i = 0, repeats or 1 do
for i, v in pairs(anim) do
if i == "Property" then continue end
if obj[anim["Property"]] and (typeof(obj[anim["Property"]]) ~= typeof(v["Value"])) then continue end
local tweenSettings = {}
tweenSettings[anim["Property"]] = v["Value"]
local tween = TS:Create(obj, v["Info"], tweenSettings)
tween:Play()
tween.Completed:Wait()
end
if not reverse then continue end
local property = anim["Property"]
local reversearr = Global.ReverseArr(table.clone(anim))
for i,v in pairs(reversearr) do
if obj[anim["Property"]] and (typeof(obj[anim["Property"]]) ~= typeof(v["Value"])) then continue end
local tweenSettings = {}
tweenSettings[anim["Property"]] = v["Value"]
local tween = TS:Create(obj, v["Info"], tweenSettings)
tween:Play()
tween.Completed:Wait()
end
end
end
function Global.ReverseArr(arr) : {any}
local i, j = 1, #arr
while i < j do
arr[i], arr[j] = arr[j], arr[i]
i = i + 1
j = j - 1
end
return arr
end
function Global.CreateChecker(checkerName : string)
local checker = {}
Global.__checkers[checkerName] = checker
end
function Global.AddCase(checkerName : string, value : any, exe : (...any) -> ...any, ...)
local checker = Global.__checkers[checkerName]
if not checker then return false end
checker[value] = {Function = exe, Arguments = table.pack(...)}
return true
end
function Global.Check(checkerName : string, obj : any, removeAfter : boolean)
local checker = Global.__checkers[checkerName]
if not checker then return false end
local result = nil
local hasRan = false
for i,v in pairs(checker) do
if i ~= obj then continue end
result = v["Function"](table.unpack(v["Arguments"]))
hasRan = true
break
end
if removeAfter then Global.__checkers[checkerName] = nil end
if not hasRan then
if not checker["default"] then return false, nil end
result = checker["default"]["Function"](table.unpack(checker["default"]["Arguments"]))
return true, result
else return true, result
end
end
function Global.Uncheck(checkerName : string)
if not Global.__checkers[checkerName] then return end
Global.__checkers[checkerName] = nil
end
function Global.RemoveSchedule(scheduleName : string)
if not Global.__schedules[scheduleName] then return end
Global.__schedules[scheduleName] = nil
end
function Global.CreateSchedule(scheduleName : string)
local schedule = {}
Global.__schedules[scheduleName] = schedule
end
function Global.AddFunc(scheduleName : string, exe : (...any) -> ...any, pause : number, ...)
local schedule = Global.__schedules[scheduleName]
if not schedule then return false end
local funcdesc = {Function = exe, Arguments = table.pack(...), Pause = pause}
table.insert(schedule, funcdesc)
return true
end
function Global.AddFuncs(scheduleName : string, ...)
local schedule = Global.__schedules[scheduleName]
if not schedule then return false end
local funcArgs = {}
local args = {}
for i,v in pairs(table.pack(...)) do--Pass one
if typeof(v) == "function" then
if i == 1 then continue end
table.insert(funcArgs, table.clone(args))
table.clear(args)
continue
end
table.insert(args, v)
end
table.insert(funcArgs, args)
local curIndex = 1
for i,v in pairs(table.pack(...)) do--Pass two
if typeof(v) ~= "function" then continue end
local ourArgs = funcArgs[curIndex]
local possiblePause = ourArgs[1]
if typeof(possiblePause) == "number" then
table.remove(ourArgs, 1)--remove to use this num as wait time.
else
possiblePause = 1--set default value
end
local funcDesc = {Function = v, Arguments = ourArgs, Pause = possiblePause}
table.insert(schedule, funcDesc)
curIndex += 1
end
return true
end
function Global.TO(condition : boolean, obj1, obj2)--TO: Terinary Operator
if condition then return obj1 end
return obj2
end
function Global.Run(scheduleName : string, removeAfter : boolean) : {any}
local schedule = Global.__schedules[scheduleName]
if not schedule then return false end
local results = {}
for i,v in pairs(schedule) do
local resuls, errormsg = pcall(function()
return v["Function"](table.unpack(v["Arguments"]))
end)
task.wait(v["Pause"])
if not resuls then print(errormsg) continue end
table.insert(results, errormsg)
end
if removeAfter then
Global.__schedules[scheduleName] = nil
end
return results
end
return Global
so this is a handful I know but I’ll go over it okay.
so the first few lines are storage tables and the module itself.
Just ignore, they aren’t part of the module’s exposed members. (as indicated by the double underscore naming convention)
the first function is called After
it needs two functions exe
and aexe
, followed by a parameter which indicates how much time to wait between the two calls, then two arrays containing the arguments for both functions,
it runs both functions one after the other with the specified time in between, and returns the result, it also logs any errors that occurred during execution.
the next one is CreateMultiAnimation
which needs a name for the animation (for later access), the property that needs to be modified , a default tweeninfo when there aren’t enough tweeninfos. and then a collection of tweeninfos and values.
the tweeninfos are going to be combined with the value to create a keyframe, which then will be added to the animation and saved to __MultiAnimations.
then its close relative RunMultiAnimation
will go over each keyframe and animate it with tweenservice, this way you can create animations that consist of multiple goal values.
example usage:
local GlobalFuncs = require(your location) -- placeholder
GlobalFuncs.CreateMultiAnimation("CoolAnim", "Color", uiMovementInfo,
Color3.fromRGB(255, 0, 0), --this works since it implicitly uses the default value
Color3.fromRGB(255, 170, 0),-- but you can pass a tweeninfo if you want...
Color3.fromRGB(255, 255, 127),
Color3.fromRGB(85, 255, 127),
Color3.fromRGB(0, 170, 255),
Color3.fromRGB(0, 85, 255),
Color3.fromRGB(170, 0, 255)
)
GlobalFuncs.RunMultiAnimation("CoolAnim", workspace.Part, 15, true)--run it 15 times in reverse to
--get a cool rainbow animation!
here is a video of me looking at the animation:
so the next function in the module is reverseArr
, a much needed one.
This should be in the std of lua, I don’t know why this doesn’t exist, but it reverses the order of an array (not a dictionary, they don’t have an order)
next up is CreateChecker
, now I called it checker because it basically checks for equality, but you might know it from other languages under the name: The Switch Statement.
this function creates a switch statement with the given name (for later access).
then you can add cases to it using AddCase
which needs the name of the checker, the value to check and any function to run, after that you can specify any arguments but that isn’t required for most statements.
then you can call Check
with an object, and it will run the function under the case that matches the object.
if none match it checks for a default case, and quits if there are none.
But if there is a default case, which you can add by saying: AddCase("Your Checker", "default", your func, your args)
it will run the default case instead.
example usage:
local Global = require(PlaceholderLocation)--replace with module loc.
Global.CreateChecker("test")
Global.AddCase("test", 1, print, "it is 1")
Global.AddCase("test", 2, print, "it is 2")
Global.AddCase("test", 3, print, "3rd time is the charm")
Global.AddCase("test", "default", print, "no matches? *mega mind meme*")
Global.Check("test", 2, false)--will print it is 1
Global.Check("test", 8, false)-- will print no matches? *mega mind meme*
Global.Check("test", 3, true)-- will print 3rd time is the charm
Global.Check("test", 5, true)--will error because the checker got removed in the last call
--because args are Check(name, value, remove?)
Then there’s Uncheck
which is the evil twin brother, because it removes a check statement from the storage.
it requires the name of the checker
There is RemoveSchedule
which removes a schedule from the storage.
It needs the name of the schedule.
there is CreateSchedule
which creates a schedule, a schedule is a list of functions which will be called from top to bottom with the given wait time in between and the given arguments, (so basically After
but better)
you can add one function using AddFunc
which needs the schedule name, the function, wait time before calling the next function, and a collection of arguments.
it adds one function to the schedule.
Then there’s AddFuncs
which adds a range of different functions to the schedule, all with their own wait time and arguments, in a specific order.
the order is: function, (optional) waittime, (optional) args, next function, etc…
if no wait time is given it will default to 1
then you can run the schedule using Run
which will call each function in order, with the wait time from addfunc or addfuncs in between.
example usage:
local mod = require(module location)
mod.CreateSchedule("test")
mod.AddFuncs(
print,--no wait time given, so it uses 1
"Hello",
print,
5,--wait time given, it uses 5
"hi",
print,
5,-- wait time given, it uses 5
10,--this will not be used as wait time, because 5 got chosen,
--so this will be passed to print
"hello",
"hey",
print,--defaults to 1
"done"
)
--you can then run your schedule as many times as you want,
mod.Run("test", false)
mod.Run("test", false)
mod.Run("test", true)--until you remove it, then it dies.
and then the very last function is TO
, which stands for Ternary Operator, you know… the:
Type name = condition ? object1 : object2;
from other languages.
it needs a condition, and two object,s and it will pick one based on the condition.
That’s all I guess…
I’ve never posted a resource before, feel free to give criticism and your opinions.
Bye!