Getting Random position on multiple parts

Making an npc that will walk around randomly on a floor, but also not walk off it. I am using pathfindingservice to do this, the only problem was that I needed to get a destination position.

Scraping around here I eventually found that you can use a raycast to find the part you are standing on. This let me use the size and position dictate a boundary of where the npc can walk.

This worked, but then I wanted to make my npc walk to another part. How would I do that?

We need your script to see how you are accomplishing it first.
remember to copy/paste it here, but put 3 backticks (```) before and after so it’ll format correctly.

Yes I’m sorry, here you go

local zombie=script.Parent

--...

local PFS=game:GetService("PathfindingService")
local params=RaycastParams.new()
params.FilterDescendantsInstances=zombie:GetChildren()
params.FilterType=Enum.RaycastFilterType.Exclude
local hit=workspace:Raycast(zombie.Head.Position,Vector3.new(0,-6,0),params)
print(hit)
local floor=hit.Instance
while wait(math.random(3,7)) do
	Xpos=floor.Position.X
	Ypos=floor.Position.Y
	Zpos=floor.Position.Z
	Xsize=floor.Size.X
	Ysize=floor.Size.Y
	Zsize=floor.Size.Z
	local randomXpos=math.random(Xpos-(Xsize/2)+2,Xpos+(Xsize/2)-2)
	local randomZpos=math.random(Zpos-(Zsize/2)+2,Zpos+(Zsize/2)-2)
	local randomYpos=Ypos+Ysize/2+2
	local path=PFS:CreatePath()
	path:ComputeAsync(zombie.HumanoidRootPart.Position,Vector3.new(randomXpos,randomZpos,randomYpos))
	local waypoints=path:GetWaypoints()
	print(waypoints)

	for i,Waypoint in ipairs(waypoints) do
		zombie.Humanoid:MoveTo(Waypoint.Position)
		zombie.Humanoid.MoveToFinished:Wait()
	end
end

Well, assuming none of the floors are rotated in at all, you’ve got the walk to random position portion down. You probably want to change what’s currently in the floor loop to a function, and create a new function that makes the zombie move to the next designated floor.

Then, you could assign where the raycast using an attribute or value, but preferably the script would be able to decide where to move on it’s own. Though that depends on what your

local PFS=game:GetService("PathfindingService")
local params=RaycastParams.new()
params.FilterDescendantsInstances=zombie:GetChildren()
params.FilterType=Enum.RaycastFilterType.Exclude

function RaycastFloorTarget(Origin,Direction)
	local hit=workspace:Raycast(Origin,Direction,params)
	if hit.Instance then 
		return hit.Instance
	else
		error("Nothing was hit!") --You may want to change this up.
	end
end

function   WalkToRandom(tFloor,WanderCount)
	local f_Pos = tFloor.Position
	local f_Size = tFloor.Size
	for iW=0,WanderCount do
		local randomXpos=math.random(f_Pos.X-(f_Size.X/2)+2,f_Pos.X+(f_Size.X/2)-2)
		local randomZpos=math.random(f_Pos.Z-(f_Size.Z/2)+2,f_Pos.Z+(f_Size.Z/2)-2)
		local randomYpos=f_Pos.Y+f_Size.Y/2+2
		local path=PFS:CreatePath()

		path:ComputeAsync(zombie.HumanoidRootPart.Position,Vector3.new(randomXpos,randomZpos,randomYpos))
		local waypoints=path:GetWaypoints()
		print(waypoints)
	
		for i,Waypoint in ipairs(waypoints) do
			zombie.Humanoid:MoveTo(Waypoint.Position)
			zombie.Humanoid.MoveToFinished:Wait()
		end
	end
end
while wait(math.random(3,7)) do
	--There's probably a better way to set the target floor than with a raycast, but that depends on what your game is.
	newFloor = RaycastFloorTarget(Zombie.Head.Position,Vector3.new(0,0,0))
	WalkToRandom(newFloor,5)
end

Talking about finding the floor by a better way than ray casting, I did try to use stuff like GetPartsInPart and GetTouchingParts, but using that on the left leg returned an empty array.

It depends on what the zombies are supposed to do. If you just want the zombie to wander around whatever it’s standing on, I’d reccomend sticking raycasts.