Coroutine not updating parameter

hey, so im making a system where you can select troops to place down from a gui

as you can see i made it so if you click on the first slot, it makes a clone of the troop, puts it into workspace and then it start a coroutine that makes the troop follow the mouse, and then if you select it a second time, it de-selects it by stopping the coroutine and then it destroys the clone

this works fine the first time, however if you select it, deselect it and then select it again - then the coroutine still thinks the troop parameter is the one thats already been deleted.

you can see in the selecting part of the script, it updates, it prints workspace, its only inside the coroutine that it prints nil

local events = game.ReplicatedStorage:WaitForChild("Events")
local player = game.Players.LocalPlayer
local uis = game:GetService("UserInputService")
local mouse = player:GetMouse()

local cam = workspace.CurrentCamera
local deckGui = player.PlayerGui:WaitForChild("DeckGui")

local stopCoroutine = false
local place = coroutine.create(function(troop)
	while task.wait() do
		
		print(troop, troop.Parent) -- prints "knight, nil"
		
		if stopCoroutine == true then
			coroutine.yield()
		end
		
		local mousePos = uis:GetMouseLocation()
		local mouseRay = cam:ViewportPointToRay(mousePos.X, mousePos.Y)

		local params = RaycastParams.new()
		params.FilterType = Enum.RaycastFilterType.Exclude
		params.FilterDescendantsInstances = {troop}
		local raycast = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, params)
		
		if raycast and raycast.Position then
			troop:PivotTo(CFrame.new(raycast.Position.X, raycast.Position.Y ,raycast.Position.Z))
		end
	end
end)

-- select troop from deck
local troop
deckGui.Frame:FindFirstChild("1").MouseButton1Click:Connect(function()
	local slot = deckGui.Frame:FindFirstChild("1")
	
	if slot:GetAttribute("Selected") == nil or slot:GetAttribute("Selected") == false then
		slot:SetAttribute("Selected", true)
		troop = slot:FindFirstChild("Troop").Value:Clone()
		
		troop.Parent = workspace
		print(troop, troop.Parent) -- prints "knight, workspace"
		
		stopCoroutine = false
		coroutine.resume(place, troop)
		
	elseif slot:GetAttribute("Selected") == true then
		slot:SetAttribute("Selected", false)
		stopCoroutine = true
		
		troop:Destroy()
	end
end)

At line 16:

troop = coroutine.yield()

“The first time you resume a coroutine, it starts running its body. The values ... are passed as the arguments to the body function. If the coroutine has yielded, resume restarts it; the values ... are passed as the results from the yield”

API reference: coroutine.resume

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.