I want my raycast to work through parts with a transparency above 0 but to work normally with parts that don’t have any kind of transparency at all, how can I achieve this?
local function performRaycast(player)
local character = player.Character
if not character then
return false
end
for _, targetPart in pairs(targetParts) do
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {player.Character}
local raycastResult = workspace:Raycast(
character.Head.Position,
(targetPart.Position - character.Head.Position).unit * (targetPart.Position - character.Head.Position).magnitude,
raycastParams
)
if raycastResult and raycastResult.Instance == targetPart then
return true
end
end
return false
end
Raycasts take a FilterDescendantsInstances parameter that allows you to select/ignore certain parts for raycasting queries.
Since you’re already using Blacklist, which only queries parts inside the list, just add every Part you want to query that isn’t transparent to your blacklist:
-- No guarantee this will work, and also incredibly inefficient lol
local blacklist = {}
for _, part in pairs(workspace:GetDescendants()) do
if part:IsA("Part") and part.CanQuery and part.Transparency == 0 then
table.insert(blacklist, part)
end
end
Make a recursive function where if the raycast hits a part with Transparency > 0, it raycasts again but add the part to ignore list and start from the hit position.
local function recursiveRaycast(origin,target,raycastParams)
raycastParams = raycastParams or RaycastParams.new() -- Incase none is provided
local result = workspace:Raycast(origin,target-origin,raycastParams)
if result then
if result.Instance.Transparency > 0 then -- Condition to ignore part
local filter = raycastParams.FilterDescendantsInstances
table.insert(filter,result.Instance)
raycastParams.FilterDescendantsInstances = filter
return recursiveRaycast(result.Position,target,raycastParams) -- Raycast again from hit position
end
return result -- Did not ignore
end
return nil -- Nothing was hit
end
You need to pass the origin and the target position to the function. The RaycastParams is optional. You would use the function like this
local function recursiveRaycast(origin: Vector3, target: Vector3, raycastParams: RaycastParams?)
raycastParams = raycastParams or RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local direction = (target - origin).Unit * (target - origin).Magnitude
local result = workspace:Raycast(origin, direction, raycastParams)
if result then
if result.Instance.Transparency > 0 then
local filter = raycastParams.FilterDescendantsInstances
table.insert(filter,result.Instance)
raycastParams.FilterDescendantsInstances = filter
return recursiveRaycast(result.Position, target, raycastParams)
end
return result
end
return nil
end
I did not notice that. Why did you add that? That is the same as doing target - origin.
.Unit is taken by dividing the Vector by its magnitude. If you multiply it by its own magnitude, you basically canceled out the .Unit, making the Unit*Magnitude thing useless.
local direction = target - origin
local magnitude = direction.Magnitude -- The distance
local unit = direction.Unit -- Equal to direction / magnitude
local newDirection = unit * magnitude -- (direction / magnitude) * magnitude == direction