Coroutines, threads and OOP

Hey there. I recently am working on a new game that has OOP and what happens is that each Unit or Agent is an Object.

There is a function in the agent/unit called FIRE that causes the agent to fire in the direction that he is facing. However, when I try looping through the agents and fire each one the thread pauses and the agents do not fire simultaneously.

I have looked at a few ways to do this.
Using coroutines. However, I have never used them before and I am not sure how it would work with OOP
Using bindable events. However, I will have probably have a max of 80 Agents at once and I do not want an event for every single agent.

Each agent has many function that I would like to be played simulateously for example. Moving, shooting, jumping, aiming mounting on vehicles and holding position.

I am going to post the code that deals with firing and the code that fires the agent.

for i,Agent in ipairs(AgentList) do
	Agent.Automated = false
	Agent:Fire()
	Agent.Automated = true
end

In the OOP there is this

function Unit:Fire()
	--wait(math.random()/6)
	local Line = Instance.new("Part",workspace)
	Line.CFrame = CFrame.lookAt(Character.Gun.AimPart.Position + Character.HumanoidRootPart.CFrame.LookVector*500/2,Character.Gun.AimPart.Position)
	Line.Size = Vector3.new(0.2,0.2,500)
	Line.CanCollide = false
	Line.Material = "Neon"
	Line.Anchored = true
	Line.BrickColor = BrickColor.new("Cyan")
	Character.Gun.Main.FlashFX.Enabled = true
	Character.Gun.Main.FlashGui.Enabled = true
	local RaycastResult = workspace:Raycast(Character.Gun.AimPart.Position,Character.HumanoidRootPart.CFrame.LookVector*500,RaycastParameters)
	if RaycastResult then
		if RaycastResult.Instance.Parent:FindFirstChild("Humanoid") then
			RaycastResult.Instance.Parent:FindFirstChild("Humanoid"):TakeDamage(600)
		end
	end
	
	DebrisService:AddItem(Line,0.1)
	wait(.1)
	Character.Gun.Main.FlashFX.Enabled = false
	Character.Gun.Main.FlashGui.Enabled = false
end

Any help is aprrecieated.

I will post a video on what they are current behaviour is.

If you want them to fire simultaneously, maybe try this?

for i,Agent in ipairs(AgentList) do
	coroutine.wrap(function()
		Agent.Automated = false
		Agent:Fire()
		Agent.Automated = true
	end)()
end

So each iteration is on a separate thread so the waits don’t affect each other. I’m not sure if putting the function’s code in a coroutine

function Unit:Fire()
	coroutine.wrap(function()
		--wait(math.random()/6)
		local Line = Instance.new("Part",workspace)
		Line.CFrame = CFrame.lookAt(Character.Gun.AimPart.Position + Character.HumanoidRootPart.CFrame.LookVector*500/2,Character.Gun.AimPart.Position)
		Line.Size = Vector3.new(0.2,0.2,500)
		Line.CanCollide = false
		Line.Material = "Neon"
		Line.Anchored = true
		Line.BrickColor = BrickColor.new("Cyan")
		Character.Gun.Main.FlashFX.Enabled = true
		Character.Gun.Main.FlashGui.Enabled = true
		local RaycastResult = workspace:Raycast(Character.Gun.AimPart.Position,Character.HumanoidRootPart.CFrame.LookVector*500,RaycastParameters)
		if RaycastResult then
			if RaycastResult.Instance.Parent:FindFirstChild("Humanoid") then
				RaycastResult.Instance.Parent:FindFirstChild("Humanoid"):TakeDamage(600)
			end
		end
		
		DebrisService:AddItem(Line,0.1)
		wait(.1)
		Character.Gun.Main.FlashFX.Enabled = false
		Character.Gun.Main.FlashGui.Enabled = false
	end)()
end

Would do the same

This works perfectly. I should probably read up on this stuff more. I for some reason kept getting cannot resume dead coroutine but it works now.

https://gyazo.com/f96f2fc143981550a3b70f0d8faeb666

1 Like

The resume dead coroutine is probably a mistake in how you set up the coroutines as once a coroutine is finished, aka, it reeaches the end of its code, it’s considered dead, but least you now know how to do it!

1 Like