Tweens bugged (solution found)?

These are doors for spawners, but over time, they get bugged . They spawn zombies but even on the first wave, they somehow fly out despite not being selected twice in a row. Is it just me or is tweenservice bugged?

Code that creates tweens + first wave of spawning enemies (do note that the spawners go into the ground which counts as opening)

local function getspawn(npcchosen)
	
	
	

			if npcchosen.Humanoid.Health < (20000 * game.ServerStorage.Values.DifficultyHealth.Value) then -- normal zombie spawn
			local randomspawn = math.random(1,20)
			local base = game.Workspace.AttackerBase
			if randomspawn == 1 then
				npcspawn = base["Zombie Spawner1"]
			end
			if randomspawn == 2 then
				npcspawn = base["Zombie Spawner2"]
			end
			if randomspawn == 3 then
				npcspawn = base["Zombie Spawner3"]
			end
			if randomspawn == 4 then
				npcspawn = base["Zombie Spawner4"]
			end
			if randomspawn == 5 then
				npcspawn = base["Zombie Spawner5"]
			end
			if randomspawn == 6 then
				npcspawn = base["Zombie Spawner6"]
			end
			if randomspawn == 7 then
				npcspawn = base["Zombie Spawner7"]
			end
			if randomspawn == 8 then
				npcspawn = base["Zombie Spawner8"]
			end
			if randomspawn == 9 then
				npcspawn = base["Zombie Spawner9"]
			end
			if randomspawn == 10 then
				npcspawn = base["Zombie Spawner10"]
			end
			if randomspawn == 11 then
				npcspawn = base["Zombie Spawner11"]
			end
			if randomspawn == 12 then
				npcspawn = base["Zombie Spawner12"]		
			end
			if randomspawn == 13 then
				npcspawn = base["Zombie Spawner13"]
			end
			if randomspawn == 14 then
				npcspawn = base["Zombie Spawner14"]
			end
			if randomspawn == 15 then
				npcspawn = base["Zombie Spawner15"]

			end
			if randomspawn == 16 then
				npcspawn = base["Zombie Spawner16"]
	
			end
			if randomspawn == 17 then
				npcspawn = base["Zombie Spawner17"]

			end
			if randomspawn == 18 then
				npcspawn = base["Zombie Spawner18"]

			end
			if randomspawn == 19 then
				npcspawn = base["Zombie Spawner19"]
				
			end
			if randomspawn == 20 then
				npcspawn = base["Zombie Spawner20"]
				
			end
		if npcspawn ~= nil  then
			
			npcchosen.Parent = workspace.AttackerNpc	
			npcchosen:MoveTo(npcspawn.PrimaryPart.Position)			

			print(npcspawn:GetFullName())

			local tween = tweenserve:Create(npcspawn.door,TweenInfo.new(0.5),{
			Position = npcspawn.door.Position - Vector3.new(0,8,0)} )--open
						
						
			local tween2 = tweenserve:Create(npcspawn.door,TweenInfo.new(0.5),{
			Position = npcspawn.door.Position + Vector3.new(0,8,0)})	 -- close



			tween:Play()	
			print("Opening:"..npcspawn.Name)			
			tween.Completed:Connect(function()
				wait(1)
				print("Closing:"..npcspawn.Name)
				tween2:Play()
			end)
		end

		
		else -- mini boss or boss spawn
			local randomspawn = math.random(1,4)
			local base = workspace.AttackerBase

			if randomspawn == 1 then
				npcspawn = base["Special Zombie Spawner1"]
			end
			if randomspawn == 2 then
				npcspawn = base["Special Zombie Spawner2"]
			end
			if randomspawn == 3 then 
				npcspawn = base["Special Zombie Spawner3"]
			end	
			if randomspawn == 4 then
				npcspawn = base["Special Zombie Spawner4"]
			end
			npcchosen.Parent = workspace.AttackerNpc	
			npcchosen:MoveTo(npcspawn.PrimaryPart.Position)
		end
		

		
	
	
	
end 

