UIAnimator: Devlog (Effects & UI Effect Manager) WIP

So, recently(today), I have started on an new project, an open source module to manage UIAnimations and Effects. I have created typechecking, and two effects: Float On Hover, and Fade.

Features:

  • Manageable Effects, easy to use and delete to clear up memory
  • Full Typechecking
  • UI sounds, instant cleanup for sounds

Upcoming Features

  • Easy to plan out ui animations(move the ui to one place, click an button on an plugin, etc)
  • An easy UIBlur implementation
  • Auto Setup for UIDragDetectors
  • Loading screen animations
  • Lots of new effects

Here is the current Module:

--!strict
local UIAnimatorClass = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
UIAnimatorClass.__index = UIAnimatorClass
local UIEffects = {}
UIEffects.__index = UIEffects

export type UIEffect = {
	connection1: RBXScriptConnection,
	connection2: RBXScriptConnection,
	connection3: RBXScriptConnection,
	connection4: RBXScriptConnection,
	name: string,
	effect: string,
	guiObject: GuiObject,
	effectPMS: {},
    Destroy: (self:UIEffect) -> nil
}

export type HoverPM = {
	hoverOffset: number,
	sound: Sound,
	floatTime: number,
}

export type FadePM = {
    fadeTime:number,
    visibility:"visible"|"invisible"
}


export type UIAnimator = {
	guiObject: GuiObject,
	state: string,
	create: (guiObject: GuiObject) -> UIAnimator,
	effects: {},
	runningEffect: nil | UIEffect,
	passiveEffect: nil | UIEffect,
}

export type UIAnimatorClass = {
	create: (guiObject: GuiObject) -> UIAnimator,
}

function UIEffects.create(name, effectName, guiObject, effectPMS: FadePM & HoverPM) --add anyother effect in here for typing
	local self: UIEffect = setmetatable({}, UIEffects) :: any
	self.name = name
	self.effect = effectName
	self.effectPMS = effectPMS
	self.guiObject = guiObject
    
	if effectName == "floatHover" then
		local hoverTween
		self.connection1 = self.guiObject.MouseEnter:Connect(function()
			local goal =
				{ guiObject.Position + UDim2.new(0, 0, guiObject.Position.Y.Scale + effectPMS["hoverOffset"], 0) }
			local TweenInfo = TweenInfo.new(effectPMS["floatTime"], Enum.EasingStyle.Sine)
			hoverTween = TweenService:Create(guiObject, TweenInfo, goal)
			hoverTween:Play()
			local soundClone = effectPMS["sound"]:Clone()
			soundClone.PlayOnRemove = true
			soundClone:Destroy()
		end)
		self.connection2 = self.guiObject.MouseLeave:Connect(function()
			if hoverTween then
				hoverTween:Cancel()
			end
			local goal =
				{ guiObject.Position + UDim2.new(0, 0, guiObject.Position.Y.Scale - effectPMS["hoverOffset"], 0) }
			local TweenInfo = TweenInfo.new(effectPMS["floatTime"], Enum.EasingStyle.Sine)
			hoverTween = TweenService:Create(guiObject, TweenInfo, goal)
			hoverTween:Play()
		end)
	end
    if effectName == "fade" then
        local tweenInfo = TweenInfo.new(effectPMS.fadeTime, Enum.EasingStyle.Sine)
        local goal:{}
        if  effectPMS.visibility == "invisible" then
            goal = {BackgroundTransparency = 1}
        end
        if effectPMS.visibility == "visible" then
            goal = {BackgroundTransparency = 0}
        end
        local MainTween = TweenService:Create(guiObject, tweenInfo, goal)
        MainTween:Play()
        for _, child:GuiObject | Instance in pairs(guiObject:GetDescendants()) do
            if child:IsA("GuiObject") then
                local newTween = TweenService:Create(child, tweenInfo, goal)
                newTween:Play()
            end
            --TODO ADD TEXT TRANSPARENCY
        end
        self.connection1 = MainTween.Completed:Wait()
    end
	return self
end

function UIEffects.Destroy(self: UIEffect)
	if self.connection1 then
		self.connection1:Disconnect()
	end
	if self.connection2 then
		self.connection2:Disconnect()
	end
	if self.connection3 then
		self.connection3:Disconnect()
	end
	if self.connection4 then
		self.connection4:Disconnect()
	end
end

function UIAnimatorClass.create(guiObject: GuiObject): UIAnimator
	local self: UIAnimator = setmetatable({}, UIAnimatorClass) :: any
	self.guiObject = guiObject
	self.state = "visible"
	self.effects = {}
	self.runningEffect = nil
	return self
end

function UIAnimatorClass.addEffect(self: UIAnimator, effect, name, effectPM)
	local RunningEffects = self.effects
	local neweffect = UIEffects.create(name, effect, self.guiObject, effectPM)
	table.insert(RunningEffects, neweffect)
end

function UIAnimatorClass.runEffect(self: UIAnimator, name): UIEffect
	for _, effect: UIEffect in self.effects :: any do
		if effect.name == name then
            self.runningEffect = effect
			return effect
		end
	end
	return nil :: any
end

function UIAnimatorClass.runPassiveEffect(self:UIAnimator, name): UIEffect
    for _, effect: UIEffect in self.effects :: any do
		if effect.name == name then
            self.passiveEffect = effect
			return effect
		end
	end
	return nil :: any
end

function UIAnimatorClass.clearRunEffect(self:UIAnimator)
    local effect:UIEffect = self.runningEffect::UIEffect
    effect:Destroy()
end

function UIAnimatorClass.clearPassiveEffect(self:UIAnimator)
    local effect:UIEffect = self.passiveEffect::UIEffect
    effect:Destroy()
end

return UIAnimatorClass

3 Likes