Unable to cast value to Objects in NPC AI script

I used Y3ellow Mustang’s advanced AI tutorial on Youtube to make an enemy NPC (I am not very familiar with pathfinding and raycasting and such) I wrote the code but this is the error that pops out and the NPC does not move:

  21:01:14.688 - Unable to cast value to Objects
21:01:14.688 - Stack Begin
21:01:14.690 - Script 'Workspace.Enemy_Ornament.AI', Line 87 - function checkSight
21:01:14.690 - Script 'Workspace.Enemy_Ornament.AI', Line 113 - function findTarget
21:01:14.690 - Script 'Workspace.Enemy_Ornament.AI', Line 153 - function main
21:01:14.691 - Script 'Workspace.Enemy_Ornament.AI', Line 167
21:01:14.691 - Stack End

.
.
.
Here is the script I am using(I marked the lines that appear in the error message in a comment at the end of the line):

local myHuman = script.Parent:WaitForChild("Humanoid")
local myRoot = script.Parent:WaitForChild("HumanoidRootPart")
local head = script.Parent:WaitForChild("Head")

local grab = script.Parent:WaitForChild("Grab")
local grabAnim = myHuman:LoadAnimation(grab)
local walkAnim = script.Parent.Humanoid.walkani
local loadWalk = myHuman:LoadAnimation(walkAnim)
grabAnim.Priority = Enum.AnimationPriority.Action

--local grabSound = head:WaitForChild("Attack")

local clone = script.Parent:Clone()

function walkRandomly()
	local xRand = math.random(-50,50)
	local zRand = math.random(-50,50)
	local goal = myRoot.Position + Vector3.new(xRand,0,zRand)
	
	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(myRoot.Position, goal)
	local waypoints = path:GetWaypoints()
	
	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in ipairs(waypoints) do
			if waypoints.Action == Enum.PathWaypointAction.Jump then
				myHuman = true
			end
			myHuman:MoveTo(waypoint.Position)
			local timeOut = myHuman.MoveToFinished:Wait(1)
			if not timeOut then
				print("Stuck")
				myHuman.Jump = true
				walkRandomly()
			end
		end
	else
		print("Path failed")
		wait(1)
		walkRandomly()
	end
end

function findPath(target)
	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(myRoot.Position,target.Position)
	local waypoints = path:GetWaypoints()
	
	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in ipairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				myHuman.Jump = true
			end
			myHuman:MoveTo(waypoint.Position)
			local timeOut = myHuman.MoveToFinished:Wait(1)
			if not timeOut then
				myHuman.Jump = true
				print("path too long")
				findPath(target)
				break
			end
			if checkSight(target) then
				repeat
					print("moving directly to target")
					myHuman:MoveTo(target.Position)
					attack(target)
					wait(0.1)
					if target == nil then
						break
					elseif target.Parent == nil then
						break
					end
				until checkSight(target) == false or myHuman.Health < 1 or target.Parent.Humanoid.Health < 1
				break
			end
			if (myRoot.Position - waypoints[1].Position).magnitude > 20 then
				print("target moved, new path")
				findPath(target)
				break
			end
		end
	end
end

function checkSight(target)
	local ray = Ray.new(myRoot.Position, (target.Position - myRoot.Position).Unit * 40)
	local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, (script.Parent)) --LINE 87
	if hit then
		if hit:IsDescendantOf(target.Parent) and math.abs(hit.Position.Y - myRoot.Position.Y) < 3 then
			print("i can see you bruh")
			return true
		end
	end
	return false
end

function findTarget()
	local dist = 200
	local target = nil
	local potentialTargets = {}
	local seeTargets = {}
	for i,v in ipairs(workspace:GetChildren()) do
		local human = v:FindFirstChild("Humanoid")
		local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
		if human and torso and v.Name ~= script.Parent.Name then
			if (myRoot.Position - torso.Position).magnitude < dist and human.Health > 0 then
				table.insert(potentialTargets,torso)
			end
		end
	end
	if #potentialTargets > 0 then
		for i,v in ipairs(potentialTargets) do
			if checkSight(v) then	--LINE 113
				table.insert(seeTargets, v)
			elseif #seeTargets == 0 and (myRoot.Position - v.Position).magnitude < dist then
				target = v 
				dist = (myRoot.Position - v.Position).magnitude
			end
		end
	end
	if #seeTargets > 0 then
		dist = 200
		for i,v in ipairs(seeTargets) do
			if (myRoot.Position - v.Position).magnitude < dist then
				target = v 
				dist = (myRoot.Position - v.Position).magnitude
			end
		end
	end
	return target
end

function died()
	wait(5)
	clone.Parent = workspace
	game:GetService("Debris"):AddItem(script.Parent,0.1)
end

myHuman.Died:Connect(died)

function attack(target)
	if (myRoot.Position - target.Position).magnitude < 5 then
		grabAnim:Play()
		--grabSound:Play()
		if target.Parent ~= nil then
			target.Parent.Humanoid:TakeDamage(15)
		end
		wait(0.5)
	end
end

function main()
	local target = findTarget() --LINE 153
	if target then
		myHuman.WalkSpeed = 15
		findPath(target)
	else
		myHuman.WalkSpeed = 8
		walkRandomly()
	end
end

while wait(0.1) do
	if myHuman.Health < 1 then
		break
	end
	main() --LINE 167
end

If anyone could help me solve this issue I would really appreciate it : )

You may have to scroll to the right to see line 87

According to the error message, there is something wrong with this line 87 as you mentioned. Using the Dev reference API we can find out what is wrong with the line specifically.

As see for the second parameter listed in the method which is ignoreDescendantsTable we can see the type of object we have to insert in to make the ray cast work. Specifically, this object refers to a Table of the objects that we want to ignore.

Consequently, in order to create a table, we have to use curly brackets like so below, instead of round brackets if you have watched a lua tutorial before.

Quite odd as other languages use square brackets like in python lol [], but it does the trick

local ignoreTable = {script.Parent}

Hopefully, you have learned how to use the dev reference API to debug scripts for the future.

2 Likes

Works like a charm, thanks for the advice!