Callback runs even if Tween isn't finished

Dig gets fired everytime the player clicks, if I click to fast or unequip the tool mid twin it bypasses the tween.

local function callback()
	ToolGui.ProgressFrame.Visible = false
	ToolGui.ProgressFrame.Progress.Size = UDim2.new(0,0,1,0)
	Progressing = false
	print(PlacetoPlace)
	if Digmode == false and script.Parent.Selected.Value ~= nil then
		local clone = script.Parent.Selected.Value:Clone()
		clone.Parent = Maginot.Configuration.ParentFortsTo.Value
		if script.Parent.Selected.Value.Configuration.Overlap.Value == true then
			clone:TranslateBy(PlacetoPlace)
		elseif script.Parent.Selected.Value.Configuration.Overlap.Value == false then
			clone:MoveTo(PlacetoPlace)
		end
		
		local rotation = CFrame.Angles(0, math.rad(player.Character.HumanoidRootPart.Orientation.Y), 0)
		local modelCFrame = clone:GetPrimaryPartCFrame()

		clone:SetPrimaryPartCFrame( modelCFrame * rotation )
	else
		print(HitObject)
		local ModelToFind = HitObject:FindFirstAncestorWhichIsA("Model")
		print(HitObject)
		if HitObject == workspace.Terrain then
			game.Workspace.Terrain:FillBall(PlacetoPlace,Maginot.Configuration.DigRadiusStuds.Value,Enum.Material.Air)
		else
			ModelToFind:FindFirstChild("Configuration",true).HP.Value -= script.Parent.Configuration.EmplacementDamage.Value

		end
	end
end
function ProgressIncrease(waittime)
	ToolGui.ProgressFrame.Visible = true

	ToolGui.ProgressFrame.Progress:TweenSize(
		UDim2.new(1,0,1,0),
		Enum.EasingDirection.Out,    -- easingDirection (default Out)
		Enum.EasingStyle.Quad,      -- easingStyle (default Quad)
		waittime,                          -- time (default: 1)
		true,                  -- should this tween override ones in-progress? (default: false)
		callback)
end
script.Parent.Events.ChangeMode.OnServerEvent:Connect(function()
	--if anim.IsPlaying then
	--	callback()
	--end
	if Digmode == false then 
		Digmode = true
		ToolGui.Mode.Text = "Mode: Dig"
	else
		Digmode = false
		ToolGui.Mode.Text = "Mode: Build"
	end
end)
script.Parent.Events.Dig.OnServerEvent:Connect(function(plr,position,target)
	print('fired')
	PlacetoPlace = position
	HitObject = target
	anim = script.Parent.Parent.Humanoid:LoadAnimation(script.Parent.Anims.Dig)
	Progressing = true
	print(script.Parent.Selected.Value)
	spawn(function()
		while Progressing == true do
			anim:Play()
			wait(1)
		end
	end)
	if Digmode == false then
		if script.Parent.Selected.Value == nil then
			
		else
			local Fort = require(game.ReplicatedStorage.Maginot.Class.Fortification)
			Selected = Fort(script.Parent.Selected.Value)
			ProgressIncrease(Selected.BuildTime)
		end
		
	elseif Digmode == true then
		ProgressIncrease(Maginot.Configuration.DigTime.Value)
	end
end)
1 Like

checked the api reference, tweensize lets you give it a callback
https://developer.roblox.com/en-us/api-reference/function/GuiObject/TweenSize

Oh that’s nice, never noticed it before. Good to know.

1 Like

I am using the callback, you can glitch out the callback.

use TweenService for tweens and do this

Tween.Completed:Wait();
callback();

I am, look at my code.
[character limit]

you are not.


rework this part using tweenservice

forgot to switch the direction and style lol

same problem

local function callback()
	if Equipped == true then
		print(Equipped)
		ToolGui.ProgressFrame.Visible = false
		ToolGui.ProgressFrame.Progress.Size = UDim2.new(0,0,1,0)
		Progressing = false
		print(PlacetoPlace)
		if Digmode == false and script.Parent.Selected.Value ~= nil then
			local clone = script.Parent.Selected.Value:Clone()
			clone.Parent = Maginot.Configuration.ParentFortsTo.Value
			if script.Parent.Selected.Value.Configuration.Overlap.Value == true then
				clone:TranslateBy(PlacetoPlace)
			elseif script.Parent.Selected.Value.Configuration.Overlap.Value == false then
				clone:MoveTo(PlacetoPlace)
			end
			
			local rotation = CFrame.Angles(0, math.rad(player.Character.HumanoidRootPart.Orientation.Y), 0)
			local modelCFrame = clone:GetPrimaryPartCFrame()

			clone:SetPrimaryPartCFrame( modelCFrame * rotation )
		else
			print(HitObject)
			local ModelToFind = HitObject:FindFirstAncestorWhichIsA("Model")
			print(HitObject)
			if HitObject == workspace.Terrain then
				game.Workspace.Terrain:FillBall(PlacetoPlace,Maginot.Configuration.DigRadiusStuds.Value,Enum.Material.Air)
			else
				ModelToFind:FindFirstChild("Configuration",true).HP.Value -= script.Parent.Configuration.EmplacementDamage.Value

			end
		end
	end
