Introducing TweenPlus - a better way to handle tweens in your game

TweenPlus

Download

TweenPlus is an extension of TweenService which allows for the creation of Tweens and TweenInfo with a string ID, which can be referenced later on to play, pause, resume, and cancel tweens. It also offers much deeper capabilities than TweenService, such as enhanced events and features. This allows for easier management of Tweens and TweenInfo objects, especially when dealing with many of these objects.


Key Features

  • Events when Tweens are canceled/completed/paused from ANY script.
  • Ability to create a queue of Tweens and make them run in a sequential order, along with events for when each specific tween is completed in the queue.
  • Ability to save Tweens and TweenInfo to be able to be used later in any other scripts.

How can I download it?

You can download and view the module using the following link:

Download


Documentation

Functions

TweenPlus:CreateTween

Allows you to create and store Tweens. For the Info parameter, you can either use a TweenInfo that you've already created and stored with a string ID, or pass through another TweenInfo object.

TweenPlus:CreateTween(TweenName, Object, Info, PropertyTable)

Parameters:

TweenName: string, Object: BasePart, Info: string | TweenInfo, PropertyTable : {}


TweenPlus:CreateInfo

Allows you to create and store TweenInfo objects.

TweenPlus:CreateInfo(InfoName, Info)

Parameters:

InfoName : string, Info : TweenInfo


TweenPlus:PlayTween

Allows you to play already created Tweens. If saveOnCompletion is false, the Tween will be destroyed after you play it.

TweenPlus:PlayTween(TweenName, saveOnCompletion)

Parameters:

TweenName : string, saveOnCompletion : boolean?


TweenPlus:PauseTween

Allows you to pause tweens that are currently running.

TweenPlus:PauseTween(TweenName,)

Parameters:

TweenName : string


TweenPlus:ResumeTween

Allows you to resume tweens that are currently paused.

TweenPlus:ResumeTween(TweenName,)

Parameters:

TweenName : string


TweenPlus:CancelTween

Cancel Tweens that have been created earlier. Note: Once cancelled, the tween can no longer be referenced and all info associated with the Tween will be deleted. (excluding any saved TweenInfo)

TweenPlus:CancelTween(TweenName,)

Parameters:

TweenName : string


TweenPlus:AddTweenToQueue

Allows you to add Tweens to a queue, which will play in order. Any other Tween events (Completed, paused, etc) will be able to be used, EXCEPT cancel.

TweenPlus:AddTweenToQueue(TweenName,)

Parameters:

TweenName : string


TweenPlus:Cleanup

Removes all Tweens, Info, etc, and anything else associated with this module and resets it.

TweenPlus:Cleanup()

Parameters:

nil

Events

TweenPlus:OnTweenCompleted

Fired when the Tween with the specific TweenName has been completed.

TweenPlus:OnTweenCompleted(TweenName, Callback)

Parameters:

TweenName: string, Callback: ( ) → ( )


TweenPlus:OnTweenPaused

Fired when the Tween with the specific TweenName has been paused.

TweenPlus:OnTweenPaused(TweenName, Callback)

Parameters:

TweenName: string, Callback: ( ) → ( )


TweenPlus:OnTweenCancelled

Fired when the Tween with the specific TweenName has been cancelled.

TweenPlus:OnTweenCancelled(TweenName, Callback)

Parameters:

TweenName: string, Callback: ( ) → ( )


Source Code
-- // Services \\
local TweenService = game:GetService("TweenService")

-- // Modules \\
local Scheduler = require(script.Scheduler)

-- // Types \\
type Tween<T> = {
	Object : BasePart,
	PropertyTable : string,
	Info : T,
}

-- // Module \\
local TweenPlus = {
	_scheduler = Scheduler.new();
	TweenData = {
		StoredInfo = {
			
		};
		StoredTweens = {
			
		}
	};
	TweenQueue = {
		
	}
}

-- // Events \\
TweenPlus._scheduler:BindCallback(function(nextTask : string)
	TweenPlus:PlayTween(nextTask)
	TweenPlus:OnTweenCompleted(nextTask, function()
		TweenPlus._scheduler:DoneHandlingTask()
	end)
end)

-- // Functions \\

function TweenPlus:CreateInfo(InfoName : string, Info : TweenInfo)
	if TweenPlus["TweenData"]["StoredInfo"][InfoName] then
		warn("TweenInfo already exists!")
	else
		TweenPlus["TweenData"]["StoredInfo"][InfoName] = Info
	end
end

