Do you use FindPartOnRayWithIgnoreList
?
Yes
Try to get close to an ignore part that was included in the table like I did in the gif, did that happen? If not, can you try to provide a gif? Thanks.
Can you demonstrate it like mine? Get as close as you can to the brick.
It doesn’t look like you got any solution to this last problem when you got close to the red brick, this is because of the way angles are calculated.
The red brick may be ignored by the ray, but it’s not ignored by the mouse. Sorry if you found a solution for this prior, but this is my take on it.
You’re right, I tried to put all characters inside a Model and link Mouse.TargetFilter to it, but sometimes when your mouse is pointed directly to the character, the ray will completely ignore the character and go straight behind (maybe next to the character)
Currently I found a solution, I give up on using Mouse.TargetFilter. I put all the ignoring parts inside a table, then link it with FindFirstRayWithIgnoreList. I also start casting the ray from the character’s torso instead of the ShootingPart, but keeping all visual effect from the ShootPart, this is an ultimate solution because it can also prevent from shooting through walls, so far I don’t encounter any problems that I mentioned above.
An easy way to fix the issue with weird angles (as OP @Headstackk and @Sunx_x showcased) is to use Mouse.UnitRay, which casts a ray that originates from the CurrentCamera. You would have to construct another Ray using Mouse.UnitRay’s properties (Ray.Direction, Ray.Origin) for the distance though, as it’s a unit ray
You can also use Camera::ScreenPointToRay which you also have to re-construct the ray (since both Mouse.UnitRay and Camera::ScreenPointToRay are both unit rays)
Using the property / function I mentioned above, I was able to make this: https://gyazo.com/1ced7a2ef20441f7c8fc782ac4f0e13e
This is almost certainly the best way to do it. Sure you can mess around with collection service and what not, but if you’re dumping a gigantic array of parts in the FindPartOnWayWithIgnoreList function it’s not going to be more efficient, so why go through all that trouble?
Here’s a basic one, I think it actually started life in the Roblox jeep some years back. It has a re-entry limit so it wont crash if by some weird bug it ends up in an infinite loop, or if you point it at a clump of thousands of parts or something. It’s currently set to ignore bricks with can collide off or with a transparency higher than 0.9, but you can set it to ignore whatever you want by changing
collide = (hit.CanCollide and hit.Transparency < 0.9)
function module.new(startPosition, offset, ignoreList)
if not ignoreList then ignoreList = {} end
local reEntry = 0
local maxDistance = offset.magnitude
local direction = offset.unit
local lastPosition = startPosition
local distance = 0
local ignore = ignoreList
local hit, position, normal, material
local collide
repeat
reEntry = reEntry + 1
local ray = Ray.New(lastPosition, direction * (maxDistance - distance))
hit, position, normal, material = workspace:FindPartOnRayWithIgnoreList(ray, ignore, false, true)
if hit then
collide = (hit.CanCollide and hit.Transparency < 0.9)
if not collide then
table.insert(ignore, hit)
end
end
distance = (startPosition - position).magnitude
lastPosition = position
until distance >= maxDistance or collide or reEntry > 10
if reEntry > 10 then
warn("Raycast reentry limit exceeded! Ray from: ", startPosition, "Heading:", offset)
end
return hit, position, normal, material
end
Since it also has an ignore list as an optional parameter, you could also use it with collection service, so you don’t have to manually tag every single cancollide off part that ever gets created in your game but you can still tag parts to be ignored that are cancollide and not transparent if you ever need to do so.
You can then also use this in place of Mouse.Hit so that you don’t end up with the gun problem shown a few posts above when near parts you can shoot thorugh. (Especially if your map uses large invisible parts!) When the player clicks, just use the following code
local RaycastModule = require(The Above Module)
local DISTANCE = 200 --How far the players click will travel to find a target before stopping
function GetMouseHit()
local Hit, Position = RaycastModule.new(Mouse.UnitRay.Origin, Mouse.UnitRay.Direction * DISTANCE)
return Hit, Position
end
Or a similar method using Auhrii’s module instead.
For me personally, first I have a table of things I want to ignore by default.
Then I make a propetries table for things i want to get in the raycast.
local function FilteredRaycast(ray, propertyFilterTable, IgnoreList)
if not IgnoreList then IgnoreList = {} end
local part
repeat
local p = workspace:FindPartOnRayWithIgnoreList(ray, IgnoreList)
if p then
local IsFiltered = true
for k,v in pairs(propertyFilterTable) do
if p[k] ~= v then
IsFiltered = false
end
end
if IsFiltered then
part = p
else
table.insert(IgnoreList, p)
end
else
break -- Ray failed to hit anything
end
until part
return part
end
local p = FilteredRaycast(Ray.new(), {CanCollide = true})
-- Please note that I just wrote this on the forum and this script is untested,
-- This is just an example of what I usually do
I kept hitting tab trying to indent code and ended up saving edits before I was done, I apologize for the many edits
Untested, but is it really a good way?
- Create collision groups
-
Set the raycast into Collision group
raycastParams.CollisionGroup = 'Raycast'
-
Set the anti raycast parts into Collision group
local physicsService = game:GetService('PhysicsService') for _, part in pairs(workspace:GetDescendants()) do if part:IsA('Accessory') then physicsService:SetPartCollisionGroup(part.Handle, 'AntiRaycast') print(part) end end
was this ever solved? becuase there might be other people looking for the same solution. (im not looking for a solution cuase i’ve got my own)
I’d do a raycast with a whitelist or blacklist which ever is smaller
This will most of the time work with the new raycast
I know this post Is old, but if you encounter this issue, you could either create a folder and put all the parts (might also be recommended to turn off CanQuery) that you want to be ignored In there or create a script that turns off CanQuery for your character’s hats whenever the character spawns
--[[
Creates a loop to check if any new hats were added.
You can use ChildAdded instead, but I prefer this loop.
]]
while wait() do
local d = script.Parent:GetChildren()
for i=1, #d do
if (d[i].className == "Accessory") or (d[i].className == "Hat") then
d[i].Handle.CanQuery = false
--LAYERED CLOTHING REMOVAL--
--[[elseif (d[i]:FindFirstChild("Handle")) and (d[i].Handle:FindFirstChildOfClass("WrapLayer")) then
d[i]:Destroy()]]
end
end
end
try adding workspace:GetDescedants above descedantadded and do the same check as descedant added. dont delete the descedant added check because it is needed to work too.