I’m currently making a gun and to make it shoot I cast a ray to mouse.Hit.p and search for a humanoid of the parent of the Instance of the ray:
local Bullet = workspace:Raycast(Origin, (HitPos - Origin).unit * 1000,BulletParams)
if Bullet then
if Bullet.Instance.Name ~= "Head" then
local hum = Bullet.Instance.Parent:FindFirstChild("Humanoid")
end
end
Only problem with this is that if the ray hits an accessory that the player is wearing, it will not detect the humanoid and therefore do no damage. My work around for this is if the Ray hits an accessory it will add that accessory to it’s ignore list and recast the ray to the same position. To my disappointment I figured out that you can’t table.insert anything into raycastParams.FilterDescendantsInstances from this post.
Is there any work from this? I could just use Ray.new() instead of WorldRoot:Raycast() but I don’t want to use deprecated methods that I’m not used to.
It’s basically whitelisting parts to that collision group only.
This would require you to set the collision group of all parts you want ignored into a separate group. It’s better then having to recast multiple rays whenever an accessory is hit. You can set the accessory parts to a collision group when the character spawns.
This worked but it’s acting kind of strange. The accessory does get added to the ignore list but the ray doesn’t ignore it. You can see in this video, the table is the ignore list and what is being printed above it is what the ray is hitting.
“Handle” is a child of the accessory so if I’m not mistaken it should get ignored.
The easiest solution is my eyes is the collision group.
You can simply just add the accessory parts into a specified collision group when the character respawns. Instead of having to loop through all characters.
Player.CharacterAdded:Connect(function(character)
-- Add all accessory parts into a collision group that ingores default collisions.
end)
Sorry, I should’ve done a bit more testing before marking it as the solution. It seemed to work the first time and then randomly stopped working. In the script where I cast the ray I have these loops to put all accessories into the “Ignored” collision group.
local PhysicsService = game:GetService("PhysicsService")
PhysicsService:CreateCollisionGroup("Ignored")
for i,v in pairs(workspace:GetChildren()) do
if v:IsA("Model") then
for i,ModelPart in pairs(v:GetChildren()) do
if ModelPart.Name == "Humanoid" then
for i, Accessory in pairs do
if Accessory:IsA("Accessory") then
for i,AccessoryDescendants in pairs(Accessory:GetDescendants()) do
PhysicsService:SetPartCollisionGroup(AccessoryDescendants, "IgnoredParts")
end
end
end
end
end
end
end
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(char)
for i,Accessory in pairs(char:GetChildren()) do
if Accessory:IsA("Accessory") then
for i,AccessoryDescendants in pairs(Accessory:GetDescendants()) do
PhysicsService:SetPartCollisionGroup(AccessoryDescendants, "Ignored")
end
end
end
end)
end)
BulletParams.CollisionGroup = "Ignored"
It doesn’t seem to ignore the accessories. Is everything here correct? I have very minimal knowledge of CollisionGroups as I haven’t worked with them much so I very well could have something incorrect.
An issue that can arise is the charatcer not being able to load all accessories on the time of spawn. You could instead hook a ChildAdded event to the character and check if that child is an accessory. If so, add it to the ignore group. This code was tested and works on studio.
Take note that every game has a Default collision group. Which encapsulates regular collisions. You can set the hat collision group to not collide with the Default collision group. (Basically everything else in the game)
local Players = game:GetService("Players");
local PhysicsService = game:GetService("PhysicsService");
local HatsCollisionGroupName = "IgnoreHats"
PhysicsService:CreateCollisionGroup(HatsCollisionGroupName); -- Creates the collision group
PhysicsService:CollisionGroupSetCollidable("Default", "IgnoreHats", false); -- Hats cannot collide with the Default group.
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
character.ChildAdded:Connect(function(child) -- Every object added into the character, we check if it's an accessory
if child:IsA("Accessory") then
for i,d in pairs(child:GetDescendants()) do -- Loop through the accesories descendants
if (d:IsA("BasePart")) then
PhysicsService:SetPartCollisionGroup(d, HatsCollisionGroupName); -- Adds any basepart descendant to the ignore group
end
end
end
end)
end)
end)
local rayparams = RaycastParams.new();
rayparams.CollisionGroup = "Default"; -- Only allow collision with parts that have the Default collision group
you can also just make any exclusion that has cancollide set to false by disabling canquery, as for parts that can collide you can make a function, add a local table inside the function. You want to loop through the children of workspace, or descendants (if neccessary) and specifcy objects and insert them in the table then outside the loop make the function return the table, and set the RaycastParams.FilterDescendantsInstances to the function.
It would go something like this:
-- Imaginary Beam between 2 parts except with your blacklisting need
local Part1 = workspace:FindFirstChild("ImaginaryPart")
local Part2 = workspace:FindFirstChild("ImaginaryPart2")
local function GenerateBlackList()
local BlackList = {}
for x, instance in pairs(workspace:GetDescendants()) do
if instance:IsA("Accessory") then
table.insert(BlackList, instance)
end
end
return BlackList
end
local RayOptions = RaycastParams.new()
RayOptions.FilterDescendantsInstances = GenerateBlackList
RayOptions.FilterType = Enum.RaycastFilterType.Blacklist
local RAY_CAST = workspace:Raycast(Part1.Position, (Part2.Position - Part1.Position).Unit * 1000, RayOptions)
print(RAY_CAST)
-- if you step in between the two parts during the ray but only your accessory is in the way it will go right through it since it is of the accessory class
-- the ray will succesfully hit the part2