values.Wave.Changed:Connect(function(newwave)
	if game.ServerStorage.Values.WaveInProgress.Value == false then values.WaveInProgress.Value = true
		game.ReplicatedStorage.Values.Wave.Value = newwave
		
		game.ReplicatedStorage.Events.PlayerEvent:FireAllClients("Dialogue","Wave "..newwave.." starting")
		
		if newwave == 1 then -- wave 1

			for count = 1,30 * values.SpawnMultiplier.Value do
				local chance = math.random(1,3)
				if chance == 1 then
					local soldierc = units["Demonic Soldier"]:Clone()
					npcchosen = soldierc
				end
				if chance == 2 then
					local demonc = units.Demon:Clone()
					npcchosen = demonc
				end
				if chance == 3 then
					local swordierc = units["Demonic Swordier"]:Clone()
					npcchosen = swordierc
				end
				getspawn(npcchosen)	


				
				wait(3)
			end
			wait(30)
		end	
        end
end

When the first wave starts, time between spawning zombies are 3 seconds, yet both tweens start and end in one second. I even ensured the same spawner was not chosen twice in a row

1 Like

I see the code that does the spawn is within a for loop

for count = 1,30 * values.SpawnMultiplier.Value do
--stuff
getspawn(npcchosen)	
		
	wait(3)
end

I believe is a chance the same NPC gets chosen in a row like demonc, demonc, demonc which will cause the tweens to somehow interrupt each other and cause it to rise multiple times somehow.

But yeah the script is hard to read. I recommend making it more modular like creating a separate function dedicated to only the tweening of the doors.

Also instead of the many if statements to the numbers you can just do this from:

			if randomspawn == 1 then
				npcspawn = base["Zombie Spawner1"]
			end

Edit: It’s concatenation sorry.
to this using the power of string concatenation.

npcspawn = base["Zombie Spawner"..tostring(randomspawn)]

Though this wasn’t the solution, atleast that simplified my script a lot, thanks for the string concentation.
If I dont understand, correct me but isn’t the cooldown between spawning 3 seconds but both tweens combined take less time than the spawn cooldown?

Hmm, perhaps the problem is the tweens where you are creating a new tween every time you call the function. Consequently, with the timing of when the doors get opened the tween 1 gets replaced by a new local tween hence disabling the tween.Completed event as you are creating an entirely new tween.

Perhaps using a coroutine will solve the problem in your get spawn.

From this:

getspawn(npcchosen)	

To this:

local newThread = coroutine.create(function()
     getspawn(npcchosen)	
end)
 
coroutine.resume(newThread)

This should make sure the waits don’t interrupt each other and the local variables stay within their own individual thread. I’m just guessing sorry.

I will try your proposed solution to see if it works

For this, keep in mind that wait(3) is not exactly accurate. It get’s especially worse the laggier the game is such as when you spawn in an NPC in your game. I believe the weird things are happening because of this but I’m not entirely sure.

you might just have to increase the time from 3 seconds to spawn the mobs to something higher and increase the wait interval in-between the 2 tweens since if it makes sense to you, the gates tween up wait a quick 1 second and go down which will look like they went up and down without waiting. maybe just increasing the intervals will fix the tween issue?

coroutine didnt work at all though

I’m not too sure since your script seems fine and doesn’t seem to have anything that might cause bugs, you could try to get rid of tween.completed and just add a wait after the first tween and then play the second tween? You would have to do wait 1.5 or num.5 to wait for the tween to finish and have a interval.

I’ve tried copy pasting the script contents into another script but it didn’t work

@dthecoolest I tried what you said it didnt work

Sorry, can’t help you without more information on what exactly what didn’t work.

Debugging requires a lot of information to interrogate what your script is doing wrong and there are two main ways of doing such as using print statements, using the lua debugger, or even a video of what is happening. These things I don’t have access to help you with sadly.

ok I will go find out more about the lua debugger, thanks for advice

I suspect the second tween interrupts the first mid-way

Ok, I found the issue after a long time. It turns out that these lines of code

		local tween = tweenserve:Create(npcspawn.door,TweenInfo.new(0.5),{
			Position = npcspawn.door.Position - Vector3.new(0,8,0)} )--open
						
						
			local tween2 = tweenserve:Create(npcspawn.door,TweenInfo.new(0.5),{
			Position = npcspawn.door.Position + Vector3.new(0,8,0)})	 -- close

It turned out they weren’t supposed to be together. The position values in the table do not update when the door’s position changes so I moved the tween2 line into a tween.completed function

1 Like