It’s been a painstaking day experimenting with the infamous PathfindingService that ROBLOX offers us developers. I’ve gotten the basics of a path-finding NPC laid out with scripts, but in practice it gets hung up on even the simplest of maneuvers.
Keep in mind this is what I call the “active” path-finding, where the NPC is actively chasing a player. When it’s kept to a simple “Hey, path-find to this prior-set goal!” it manages to get it right as shown in the GIF below but I need more use out of it than that.
I’d share the code itself but it’s basically indistinguishable from the other open-source path-finding scripts out there. What can I implement into my system to get around this? I’ve tried SimplePath a while ago and the same issue occurred, which is what led me to try a crack on path-finding for myself. I’ve tried adjusting the parameters of the agent with no luck, and attempted a remedy by making the agent jump occasionally when loosely detected as stuck, but it’s almost stubborn and likes to continuously lock itself onto a particular problem part.
This is humorously glossed over in the Pathfinding guide on the ROBLOX docs, but the issue was that in the above-most code, the path was being calculated from the agent’s HumanoidRootPart position as expected—in practice however, this calculates the paths too high and your agent will try to “walk up walls” essentially, as seen in the below image. Take note that the white orb being partially consumed by the zombie’s torso is the first waypoint in the path, and is a Walking action:
If we change our code to the lower-most example, the path will now begin calculating closest to the legs than the middle of the agent, eliminating any attempts of walking up and onto ledges.
Opting back to SimplePath (which I recommend) after merging this fix in, I can say my zombies now maneuver twice as good than what I originally needed, which was a happy sight. The rest is up to me and the hundreds of lines of logic I still have to write for their behavior… fun!
What is the recommended procedure for integrating this feature into SimplePath? SimplePath has its own slightly different implementation method that may differ from the current approach.
self._path:ComputeAsync(self._agent.PrimaryPart.Position, (typeof(target) == "Vector3" and target) or target.Position)
Can I just do this?
self._agent.PrimaryPart.Position - Vector3.new(0, self._agent.PrimaryPart.Size.Y/0.75, 0), rest of code
Also, I have a taller character. What should I set PrimaryPart.Size.Y/0.75 to? Is there something to do with HipHeight?
In retrospect, I feel like multiplication would be easier to read, but for some reason I chose to do division. They’re opposites, and can both be used here albeit with different values.
For context, the PrimaryPart of most rigs is the HumanoidRootPart, which is the case here. Take a default HumanoidRootPart of an R6 character; it’s 2 studs tall. The code character.PrimaryPart.Size.Y/0.75 will give me around 2.67. I then subtract this from the position of the HumanoidRootPart so I’ll end up 2.67 studs lower, allowing the script to calculate more from the position of the legs.
To visualize this, take this green part which is centered with the HumanoidRootPart:
If we move it down 2.67 studs, it’ll be in line with the lower part of the legs.
In all simplicity I’m just getting an offset that’ll stay relative regardless of the size of different rigs and moving it further up or down with that last little /0.75 division bit. You can remove it and still be fine.
HipHeight isn’t taken into account with this code. If you want to tweak it, you can change the amount that the offset is divided by.
Correct! I did exactly as you did. Let me know if you have any other questions.