end
function ProgressIncrease(waittime)
	ToolGui.ProgressFrame.Visible = true
	local tweenInfo = TweenInfo.new(
		waittime,
		Enum.EasingStyle.Quad,    -- easingDirection (default Out)
		Enum.EasingDirection.Out,      -- easingStyle (default Quad)
		0,                          -- time (default: 1)
		false,                  -- should this tween override ones in-progress? (default: false)
		0)
	local goal = {}
	goal.Size = UDim2.new(1, 0, 1,0)
	local Tween = TweenService:Create(ToolGui.ProgressFrame.Progress,tweenInfo,goal)
	Tween:Play()
	Tween.Completed:Wait()
	callback()
end

oh lol I just read your issue again

this happens because u don’t have a debounce on server event

How should I go about implementing this?

local debounce = false;
local function callback()
	ToolGui.ProgressFrame.Visible = false
	ToolGui.ProgressFrame.Progress.Size = UDim2.new(0,0,1,0)
	Progressing = false
	print(PlacetoPlace)
	if Digmode == false and script.Parent.Selected.Value ~= nil then
		local clone = script.Parent.Selected.Value:Clone()
		clone.Parent = Maginot.Configuration.ParentFortsTo.Value
		if script.Parent.Selected.Value.Configuration.Overlap.Value == true then
			clone:TranslateBy(PlacetoPlace)
		elseif script.Parent.Selected.Value.Configuration.Overlap.Value == false then
			clone:MoveTo(PlacetoPlace)
		end

		local rotation = CFrame.Angles(0, math.rad(player.Character.HumanoidRootPart.Orientation.Y), 0)
		local modelCFrame = clone:GetPrimaryPartCFrame()

		clone:SetPrimaryPartCFrame( modelCFrame * rotation )
	else
		print(HitObject)
		local ModelToFind = HitObject:FindFirstAncestorWhichIsA("Model")
		print(HitObject)
		if HitObject == workspace.Terrain then
			game.Workspace.Terrain:FillBall(PlacetoPlace,Maginot.Configuration.DigRadiusStuds.Value,Enum.Material.Air)
		else
			ModelToFind:FindFirstChild("Configuration",true).HP.Value -= script.Parent.Configuration.EmplacementDamage.Value

		end
	end
	debounce = false;
end
function ProgressIncrease(waittime)
	ToolGui.ProgressFrame.Visible = true

	ToolGui.ProgressFrame.Progress:TweenSize(
		UDim2.new(1,0,1,0),
		Enum.EasingDirection.Out,    -- easingDirection (default Out)
		Enum.EasingStyle.Quad,      -- easingStyle (default Quad)
		waittime,                          -- time (default: 1)
		true,                  -- should this tween override ones in-progress? (default: false)
		callback)
end
script.Parent.Events.ChangeMode.OnServerEvent:Connect(function()
	--if anim.IsPlaying then
	--	callback()
	--end
	if Digmode == false then 
		Digmode = true
		ToolGui.Mode.Text = "Mode: Dig"
	else
		Digmode = false
		ToolGui.Mode.Text = "Mode: Build"
	end
end)

script.Parent.Events.Dig.OnServerEvent:Connect(function(plr,position,target)
	if debounce then
		return
	end; debounce = true;
	
	print('fired')
	PlacetoPlace = position
	HitObject = target
	anim = script.Parent.Parent.Humanoid:LoadAnimation(script.Parent.Anims.Dig)
	Progressing = true
	print(script.Parent.Selected.Value)
	spawn(function()
		while Progressing == true do
			anim:Play()
			wait(1)
		end
	end)
	if Digmode == false then
		if script.Parent.Selected.Value == nil then

		else
			local Fort = require(game.ReplicatedStorage.Maginot.Class.Fortification)
			Selected = Fort(script.Parent.Selected.Value)
			ProgressIncrease(Selected.BuildTime)
		end

	elseif Digmode == true then
		ProgressIncrease(Maginot.Configuration.DigTime.Value)
	end
end)
1 Like

sometimes when I unequip it still runs callback but that’s okay

Additionally, it demonstrates how the callback parameter can be used to detect when the tween stops (whether it was cancelled by another tween or completed).

I’ve noticed that you’ve omitted this parameter in your tween’s callback, further demonstration of its use can be found here.

The parameter represents a ‘TweenStatus’ enumeration item, ‘Enum.TweenStatus.Completed’ represents a tween which was completed and ‘Enum.TweenStatus.Canceled’ represents a tween which was canceled. You should be using this in order to determine the state of a finished tween.