Best way for an npc to find cover?

So, I’m making a destiny inspired game and I’m currently working on the bot, and I want it to find cover. So, Should I make specific parts that can work as cover and the figure out the best spot to hide behind (how would I do that? I want them to be hidden by the player and be able to peek out and shoot them).

I would show code, But its just a basic pathfinding system. I just need to know how to find the position to go to.

2 Likes

If you want to make the bot find cover, I would create an invisible part under the cover that you want the bot to pathfind to, then use MoveTo() to make him move there if a player is within a certain distance of the bot.

1 Like

Yes, I know that part. but I bet there is a better way to do it. also, I want to make it so they are hidden.

also, I’m having an issue (off subject but is required). does anyone know how to make a character look at another part with it still being able to move.

You could fire multiple rays starting from the player your bot is hiding from, and find the object that is closest to the bot (if any)

Here’s a 2d view from above of what I mean:
image

This is the best I can come up with so I hope it helps.

1 Like

Like the idea. issue though is that it will be terrible laggy. What I’m thinking is there are some parts marked as hidable. then it finds the closet, checks for good cover, if not good cover, then find the second closets and repeat.

but I have no idea how to do that :confused:

1 Like

Lag from raycasts depends mostly on length not amount, and many games fire multiple per frame. You could test it out by checking Script Performance if you have any concerns but as long as your bot isn’t a sniper at long distance it should be fine

1 Like

Maybe combine both ideas.

Use your own idea to run for cover.

Use @vinvokz idea to check the place when your NPC gets there.

1 Like

Hmmm. interesting, Another Problem is that these are grunts meaning there are gonna be 10 - 20+ at all times around you. not including around the map.

1 Like

In that case it would make sense to combine both like @mc7oof said. Make a folder of walls that can be hid behind or tag them with CollectionService and you can reduce the raycasts significantly

1 Like

Yeah but problem,


this is the cover. but how would i tell it that this

is the best spot to hide?

I’m currently thinking we find a way to calculate size thingy and make it check on the left of the part can it peek and the player? no then check the right if not then that’s an invalid hiding spot.

The way I’d probably go about doing it is manually marking “cover zones” with an invisible part/marker of some sort.

When a bot desires to move to cover, it’ll iterate through the cover zones, and put the ones within a set distance (maybe say, 100 studs or so) into a table.

Then, for each of those in-range cover zones in the table, it’ll do a raycast from the cover zone to each enemy within the bot’s sight radius. If the cover zone is visible to any enemies, it will be removed from the table. Then, after all cover zones are checked, it’ll pick a random cover zone from the remaining list, and pathfind to it.

If you want the bot’s behavior to be a bit less predictable, you could instead make it so each cover zone is given a “score” based on how many enemies it is visible to, and then it instead picks a cover zone based on a weighted random distribution, with the “score” of the cover point being it’s weight.

2 Likes

The first step would be to detect all nearby pieces of cover. You could try and define these procedurally, but this may be laggy if you have lots of NPCs. Tagging objects as cover works fine as well.

Then we need to find out the best direction to use the cover, which should be the opposite to the general direction of the enemy. This would be calculated from the opposite direction of the enemy team’s spawn and the direction of nearest 3-5 enemies combined.

Lastly we need to find the most optimal piece of cover. Factors in order of importance are:

  • Allies near cover (avoid grouping up)
  • Range of current weapon in relation to nearest enemy from cover.
  • Amount of enemy directions covered.
  • Height advantage (if desired).
  • Size and height of cover; how safe the cover is.
  • Time to to arrive.

Also, depending on the size of the cover, the NPC may need to peek to the left or right.

I already have an idea. I’m going to get each side of a part tagged as a hiding spot then get each side (expect top and bottom) and see if they can be spotted by the player. Issue though this raycast won’t work for some reason. Its supposed to be ok but its not


code:

function RayCast(PositionA,PositionB,Params)
	local raycastParams = RaycastParams.new()
	table.insert(Params,Character)
	raycastParams.FilterDescendantsInstances = Params
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	local raycastResult = workspace:Raycast(PositionA, PositionB, raycastParams)
	print(raycastResult)
	if raycastResult then
		return raycastResult
	else
		return nil
	end
end

function PlacePart(Pos,Color)
	local p = Instance.new("Part")
	p.Size = Vector3.new(1,1,1)
	p.Shape = "Ball"
	p.Material = "Neon"
	p.CFrame = Pos
	p.Anchored = true
	p.CanCollide = false
	p.Color = Color
	p.Parent = workspace
	return p
end

function CheckIfGoodSpot(Part)
	local Sides = {}
	local BestSpots = {}
	table.insert(Sides,Part.CFrame * CFrame.new(Part.Size.X/1.5,1,Part.Size.Z/2.5))
	for _, Side in pairs(Sides) do
		for _, current in pairs(Targets) do
			local cast = RayCast(Side.Position,current:FindFirstChildWhichIsA("Humanoid").RootPart.Position,{})
			PlacePart(Side,Color3.new(1, 0.666667, 0))
			if cast == nil then
				local haystack = table.find(Sides,Side)
				table.remove(Sides,haystack)
				print("BAD")
			end
		end
	end
end

Never Mind issue found. also figured out a way! thank you all for your help!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.