Enemy Pathfinding Help

Im doing primarypart then i updated it to humanoidrootpart

I dont know anymore can you try it?

This means that self.Model is nil or doesn’t exist for some reason. After calling Ai.new, you need to use the returned object to run the functions:

local MyAi = Ai.new(Enemy)

...
MyAi:GetTarget(500)

...
MyAi:Capture(Target)

instead of

Ai:Capture(Target)

and so on.

Wait I didnt try that before! Thank you I’ll try it if it doesnt work can I friend you and you can edit the game?

Can you friend my alt, R0_Builder2

Tomorrow I’ll be active… probably

This community resource is really helpful for learning more about what’s going on here:

This is good, but can you help finish my module? It would be nice

Do you mean the enemy patrolling? If so, you just need to edit the Ai:Patrol() function to include the random movement when there’s no active target.

I dont know anymore it just wotn work for me and can you help me rewrite it?

Yes but I’m not good at coding self and I will only have 5 characters and I want to make it a module for optimization

It’s important to understand how self works.

function module.doSomething(self, otherThing)

end

is the same as

function module:doSomething(otherThing)

end

self is just an invisible variable in this case.

Are there any error messages you are encountering?

Like I was getting PrimaryPart not a valid thing but I do have a primary part so I’m going to rewrite it but can you help?

Can I invite you to my game and you can help me write it?

I do believe that this could be causing it because no “Ai” object has been created yet. You need to do Ai.new first.

I would be happy to but I’m on my phone right now, so I cannot actually use Roblox Studio. However, it would be helpful if you could show me the other script that is responsible for the require and does Ai.new.

--@Server
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
task.wait(5)
local Ai = require(ReplicatedStorage.Ai)
local Figures = Workspace.Figures



for Index, Figure : Part in pairs(Figures:GetChildren()) do
	local NewModule = Ai.new(Figure)
	Figure.PrimaryPart:SetNetworkOwner(nil)
end

In here, you should also add NewModule:Patrol() every heartbeat instead of inside the ai script:

RunService.Heartbeat:Connect(function()
	NewModule:Patrol()
end)

ReplicatedStorage.Ai:64: attempt to index nil with ‘PrimaryPart’ (x2588)

I keep getting that one error every time

Things like these should be changed to self:FollowPath instead if it’s inside of the Ai script functions.

--@Ai
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")

local Ai = {}
Ai.__index = Ai

function Ai.new(Model : Model)
	local self = setmetatable({}, Ai)
	self.Model = Model
	self.Connections = {
		Waypoints = nil,
		NextWaypointIndex = nil,
		ReachedConnection = nil,
		BlockedConnection = nil
	}
	self.Path = PathfindingService:CreatePath({
		["AgentHeight"] = 7,
		["AgentRadius"] = 4,
		["AgentCanJump"] = false,
		["AgentCanClimb"] = false
	})
	
	return self
end

function Ai:GetTarget(MaxSearchDistance : number)
	local NearestTarget = nil
	local SearchDistance =MaxSearchDistance
	
	for Index, Player in pairs(Players:GetPlayers()) do
		local Character = Player.Character
		if not Character then return end
		
		local Humanoid = Character:FindFirstChild("Humanoid")
		if not Humanoid then return end
		if Humanoid.Health < 0 then return end
		
		local Distance = (self.Model.PrimaryPart.Position - Character.PrimaryPart.Position).Magnitude
		
		if SearchDistance > Distance then
			NearestTarget = Character
			SearchDistance = Distance
		end
	end
	
	return NearestTarget
end

function Ai:Capture(Target)
	local Distance = (self.Model.PrimaryPart.Position - Target.PrimaryPart.Position).Magnitude
	
	if Distance > 3 then
		self:FollowPath(Target.PrimaryPart.Position)
	else
		Target.Humanoid:TakeDamage(100)
	end
end

function Ai:FollowPath(Destination : Vector3)
	local Success, ErrorMessage = pcall(function()
		self.Path:ComputeAsync(self.Model.PrimaryPart.Position, Destination)
	end)
	
	if Success and self.Path.Status == Enum.PathStatus.Success then
		self.Connections.Waypoints = self.Path:GetWaypoints()
		
		for Index, Waypoint in pairs(self.Connections.Waypoints) do
			local Target = self:GetTarget(200)
			
			if Target then
				Ai:Capture(Target)
				self.Model.Humanoid.WalkSpeed = 25
				break
			else
				self.Model.Humanoid.WalkSpeed = 10
				self.Model.Humanoid:MoveTo(Waypoint.Position)
				self.Model.Humanoid.MoveToFinished:Wait()
			end
		end
	else
		warn(ErrorMessage)
	end
end

function Ai:Patrol()
	local WayPoints = Workspace.Waypoints:GetChildren()
	local RandomWaypoint = math.random(1, #WayPoints)
	self:FollowPath(Workspace.Waypoints[RandomWaypoint].Position)
end
return Ai

There might be more that I missed