Why isn't tween Cancelling?

I have a menu gui with a camera that tweens around the map, and when i try to cancel the tween after they hit the play button. It only works if you hadn’t reached the second tween yet. Heres my script an example.

local tweenInfo = TweenInfo.new(
	65, -- Speed
	Enum.EasingStyle.Linear, -- Easing Style
	Enum.EasingDirection.Out, -- Easing Direction
	0, -- Repeat Count
	false, -- Reverse
	0 -- Delay Time

)

local function tweenCycle(tween1, tween2, tween3, tween4, endTween)
	tween1:Play()
	tween1.Completed:Wait() -- I'm thinking its something to do with the wait here? Its waiting for it to complete before it can cancel?
	tween2:Play()
	tween2.Completed:Wait()
	tween3:Play()
	tween3.Completed:Wait()
	tween4:Play()
	tween4.Completed:Wait()
	endTween:Play()
end

local tween1 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["2"].CFrame})
local tween2 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["3"].CFrame})
local tween3 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["4"].CFrame})
local tween4 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["5"].CFrame})
local endTween = tweenService:Create(camera, tweenInfo, {CFrame = cameras["1"].CFrame})

button.MouseButton1Click:Connect(function()
    tween1:Cancel()  -- It works if im on tween 1 but after that nothing gets cancelled and the camera starts moving to where the part is, then back to the player
    tween2:Cancel() -- I even tried pausing the tweens before cancelling, doesnt work
    tween3:Cancel()
    tween4:Cancel()
    endTween:Cancel()
end)

Once the player spawns in the camera starts moving out of the spawn area to the tween part, then goes back to the player straight after it reaches the tween part. Im thinking its because of the tween.Completed:Wait()

Heres a video if you dont understand what I mean.
robloxapp-20210119-1743323.wmv (1.3 MB)

well i dont see much that could be a problem, though the speed

is actally the time it takes to do the tween and not how fast it completes it. though i dont see a problem with the completed,

you may also be able to add

button.MouseButton1Click:Connect(function()
    tween1:Cancel() 
    tween1.Completed:Wait()
    tween2:Cancel()
    tween2.Completed:Wait()
    tween3:Cancel()
    tween3.Completed:Wait()
    tween4:Cancel()
    tween4.Completed:Wait()
    endTween:Cancel()
end)

though whether this would work i do not know

1 Like

Even mid way through the first tween it will stop the tween. But any other tween apart from the first one, it wont stop until it gets to the next part.

I assume :Cancel() function runs before the tween even starts to play so they don’t actually stop other tweens from carried out as normal. We can fix this by checking the PlaybackState Enum that Tween.Completed:Wait() returns:

local tweenInfo = TweenInfo.new(
	65, -- Speed
	Enum.EasingStyle.Linear, -- Easing Style
	Enum.EasingDirection.Out, -- Easing Direction
	0, -- Repeat Count
	false, -- Reverse
	0 -- Delay Time

)

local function tweenCycle(...) --Changed this to a variadic function because it's easier to use one loop and one if statement than 5 if statements for no reason.
    for Index, Tween in ipairs({...}) do
        Tween:Play()
        local TweenStatus = Tween.Completed:Wait()
        if TweenStatus == Enum.PlaybackState.Cancelled then
            return --Function stops running if one of the tweens are canceled.
        end
    end
end

local tween1 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["2"].CFrame})
local tween2 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["3"].CFrame})
local tween3 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["4"].CFrame})
local tween4 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["5"].CFrame})
local endTween = tweenService:Create(camera, tweenInfo, {CFrame = cameras["1"].CFrame})

button.MouseButton1Click:Connect(function()
    tween1:Cancel() 
    tween2:Cancel()
    tween3:Cancel()
    tween4:Cancel()
    endTween:Cancel()
end)
1 Like

Still wont work, after the 2nd tween starts playing and I press play, the camera goes to the player then it moves to the 3rd tween part and goes back to the player.

Huh. Question, do you change Camera’s cameratype at some point?

1 Like

Yes, right after I cancel the tween:

tween1:Cancel()
tween2:Cancel()
tween3:Cancel()
tween4:Cancel()
endTween:Cancel()

camera.CameraType = Enum.CameraType.Custom
camera.CameraSubject = humanoid

Interesting, it works fine for me. I used this code to test it:

