Help with complex pathfinding for a shooter

So, I’m making a destiny inspired game and I want to make enemies that seek shelter to hide behind and shoot you. I have no idea how to go along this. So, any help needed.

1 Like

Currently I have a very basic script for pathfinding

edit: wrong code

code:

  -- Settings --
local Size = 4 -- Character size. will break if not set correctly
local GiveUpTime = 5 -- Time it takes for the character to give up a path.
local Radius = 50 -- wander radius
local pathargs = {["AgentHeight"] = 1, ["AgentRadius"] = 4, ['AgentCanJump'] = true}


local humanoid = script.Parent:FindFirstChildWhichIsA("Humanoid")
local pfs = game:GetService("PathfindingService")
local died = false

function Raycast(PointA,PointB,Params)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {script.Parent}
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.IgnoreWater = true
	local raycastResult = workspace:Raycast(PointA, PointB, raycastParams)
	if raycastResult then
		return raycastResult.Instance
	else
		return false
	end
end

while true do
	wait(math.random(4,5))
	if not script.Parent.HumanoidRootPart then
		script.Parent:Destroy()
	end
	local path = pfs:CreatePath(pathargs)
	path:ComputeAsync(script.Parent.HumanoidRootPart.Position, script.Parent.HumanoidRootPart.Position + Vector3.new(math.random(-Radius,Radius),0,math.random(-Radius,Radius)))
	local waypoints = path:GetWaypoints()
	if #waypoints > 0 then
		for i = 1, #waypoints do
			humanoid:MoveTo(waypoints[i].Position)
			local counter = 0
			repeat wait(0.1) counter += 0.1 until (waypoints[i].Position - script.Parent.HumanoidRootPart.Position).Magnitude <= Size or counter >= GiveUpTime
		end
	end
end

New Problem: this ray cast refuses to see the baseplate. I’ve never seen something like this.

code:

-- Settings --
local Size = 4 -- Character size. will break if not set correctly
local GiveUpTime = 5 -- Time it takes for the character to give up a path.
local Radius = 50 -- wander radius
local pathargs = {["AgentHeight"] = 1, ["AgentRadius"] = 4, ['AgentCanJump'] = true}


local humanoid = script.Parent:FindFirstChildWhichIsA("Humanoid")
local pfs = game:GetService("PathfindingService")
local died = false

function Raycast(PointA,PointB,Params)
	table.insert(Params,script.Parent)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = Params
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.IgnoreWater = true
	local raycastResult = workspace:Raycast(PointA, PointB, raycastParams)
	PlaceWayPoint(PointA,Color3.new(0.666667, 0, 0))
	PlaceWayPoint(PointB,Color3.new(0.333333, 0, 0))
	if raycastResult then
		return raycastResult
	else
		return false
	end
end

function PlaceWayPoint(Pos,Color)
	local part = Instance.new("Part")
	part.Color = Color
	part.Shape = Enum.PartType.Ball
	part.Material = Enum.Material.Neon
	part.Size = Vector3.new(1,1,1)
	part.Position = Pos
	part.Anchored = true
	part.CanCollide = false
	part.Parent = workspace
	return part
end

while true do
	wait(math.random(4,5))
	local path = pfs:CreatePath(pathargs)
	local Pos = nil
	local RayPos = script.Parent.HumanoidRootPart.Position + Vector3.new(math.random(-Radius,Radius),0,math.random(-Radius,Radius))
	local cast = Raycast(RayPos + Vector3.new(0,50,0),RayPos + Vector3.new(0,-50,0),{})
	if cast then
		Pos = cast.Position + Vector3.new(0,1,0)
		print(cast.Instance)
	else
		print(nil)
		Pos = Vector3.new(math.random(-Radius,Radius),0,math.random(-Radius,Radius))
	end
	local Part = PlaceWayPoint(Pos,Color3.new(0, 0.666667, 0))
	game:GetService("Debris"):AddItem(Part,5)
	path:ComputeAsync(script.Parent.HumanoidRootPart.Position, script.Parent.HumanoidRootPart.Position + Pos)
	local waypoints = path:GetWaypoints()
	if #waypoints > 0 then
		for i = 1, #waypoints do
			humanoid:MoveTo(waypoints[i].Position)
			local counter = 0
			repeat wait(0.1) counter += 0.1 until (waypoints[i].Position - script.Parent.HumanoidRootPart.Position).Magnitude <= Size or counter >= GiveUpTime
		end
	end
end

One Way point is under the baseplate one is over. like it should, but it doesn’t see it??

Woah woah woah that’s a lot of code. Could you find the specific snippets where you assume the problem is at?

I don’t know where the problem is. Thats the problem (ironic).

1 Like

Also why are you using a FilterType?

Especially since the parameter you’re sending is an empty table:

It returns nil every time. Also, I’m trying to figure out a way to get them to cover.

Its temporary until I put something there.

1 Like

Maybe it’s because you’re attempting to use a range with a negative number and a positive number.

If this returned a negative number, it would go down on the y-axis leading it to be under the baseplate. It wouldn’t even intersect the baseplate.

Do you need it to be a negative number? Or are you just trying to get a range in between? If you’re not, you can simple use math.abs (get the absolute value of the number)

Trying to randomize the pathfinding. then making it so if they spot someone then they get cover.

1 Like

My bad, I didn’t realize that the y spot was 0. You’re right

AHA issue:

-- its making it go in a really wierd position
local cast = Raycast(RayPos + Vector3.new(0,50,0),RayPos +Vector3.new(0,-50,0),{})
-- this is what it should have been
local cast = Raycast(RayPos + Vector3.new(0,50,0),Vector3.new(0,-50,0),{})
1 Like

Is that all that’s wrong? Mark ya post as the solution

That wasn’t what I was trying to accomplish. I wanted to make a way for this guy to find cover.

Hm well from the way I’ve interpreted it, I’d probably just check if the enemy is in the line of sight of a nearby player (you’d either retrieve that from a raycast or using a Spatial Query or manually checking the distance of each player)

If they are, then find a nearby object.

If the guy can crouch, basically do the equation to get the height (in Vector3 form) and see if any nearby objects is less than or equal to that value (you can use math.clamp for this)

Oh, I know that part. but what would be the most effective way to find an object?

Hm maybe raycasting I feel but in terms of performance, prolly not

That’ll be up to you I guess

Also new problem.


This guy thinks he can walk up walls. (he’s trying to Path find up the hill.)

With what you just said do you think I would have to put a point behind all hidable objects? then he would see which one is closest, provides best cover?

Npc

1 Like

You could however store all the objects that they can hide behind in a Folder

You could then iterate thru that folder and compare positions with the guy (is it a NPC or a player?)

Get the closest one and move behind it

Maybe you could come up with a way to get the longest side of the part and add something depending on what you get from that. Is that even possible? I’m not sure

Or you could just get the LookVector or the part and determine what to do from there.

Yes, I agree with that. I was wondering if there is a more effective way of doing it.

Also why doesn’t he jump over the ledge? He has can jump to true.