Problem:
Doing checks to see what players can collide against with WorldRoot:Raycast is currently difficult, because raycasts ignore parts CanCollide property.
Often CanCollide == false geometry gets used for triggers, effects, and other visuals, and players automatically do not collide with them, which makes building relatively simple.
To have a raycast check the same geometry that players can touch the options are:
- manually casting the ray twice or more (example below)
- building/maintaining complicated whitelists or blacklists
- making sure everything is tagged with a custom collision group
None of these solutions are ideal, especially collision groups, because if you use that to ignore CanCollide parts, you can’t use the collision group for other physics related tasks in the world.
Example code of the current “best” workaround:
function module:CastAgainstSameStuffAsPlayer(start, dir)
local raycastParams = RaycastParams.new()
local blacklist = {}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = blacklist
raycastParams.CollisionGroup = "PlayerGroup"
raycastParams.IgnoreWater = true
while (true) do
local raycastResult = workspace:Raycast(start,dir, raycastParams)
if (raycastResult == nil) then
return nil
end
if (raycastResult.Instance.CanCollide == false) then
--Add the CanCollide part to the blacklist, Repeat
table.insert(blacklist, raycastResult.Instance)
raycastParams.FilterDescendantsInstances = blacklist
else
return raycastResult
end
end
return nil
end
Benefit if addressed
A very common use would be pets, where you want the pet to hover off the ground a short distance away from the player.
You’d be able to cast a ray down and have it hit exactly the same geometry that a player can currently stand on, so same collision group, and also CanCollide == false.
The code might end up looking like:
function module:CastAgainstSameStuffAsPlayer(start, dir)
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "PlayerGroup"
raycastParams.IgnoreWater = true
raycastParams.UseCanCollide = true
return workspace:Raycast(start,dir, raycastParams)
end