Hello! I’ve been working on a project that requires large amounts of zombie-like NPCs. These NPCs do not use Roblox’s PathfindingServce; they only go after targets that are within its proximity. So with that being said, I’ve been trying to find different ways to make the AI recognize parts, objects, or obstacles that it will need to jump over to get to its target. Ways I’ve gone about doing so in the past include:
Using touched events to tell the NPC whether or not the object touched was a part; if yes, then jump. (Not reliable, induces lag when large amounts of NPCs are present.)
Using a spawner function to tell whether or not the NPCs WalkToPoint.Y position is greater or lesser than it’s target’s head position. Like this:
spawner(function()
if NPC.Humanoid.WalkToPoint.Y > NPC.Humanoid.Parent.Head.Position.Y then
NPC.Humanoid.Jump = true
end
end)
The method listed in the second bullet is the one I’m currently using. But as a result, the NPC only jumps when the player jumps, or only when the player is in a higher position than the NPC. The AI doesn’t actually recognize obstacles. If anybody has any other methods to make NPCs jump (only when needed) to get over objects, I’m all ears. Any help at all is much appreciated.
You could cast two rays from the front of the zombie. One at around waist height, and one somewhere above the head. You can use the two to determine if there is an obstacle that is high enough to need to jump over, but also isn’t a wall.
Adding onto what @KeysOfFate said, Here’s what this should roughly look like.
spawner(function()
local jumpHeight = NPC.Humanoid.JumpPower^2 / (2*workspace.Gravity)
local cframe, size = NPC:GetBoundingBox() -- get the boundingbox of the npc
local bottom, top = cframe.Position - Vector3.new(0, size.Y / 2, 0), cframe.Position + Vector3.new(0, size.Y / 2, 0)
local hip = bottom + NPC.Humanoid.HipHeight
local hipRay, topRay = Ray.new(hip, hip + NPC.Humanoid.RootPart.LookVector * 10), Ray.new(top, top + NPC.Humanoid.RootPart.LookVector * 10)
local hipPart, hipPosition = workspace:FindPartOnRay(hipRay, NPC)
local topPart, topPosition = workspace:FindPartOnRay(topRay, NPC)
if topPart == hipPart then
if ((topPart.Position.Y + (topPart.Size.Y / 2)) - bottom.Y) <= jumpHeight then -- because position is in the centre of a part, to get the top you add the size / 2
NPC.Humanoid.Jump = true
end
end
end)
I’ve discovered a simpler method for this. Let me know if you find it appealing.
local npc = script.Parent
local humanoid = npc:WaitForChild("Humanoid")
local function jump()
humanoid.Jump = true
end
-- Check for obstacles in front of the NPC
local function checkFront()
local frontRay = Ray.new(npc.PrimaryPart.Position, npc.PrimaryPart.CFrame.lookVector * 1)
local hit, hitPosition = workspace:FindPartOnRayWithIgnoreList(frontRay, {npc})
if hit then
jump()
end
end
while true do
task.wait()
checkFront()
end
You can make a list of things (Table) you want Ray to ignore, like characters and other objects and add the table in the ignore list, and then character won’t jump over those things.