The output is this:
local c = coroutine.create(f)
coroutine.resume(f,1,2):6: invalid argument #1 to ‘resume’ (thread expected, got function)
Yes it is an error.
Then that’s the code working properly, meaning something is structured badly in your code. I didn’t manage to find out what, but try not using placeholder parameters and check the actual code running, with the example above implemented?
That could be possible but it is inefficient and would cause a mess that is hard to add anything or remove anything later on plus the variable constantly changes so you would need a new set of code for each and every possible changes, I don’t know for you but I would not want the code to be that messy and inefficient.
function Tower.Attack(newTower,plr)
print(plr)
local Config = newTower.Status
local target = FindNearestTarget(newTower, Config.Range.Value)
if target and target:FindFirstChild("Humanoid") and target.Humanoid.Health > 0 then
local targetCFrame = CFrame.lookAt(newTower.HumanoidRootPart.Position, target.PrimaryPart.Position)
newTower.HumanoidRootPart.BodyGyro.CFrame = targetCFrame
if Config.Damage.Value > target.Humanoid.Health then
plr.Money.Value += target.Humanoid.Health
elseif Config.Damage.Value <= target.Humanoid.Health then
plr.Money.Value += Config.Damage.Value
end
target.Humanoid:TakeDamage(Config.Damage.Value)
task.wait(Config.FireRate.Value)
end
task.wait(0.1)
Tower.Attack(newTower)
end
function Tower.Spawn(name, cframe, plr)
local AllowedToSpawn = Tower.CheckSpawn(plr, name)
if AllowedToSpawn then
local newTower = RepStorage.Towers[name]:Clone()
newTower:SetPrimaryPartCFrame(cframe)
newTower.Parent = workspace.Towers
newTower.HumanoidRootPart:SetNetworkOwner(nil)
local bodyGyro = Instance.new("BodyGyro")
bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
bodyGyro.D = 0
bodyGyro.CFrame = newTower.HumanoidRootPart.CFrame
bodyGyro.Parent = newTower.HumanoidRootPart
for i, object in ipairs(newTower:GetDescendants()) do
if object:IsA("BasePart") then
object.CollisionGroup = "Tower"
end
end
plr.Money.Value -= newTower.Status.Cost.Value
plr.TowerPlaced.Value += 1
coroutine.wrap(Tower.Attack)(newTower,plr)
else
warn("Requested tower does not exist", name)
end
end
Depends on what you are doing, I suppose, but I have not run into any problems and never once used a variable for a wrap. I use it to finish off a function that needs to both return immediately AND wait for time to pass. It happens a lot in my games… I do not use wrap for core game mechanics.