function TweenPlus:CreateTween(TweenName : string, Object : BasePart, Info : TweenInfo | string, PropertyTable : {})
	if typeof(Info) == "string" then
		Info = TweenPlus["TweenData"]["StoredInfo"][Info]
		if not Info then
			error("Specified TweenInfo not found!")
		end
	elseif typeof(Info) ~= "TweenInfo" then
		error("Incorrect TweenInfo provided!")
	end
	
	if TweenPlus["TweenData"]["StoredTweens"][TweenName] then
		warn("Tween already exists!")
	else
		local TweenData : Tween = {
			Object = Object,
			PropertyTable = PropertyTable,
			Info = Info
		}
		TweenPlus[TweenName] = ""
		TweenPlus[TweenName.."_completed"] = Instance.new("BindableEvent", script)
		TweenPlus[TweenName.."_cancelled"] = Instance.new("BindableEvent", script)
		TweenPlus[TweenName.."_paused"] = Instance.new("BindableEvent", script)
		TweenPlus["TweenData"]["StoredTweens"][TweenName] = TweenData
	end
end

function TweenPlus:AddTweenToQueue(TweenName : string)
	if TweenPlus["TweenData"]["StoredTweens"][TweenName] then
		TweenPlus._scheduler:AddTask(TweenName)
		--table.insert(TweenPlus["TweenQueue"], TweenName)
	else
		error("Tween you are trying to add to queue does not exist!")
	end
end

function TweenPlus:PlayTween(TweenName : string, saveOnCompletion : boolean?)
	local Tween = TweenPlus["TweenData"]["StoredTweens"][TweenName]
	local Info
	if Tween then
		if typeof(Tween["Info"]) == "string" then
			Info = TweenPlus["TweenData"]["StoredInfo"][Tween["Info"]]
		else
			Info = Tween["Info"]
		end
		
		if Info then
			TweenPlus[TweenName] = TweenService:Create(Tween["Object"], Info, Tween["PropertyTable"])
			TweenPlus[TweenName]:Play()
			
			
			TweenPlus[TweenName].Completed:Connect(function()
				if saveOnCompletion == false then
					TweenPlus[TweenName.."_completed"]:Fire()
					TweenPlus[TweenName] = nil
					TweenPlus[TweenName.."_cancelled"] = nil
					TweenPlus[TweenName.."_completed"] = nil
					TweenPlus[TweenName.."_paused"] = nil
					TweenPlus["TweenData"]["StoredTweens"][TweenName] = nil
				end
			end)
		else
			error("Saved TweenInfo not found!")
		end
	else
		error("Saved Tween not found!")
	end
end

function TweenPlus:PauseTween(TweenName : string)
	if TweenPlus[TweenName] then
		TweenPlus[TweenName.."_paused"]:Fire()
		TweenPlus[TweenName]:Pause()
	else
		error("Error pausing tween: Tween you are trying to pause not found!")
	end
end

function TweenPlus:OnTweenCancelled(TweenName : string, Callback : () -> ())
	if TweenPlus[TweenName] then
		TweenPlus[TweenName.."_cancelled"].Event:Connect(Callback)
	else
		error("Error getting TweenCancelled event: Tween you are trying to reference not found!")
	end
end

function TweenPlus:OnTweenCompleted(TweenName : string, Callback : () -> ())
	if TweenPlus[TweenName] then
		TweenPlus[TweenName.."_completed"].Event:Connect(Callback)
	else
		error("Error getting TweenCompleted event: Tween you are trying to reference not found!")
	end
end

function TweenPlus:OnTweenPaused(TweenName : string, Callback : () -> ())
	if TweenPlus[TweenName] then
		TweenPlus[TweenName.."_paused"].Event:Connect(Callback)
	else
		error("Error getting TweenPaused event: Tween you are trying to pause not found!")
	end
end

function TweenPlus:ResumeTween(TweenName : string)
	if TweenPlus[TweenName] then
		TweenPlus[TweenName]:Play()
	else
		error("Error resuming Tween: Tween you are trying to resume not found!")
	end
end

function TweenPlus:CancelTween(TweenName : string)
	if TweenPlus[TweenName] then
		TweenPlus[TweenName]:Cancel()
		TweenPlus[TweenName.."_cancelled"]:Fire()
		TweenPlus[TweenName] = nil
		TweenPlus[TweenName.."_cancelled"] = nil
		TweenPlus[TweenName.."_completed"] = nil
		TweenPlus[TweenName.."_paused"] = nil
		TweenPlus["TweenData"]["StoredTweens"][TweenName] = nil
	else
		error("Error cancelling Tween: Tween you are trying to cancel not found!")
	end
end

function TweenPlus:Cleanup()
	for _, Tween in pairs(TweenPlus["TweenData"]["StoredTweens"]) do
		Tween:Cancel()
		Tween = nil
	end
	TweenPlus["TweenQueue"] = {}
	TweenPlus["TweenData"]["StoredTweens"] = {}
	TweenPlus["TweenData"]["StoredInfo"] = {}
	TweenPlus._scheduler:Destroy()
	for i, v in pairs(TweenPlus) do
		if typeof(v) == "function" or table.find({"TweenQueue", "TweenData", "_scheduler"}, i) then
			continue
		end
		
		TweenPlus[i] = nil
	end
end

return TweenPlus

If you have any questions at all about this module, please do not hesitate to reply to this thread. Thank you for reading!

11 Likes

Thanks man! Let me know if you’d like to see any changes or improvements to this!

Nice module dude, tween has always been problematic