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
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.
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.