I’m trying to make a system for which SCPs (Humanoids) can pathfind to valid targets based on modes of operation.
I have a table called validTargets, whenever a new target is added to that table; I want to check if it is the closest target or not to the SCP (aka Humanoid I’m trying to pathfind from).
What I’m doing in the script below is, I have a __newindex
metamethod that calls a function that generates a new target based on the mode of operation. Then that function calls another function to generate a path to that new target, which then calls another function to start the moving sequence.
I’m getting the following error: attempt to yield across metamethod/C-call boundary
local services = {
pathfind = game:GetService("PathfindingService"),
run = game:GetService("RunService")
}
local SCP = script.Parent
local SCPHumanoid = script.Parent:FindFirstChildWhichIsA("Humanoid")
local SCPHumanoidRootPart = script.Parent:FindFirstChild("HumanoidRootPart")
local status = {
walking = false,
attacking = false,
chasing = false
}
local config = {
canAttack = true,
canAnimate = true,
canChase = true,
mode = 1
}
--[[
1: Target closest Humanoid
2: Target Humanoid with least health
3: Target Humanoid with most health
4: Target specific Humanoid
--]]
local targetsFolder : Folder = workspace.TargetsV2
local agentParam = {
AgentRadius = 2,
AgentHeiht = 5,
AgentCanJump = true,
AgentCanClimb = true,
WaypointSpacing = 3,
Costs = {
Water = 100,
Air = 5,
DangerZone = math.huge
}
}
local mt = {
__newindex = function(self, index, value)
print(value)
rawset(self, index, value)
generateTrueTarget(self)
end
}
local validTargets = setmetatable({}, mt)
local validTargetCheckThread = task.spawn(function()
local pathObj : Path = services.pathfind:CreatePath(agentParam)
while task.wait() do
for i, v : Part in ipairs(targetsFolder:GetChildren()) do
pathObj:ComputeAsync(SCPHumanoidRootPart.Position, v.Position)
if table.find(validTargets, v) then
continue
end
if pathObj.Status ~= Enum.PathStatus.NoPath then
validTargets[#validTargets + 1] = v
end
end
print(validTargets)
end
end)
function generateTrueTarget()
print("Generating true target")
local foundClosest = -1
if config.mode == 1 then
for i, v in validTargets do
if foundClosest == -1 then
foundClosest = v
continue
end
if (SCPHumanoidRootPart.Position - v.Position).Magnitude < (SCPHumanoidRootPart.Position - ((foundClosest.Position) or math.huge)).Magnitude then
foundClosest = v
end
end
end
generatePath(foundClosest)
end
function generatePath(target : Part)
local mainPathObj : Path = services.pathfind:CreatePath(agentParam)
moveTo(mainPathObj:ComputeAsync(SCPHumanoidRootPart.Position, target.Position))
end
function moveTo(generatedPath : Path)
local generatedPathWaypoints = generatedPath:GetWaypoints()
for i, point : PathWaypoint in ipairs(generatedPathWaypoints) do
SCPHumanoid:MoveTo(point.Position)
print("Moving to point " .. i)
if point.Action == Enum.PathWaypointAction.Jump then
SCPHumanoid.Jump = true
end
end
end
Any ideas on how I can remedy this? I know that error is for when you try to call a non-yielding function inside a metamethod.