Issues with pathfinding a non humanoid npc

Im making a non humanoid npc pathfind but Im running into an issue.

whenever I run the script below the npc shoots upward on the Y axis. its Y position shows a number too big to add to this post.

local PathfindingService = game:GetService("PathfindingService")
local npc = script.Parent
local goal = game.Workspace.PathGoal
local path = PathfindingService:CreatePath()






function aim(target)
	local c = script.Parent
script.Parent.Parent:SetPrimaryPartCFrame(CFrame.new(c.Position,Vector3.new(
 	target.Position.X,
 	c.Position.Y,
 	target.Position.Z
   )
))

end

function followpoint(p)
	repeat
		wait()
		aim(p)
		script.Parent.BodyVelocity.Velocity = script.Parent.CFrame.LookVector * 2
	until
	script.Parent.Position.X == p.Position.X + 1 or script.Parent.Position.X == p.Position.X - 1 and
	script.Parent.Position.X == p.Position.Z + 1 or script.Parent.Position.Z == p.Position.Z - 1
end


function calculatepath()
path:ComputeAsync(npc.Position,goal.Position)
local waypoints = path:GetWaypoints()

for _, p in next, waypoints do
	local newpart = Instance.new("Part")
	newpart.Shape = Enum.PartType.Ball
	newpart.Size = Vector3.new(1,1,1)
	newpart.Anchored = true
	newpart.Parent = game.Workspace
	newpart.CanCollide = false
	newpart.Position = p.Position
end


for _, p in pairs(waypoints) do
	 followpoint(p)
end

end




	calculatepath()

if I leave the part anchored the npc does face the first waypoint, but when I unanchor the npc thats when somehow it goes so high the studio crashed when I zoom to it. why is this behavior present?

2 Likes

the issue is i believe, Here:

script.Parent.BodyVelocity.Velocity = script.Parent.CFrame.LookVector * 2

i’m not sure exactly sure what you are trying to do, are you trying the move the non humanoid npc towards the the next node in a specific way?

I plan to have the non humanoid npc move around using bodyvelocity.
but interestingly I dont think the problem is linked to its maxforce as I tried this script when the bodyvelocity’s maxforce is 0,0,0 to see if it changed at all.

I think I see what you’re trying to do, but there’s a better way to do this. So when you call aim() I’m assuming you want your NPC to look towards the waypoint. Try using a BodyGyro instead, you can do this by simply changing the Gyro’s cframe to (npc.PrimaryPart.Position, target.Position). And for movement to each point I would suggest using a BodyPosition and simply moving your NPC towards that point. This may give the look that you want, although I’m unsure.

Here’s for reference:

function aim(target)
      npc.PrimaryPart.BodyGyro.CFrame = CFrame.new(npc.PrimaryPart.Position, target.Position)
end

function followpoint(p)
      npc.PrimaryPart.BodyPosition.Position = p.Position
      
      repeat 
      wait() 
      aim(p)
      until (npc.PrimaryPart.Position - p.Position).magnitude <= 2
end

You may have to mess with the properties a bit to get the results you want.

I think I found the problem, it seems to be a studio bug, if I change the bodyvelocitys maxforce on the Y axis to a high number, the npc does not fling out. so what I did was add another bodyvelocity. this new bodymover will apply a constant force downward. this for the most part solves the flinging problem and keeps the part from floating since its pulling it down. though it still does it from time to time and the exact cause is unknown.

It’s likely just Roblox physics in general causing your issue, and not the script. If you want something more precise and less glitchy, try my method.

thanks, ill see what I can do.

I tried your method and its still occuring, its really strange and frustrating because even If I anchor everything it still moves!?

this is the new aim function:

function aim(target)
	local c = script.Parent
	local cpos = c.Position
--script.Parent.Parent:SetPrimaryPartCFrame(CFrame.new(cpos,Vector3.new(
-- 	target.Position.X,
-- 	cpos.Y,
-- 	target.Position.Z
--   )
--))


script.Parent.BodyGyro.CFrame = CFrame.new(cpos,Vector3.new(
	target.Position.X,
	cpos.Y,
	target.Position.Z
))

repeat
	wait()
c.Position = cpos
until
c.Position == cpos

end

the last part forces the part back to its original position before flying off but even with this it flickers around wildly even if I anchor it, only when I turn this script off does it stop. the only thing that remained the same when I changed this function was the CFrame that only changes the X and Z axis. could this be the cause?

Could this be your problem:

repeat
	wait()
c.Position = cpos
until
c.Position == cpos

What happens if you remove this

this chunk of code was used to bring it back, it still disappears without it.

The only thing i can think of is you need to wait until the npc has reached it’s destination before calling followpoint(p) again. Other than that i tested the code you provided (above) and i can’t seem to replicate the issue, could you provide a video/image of exactly is happening?

test file.rbxl (22.7 KB)

I put the npc and its goal into this save file, I also included some texts to help you.

Ok, so i added BodyGyro and messed around with the body movers (lowered some damping and such) and the result was similar to what you’re looking for:

Essentially i changed your followpoint and aim functions to:


function aim(target)
   npc.BodyGyro.CFrame = CFrame.new(npc.Position , Vector3.new(target.Position.X, npc.Position.Y, target.Position.Z)) --- rotate the npc towards the target whilst maintaining it's y 
end



function followpoint(p, isblocked)

	local multiplier  = 5
	aim(p)
     script.Parent.BodyVelocity.Velocity = ( p.Position - script.Parent.Position).unit * multiplier ---Take the unit of the waypoint from the npc's position then multiply by a value for "speed"

     while true do---Use Magnitude and yield the script until the npc is close to the waypoint 
		wait()
		if (script.Parent.Position - p.Position).magnitude < .7 then ---you can play around with this
		  break
		end
	end
end

it seems to work, but you might want to do some additional testing still.

As a side note i would recommend adding a conditional statement in your path.Blocked event, to check whether the node that was blocked is in front of the npc/hasn’t been visited yet (if that makes sense)

Here the edited place file if you need it:

test file 2.rbxl (23.3 KB)

so…its not doing it…as much. but I went to test the place you provided and from time to time it still likes to spontaneously fly away, although in a different way this time.

this time the part raises up on the y axis about 10 or 20 studs while spinning really fast.
the part will then proceed to gracefully sink downward until it touches the baseplate.
in which it will merge slightly before flinging into oblivion.

idk why pathfinding non humanoid npcs has to be so glitchy like this -_-

hmm… that’s weird, i can’t seem to replicate the issue you’re describing . Everytime i tried it, it worked. Well… if bodymovers don’t work out you can always use tweening or cframing. i’m not sure why i would be doing that though.

this has to be a bug. I took video when it does glitch and when it doesnt:

after replaying the game several times it finally decides to work again:

it seems to do this randomly and its really unfortunate because I was hoping to try a new game idea without using humanoids as they are performance heavy :frowning:

1 Like

it looks like it might have something to do with the settings for the forces but i can’t say for sure, maybe play around with those idk, there probably is a way to fix your problem but i’m not sure at the moment, if i figure it out i’ll let you know.

Also during testing i found that body position worked well too, but it was a little jittery for me, but maybe if you lower the power on it, it would be better.

Either way good luck on your game!

thanks, I might have to try a different concept and return here when the problem can be remedied.