How do i detect if the raycast hit a part near another player

I have this weapon script wich was built around the old raycast system and i got it modified. However
i have a problem.

I want when a player shoots near another player. That another player hears a crack sound/bullet passing sound

-- GunScript_Local (CLIENTSIDE)
local rayOrigin = Start
		local rayDirection = Direction + AcceptedUnit * Range

		local rayParams = RaycastParams.new()
		rayParams.FilterDescendantsInstances = {Character}
		rayParams.FilterType = Enum.RaycastFilterType.Blacklist
		BulletRay = workspace:Raycast(rayOrigin, rayDirection, rayParams)

		local Hit, EndPos = nil, rayDirection
		if BulletRay then
			Hit = BulletRay.Instance
			EndPos = BulletRay.Position	
		end
		BulletRay = Ray.new(rayOrigin, rayDirection)
-- BULLETVISUALIZER SCRIPT PROJECTED ON EVERY CLIENT (CLIENTSIDE)
				 for _,P in ipairs(game.Players:GetChildren()) do
					if P.Character then
						if P.Character:FindFirstChild("Torso") then
							if BulletRay.Unit:Distance(P.Character.Torso.Position) --[[and P ~= game.Players.LocalPlayer]] then
								--print('cracking bullet for ' .. P.Name)
								BulletPass(P, BulletRay.Unit:Distance(P.Character.Torso.Position))
							end
						end
					end
				end

function BulletPass(Player, Distance)
	if Distance > 2 and Distance < 10 then
		local BulletCrackFX = script.Crack
		BulletCrackFX.SoundId = 'rbxassetid://' .. BulletCracks[math.random(1, #BulletCracks)]
		local CrackFXClone = BulletCrackFX:Clone()
		if Player:FindFirstChild('PlayerGui') then
			CrackFXClone.Parent = Player.PlayerGui
			CrackFXClone:Play()
		end
		game:GetService("Debris"):AddItem(CrackFXClone, CrackFXClone.TimeLength)
	end
end

My Problem is that sometimes i get the error “Unit isnt a valid member of Ray”. If i dont get that error then no ray at all gets projected plus the impact sound dosent appear plus no Impact decal appears.
https://i.gyazo.com/dc59e7bd47cd4fb946c8da4aa3ea632f.mp4

https://i.gyazo.com/85f4c091061ebb77d07ffdbbcaeabaf0.mp4

Why don’t you just do

for _,P in ipairs(game.Players:GetChildren()) do
					if P.Character then
						if P.Character:FindFirstChild("Torso") then
                            local mag  = (BulletRay.Position-Character.Torso.Position).Magnitude
							if  mag   <= 5 --[[and P ~= game.Players.LocalPlayer]] then
								--print('cracking bullet for ' .. P.Name)
								BulletPass(P, mag )
							end
						end
					end
				end

Here Im giving 5 as an example distance , you could change it to anything you want.
Also I don’t know why you are checking for Torso , but you can just get the difference from the HumanoidRootPart.

1 Like

Bro that was like that. Whats better torso or humanoidrootpart ?

EDIT: I also get the error now
Position is not a valid member of Ray

First of all remove this BulletRay = Ray.new(rayOrigin, rayDirection) and then just add a check if BulletRay then above the for loop also or you could just check if EndPos then and replace it with BulletRay.Position , HumanoidRootPart would be better since it exists for both R15 and R6

EDIT : I would advise you to use Local functions over Global functions , Global variables are stored in a heap which has a more complex structure where as local variables are stored in stack therefore Global variables take much more time to index.

This is my idea. Make a small, temporary, invisible part where the raycast was hit (where the bullet hit). Insert the sound into the part, have it play, then have the part deleted.

Make sure to have the script check if the part that the ray hit was a player or not. Also, set the RollOffMaxDistance on the sound to the desired distance that the player needs to be in order to hear the bullet crack. This is all done on the server side, the script that handles the raycast.

i fixed this solution by not trying at all. xD

Big problem is that the whole gunscript was build around the old ray functions. I will just try to find a new and better gun template if avaible and modify it to my needs.

if i change it into local it dosent work anymore

You have to define it above where you call the function , making a global function is not an efficient workaround for that.