Attempting to make a player following monster script, need help

Hey everyone,
So I’m trying to make a Pathfinding Follow player type of script and at the moment it’s all wonky and sometimes pauses, bumps into walls, etc.

I need it to: look for a player > get closest waypoint to the player > move to waypoint > if player is within [x] studs, follow player directly > if its within [y] studs, take damage (last part i have handeled)

local function properMoveTo(p1, p2, humanoid)
	local distance, waypoints = LocalAPI:AdvanceDistance(p1, p2, PathfindingData)
	local targetWaypoint = waypoints[PathfindingSettings.SkipToWP]

	if targetWaypoint then
		debugg(targetWaypoint.Position)
		humanoid:MoveTo(targetWaypoint.Position)
	else
		debugg(p2)
		humanoid:MoveTo(p2)
	end
end

local entities = {}

function module:InitEntity(entity, spotDistance, hitDamage, hitCooldown, hitDistance)
	local entityExists = entities[entity]
	if not entityExists then
		local humanoid = entity:FindFirstChildWhichIsA("Humanoid")
		entity.PrimaryPart:SetNetworkOwner(nil)
		
		entities[entity] = {}
		entities[entity].HitCooldown = os.time()
		entities[entity].FollowingRNG = nil
		entities[entity].OverallDebounce = os.time()
		
		entities[entity].Loop = RunService.Heartbeat:Connect(function()
			if os.time() <= entities[entity].OverallDebounce then
				entities[entity].OverallDebounce += .5
				
				local inRangePlayer, targetPosition = module:GetClosestPlayer(entity.PrimaryPart.Position, spotDistance)
				if inRangePlayer then
					ReplicatedStorage:WaitForChild("airesponse").Value = "player in range"
					entities[entity].FollowingRNG = nil
					properMoveTo(entity.PrimaryPart.Position, spotDistance, humanoid)

					local distanceV2 = LocalAPI:GetDistance(entity.PrimaryPart.Position, targetPosition) -- just the magnitude
					if distanceV2 <= hitDistance then
						local currentCooldownWaitTill = entities[entity].HitCooldown
						if currentCooldownWaitTill <= os.time() then
							entities[entity].HitCooldown += hitCooldown
							module:DamagePlayer(entity, inRangePlayer, hitDamage)
						end
					end
				elseif not inRangePlayer then
					local closestWaypoint, status = module:FindClosestPlayerWaypoint(entity.PrimaryPart.Position) -- gets the closest player and then returns the closest waypoint to player
					if closestWaypoint then
						if status then
							ReplicatedStorage:WaitForChild("airesponse").Value = "player not in range"
							entities[entity].FollowingRNG = nil
							properMoveTo(entity.PrimaryPart.Position, closestWaypoint.Position, humanoid)
						end
					end
				end
			end
		end)
	end
end

The Pathfinding settings are:

local PathfindingData = {
	AgentRadius = 3,
	AgentCanJump = false,
	AgentCanClimb = false,
	WaypointSpacing = 50, -- this is super high because if its low it tends to walk into walls, if its 50+ it sorta works
	Costs = {
		Border = math.huge
	}
}

And this is the map: (gray walls will only be collidable for the monster to make it simpler (cause the walls itself have decors which may disrupt pathfinding))

Any helps is appreciated folks!

3 Likes

Bump, neeeding help \\\\\\\

Ok, listen I know this sounds weird but I had the same problem and my solution was kind of strange.

The AI pathfinding was seemingly working just fine, but every few steps it would just stop randomly for a second or two. I fixed this by adding a separate new server script in the monster that went a little something like this:

local monster = script.Parent -- monster location

for i, v in pairs(monster:GetDescendants()) do -- get monster's descendants
    if v:IsA("BasePart") then -- check if it's a basepart/part
        v:SetNetworkOwner(nil) -- set network owner of found parts to the server, not a player
    end
end

This might have happened to you because it automatically set your monster’s network owner to your player, which is known to cause problems with the pathfinding stuff.

I made it so it sets the Root part’s NetworkOwner to nil but not all of the bodyparts. And it seems to walk fine, but when it reaches a corner it stops for a second or two and then moves again

1 Like

When I get back home, I’ll record of the behaviour. (If setting every bodypart’s NetworkOwner won’t work)

1 Like


I may have done something but, now it moves a bit and then just stops.

Current code, if needed:

function module:InitEntity(entity, spotDistance, hitDamage, hitCooldown, hitDistance)
	local entityExists = entities[entity]
	if not entityExists then
		local humanoid = entity:FindFirstChildWhichIsA("Humanoid")
		--entity.PrimaryPart:SetNetworkOwner(nil)

		for _, bodyPart in pairs(entity:GetDescendants()) do
			if bodyPart:IsA("BasePart") then
				bodyPart:SetNetworkOwner(nil)
			end
		end

		entities[entity] = {}
		entities[entity].HitCooldown = os.time()
		entities[entity].FollowingRNG = nil

		entities[entity].Loop = RunService.Heartbeat:Connect(function()
			local inRangePlayer, targetPosition = module:GetClosestPlayer(entity.PrimaryPart.Position, spotDistance)
			if inRangePlayer then
				ReplicatedStorage:WaitForChild("airesponse").Value = "player in range"
				entities[entity].FollowingRNG = nil
				properMoveTo(entity.PrimaryPart.Position, spotDistance, humanoid)

				local distanceV2 = LocalAPI:GetDistance(entity.PrimaryPart.Position, targetPosition)
				if distanceV2 <= hitDistance then
					local currentCooldownWaitTill = entities[entity].HitCooldown
					if currentCooldownWaitTill <= os.time() then
						entities[entity].HitCooldown += hitCooldown
						module:DamagePlayer(entity, inRangePlayer, hitDamage)
					end
				end
			elseif not inRangePlayer then
				local closestWaypoint, status = module:FindClosestPlayerWaypoint(entity.PrimaryPart.Position)
				if closestWaypoint then
					if status then
						ReplicatedStorage:WaitForChild("airesponse").Value = "player not in range"
						entities[entity].FollowingRNG = nil
						properMoveTo(entity.PrimaryPart.Position, closestWaypoint.Position, humanoid)
					end
				end
			end
		end)
	end
end

Bump. \\\\\\\\\\\\\\