local tweenService = game:GetService("TweenService")
local camera = workspace.CurrentCamera
local cameras = game.Workspace:WaitForChild("cameras")
local button = script.Parent
local tweenInfo = TweenInfo.new(
	5, -- Speed, changed it to 5 from 65 because I'm not gonna sit for a whole minute to wait one of them to get completed.
	Enum.EasingStyle.Linear, -- Easing Style
	Enum.EasingDirection.Out, -- Easing Direction
	0, -- Repeat Count
	false, -- Reverse
	0 -- Delay Time

)

local function tweenCycle(...) --Changed this to a variadic function because it's easier to use one loop and one if statement than 5 if statements for no reason.
	for Index, Tween in ipairs({...}) do
		print(Index)
		Tween:Play()
		local TweenStatus = Tween.Completed:Wait()
		if TweenStatus == Enum.PlaybackState.Cancelled then
			print("Cancelled")
			camera.CameraType = Enum.CameraType.Custom
			return --Function stops running if one of the tweens are canceled.
		end
	end
end

local tween1 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["2"].CFrame})
local tween2 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["3"].CFrame})
local tween3 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["4"].CFrame})
local tween4 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["5"].CFrame})
local endTween = tweenService:Create(camera, tweenInfo, {CFrame = cameras["1"].CFrame})

button.MouseButton1Click:Connect(function()
	tween1:Cancel() 
	tween2:Cancel()
	tween3:Cancel()
	tween4:Cancel()
	endTween:Cancel()
end)
wait(5) --I added wait so I can actually see what's wrong with this tween script.
camera.CameraType = Enum.CameraType.Scriptable
tweenCycle(tween1, tween2, tween3, tween4, endTween)

1 Like

Ill send you not the full script but all the camera stuff.

-- Camera
local camera = workspace.Camera
local cameras = game.Workspace.CAMERAS

repeat wait()
	camera.CameraType = Enum.CameraType.Scriptable
until camera.CameraType == Enum.CameraType.Scriptable
camera.CFrame = cameras["1"].CFrame

local tweenInfo = TweenInfo.new(
	65, -- Speed
	Enum.EasingStyle.Linear, -- Easing Style
	Enum.EasingDirection.Out, -- Easing Direction
	0, -- Repeat Count
	false, -- Reverse
	0 -- Delay Time

)

local function tweenCycle(tweenTable)
	for index, tween in pairs(tweenTable) do
		tween:Play()
		local tweenStatus = tween.Completed:Wait()
		if tweenStatus == Enum.TweenStatus.Canceled then
			return
		end
	end
end

local tween1 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["2"].CFrame})
local tween2 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["3"].CFrame})
local tween3 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["4"].CFrame})
local tween4 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["5"].CFrame})
local endTween = tweenService:Create(camera, tweenInfo, {CFrame = cameras["1"].CFrame})

local newTween1
local newTween2
local newTween3
local newTween4
local newEndTween

local functon openMenu()
    newTween1 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["2"].CFrame})
		newTween2 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["3"].CFrame})
		newTween3 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["4"].CFrame})
		newTween4 = tweenService:Create(camera, tweenInfo, {CFrame = cameras["5"].CFrame})
		newEndTween = tweenService:Create(camera, tweenInfo, {CFrame = cameras["1"].CFrame})

		tweenCycle({newTween1, newTween2, newTween3, newTween4, newEndTween})
end

-- Play
playButton.MouseButton1Click:Connect(function()
	if debounce == false then
		debounce = true
		
		defaultFrame:TweenPosition(UDim2.new(-1, 0, 0.102, 0), "Out", "Quad", .5)
		wait(.5)
		
		tween1:Cancel()
		tween2:Cancel()
		tween3:Cancel()
		tween4:Cancel()
		endTween:Cancel()
		
		if newTween1 then
			newTween1:Cancel()
			newTween2:Cancel()
			newTween3:Cancel()
			newTween4:Cancel()
			newEndTween:Cancel()
		end

		humanoid.WalkSpeed = 20
		humanoid.JumpPower = 50

		camera.CameraType = Enum.CameraType.Custom
		camera.CameraSubject = humanoid
		
		starterGui:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, true)
		starterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Chat, true)
		
		debounce = false
	end
end)

Btw, I do have another function that creates another tween when they exit and the menu, and press the menu button it will start tweening the camera again. Ik its not the most efficient way to do things. ( the open menu function is called when they click a button and it bassically just opens up the menu and starts doing the tweenCycle again lol )