Detecting Two objects are blocked by walls Possible?

Okay, Im trying to script a detection about checking there’s anything blocking between two objects
like this:


i have tried many ways like:

  1. creating a part to connect both dummy per heartbeat and use Touched to detect. But that was too ineffectiveness for that.
  2. using both attachment and rope to detect, but i cant find any ways to detect like Touched (yes i didn’t do anything for this :joy:)

Is there any more efficiency codes for Detecting Two objects are blocked by walls? I’ll be much grateful for anyone who answered me.

3 Likes

There might be a creative way that doesn’t involve constantly checking, but one simply way to do it is by simply creating a ray, from the first character’s head to the second, checking if the ray is disrupted, meaning workspace:FindPartOnRay(ray, character) if returned nil as a first value indicating that no part was hit by the ray, there is no part in between. The problem with this is that if there was a little gap that the ray can slip through and would still count as no part being there. If this is for some “don’t get caught” game where they don’t have to see you, that would work I guess.

To create a ray from the first head to the second simply

Ray.new(character1.Head.Position, character2.Head.Position)
3 Likes

This is a decent video that explains it.

2 Likes

Just use Ray they work much better

Ray.new(StartPosition,DirectionToGo)

Raycasting is a great way of determining whether there’s something in the way between two objects, but also for some other useful cases than checking if ObjectA can see ObjectB.

The only information we need is just the positions of both objects (PointA_Position and PointB_Position), and then by getting our Direction,

local Direction = (PointB_Position - PointA_Position).Unit

we have basically what points towards our PointB_Position. (in this case, pointing towards CharacterB’s head).

We can now fire a ray with Ray.new(), using PointA_Position and the Direction, then using workspace:FindPartOnRay() to check whether the ray is hitting something.

Below is a rough example of checking whether something is in between two points.

-- Rough draft of how we use Raycasting in your case, and essentially in any other cases
local function isObstructed(PointA_Position, PointB_Position)
	local Direction = (PointB_Position - PointA_Position).Unit -- gives us our direction towards PointB_Position
	local Raycast = Ray.new(PointA_Position, PointB_Position * 100) -- Multiplier, just in case.
	local Hit = workspace:FindPartOnRay(Raycast) 
    --workspace:FindPartOnRay() also has three more parameters you can pass through, respectively: what the Ray should ignore, whether the Terrain cells are cubes, and whether the ray should ignore the Enum.Material.Water.
	
	if Hit then
		return true -- If there was anything that got hit by the Raycast variable, return true.
	else
		return false -- If there wasn't anything in the way, return false.
	end
end

Do note, I haven’t added any sanity checks to determine if PointA can actually see PointB (easily solvable by getting the Parent or Name of the hit object, easy on paper). How you handle checking a ray after is completely up to you, as my example is just a stepping stone.

Hope this helps!

7 Likes

Hey! I fully support your answer but would just like to point it out that when you cast a ray between 2 basepart positions, specifically the 2 HumanoidRootParts in this case. If u are casting a ray from either of the positions, the HumanoidRootPart or any other body part, or even the part at the other end would be detected as hit which would return true, you might want to add it to the ignore list. Also if the distance between the 2 parts was more than 100 studs, it won’t be accurate, so it would be better if u multiply it by (pos1 - pos2).Magnitude

True, the ray would end up hitting the targeted object at the end, so that can be added as an ignored instance in workspace:FindPartOnRay() (and its descendants automatically), along with the length of the ray being exactly the distance between PointA and PointB when it’s used as a multiplier in the direction, instead of using a flat 100.

local function RayCasting(PointA_Position, PointB_Position, Raidus, Whitelist)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
	raycastParams.FilterDescendantsInstances = {workspace.Part}
	raycastParams.IgnoreWater = true
	local raycastResult = workspace:Raycast(PointA_Position, (PointB_Position - PointA_Position).Unit * Raidus, raycastParams)
	if raycastResult then
		print("Object/terrain hit:", raycastResult.Instance:GetFullName())
		print("Hit position:", raycastResult.Position)
		print("Surface normal at the point of intersection:", raycastResult.Normal)
		print("Material hit:", raycastResult.Material.Name)
		return true
	else
		return false
	end
end

Okay. I found a function that recommended by Roblox. It called Raycast.
That could be more easy to modify your Raycast setting.