Raycast passing through wall

Hello! I made a weapon system, but when I put the weapon inside the wall, it shoots inside the wall and goes through walls

i have the local and server code

Local code

-- feel free to use it in other games :3 -- credit is appreciated, but totally up to you! local Workspace = game:GetService("Workspace") local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local tool = script.Parent local equipped = true local player = Players.LocalPlayer local character = player.Character or player.CharacterAdded:Wait() local head = character:WaitForChild("Head") local humanoid = character:WaitForChild("Humanoid") local playerGui = player:WaitForChild("PlayerGui") local mobileShiftlockGui = playerGui:WaitForChild("ShiftlockGui") local shiftlockOn = mobileShiftlockGui:WaitForChild("ShiftlockOn") local mouse = player:GetMouse() local fireWeapon = tool:WaitForChild("FireWeapon") local camera = Workspace.CurrentCamera tool.Parent = character local tapStart = 0 local TAP_THRESHOLD = 0.2 local onIcon = "rbxassetid://79658449" local offIcon = "" Workspace:GetPropertyChangedSignal("CurrentCamera"):Connect(function()	camera = Workspace.CurrentCamera end) player.CharacterAdded:Connect(function(newCharacter)	character = newCharacter	head = newCharacter:WaitForChild("Head")	humanoid = newCharacter:WaitForChild("Humanoid") end) local raycastParams = RaycastParams.new() raycastParams.FilterType = Enum.RaycastFilterType.Exclude raycastParams.FilterDescendantsInstances = {character} raycastParams.IgnoreWater = true raycastParams.RespectCanCollide = true local function shoot()	if not equipped or not tool.Enabled or humanoid.Health <= 0 then	return	end	local targetPosition	local isFirstPerson = camera and (camera.CFrame.Position - head.Position).Magnitude < 2 or shiftlockOn.Value	if isFirstPerson and camera then	local viewportSize = camera.ViewportSize	local screenCenter = Vector2.new(viewportSize.X / 2, viewportSize.Y / 2)	local ray = camera:ViewportPointToRay(screenCenter.X, screenCenter.Y)	local rayOrigin = ray.Origin	local rayDirection = ray.Direction * 400	local result = Workspace:Raycast(rayOrigin, rayDirection, raycastParams)	if result then	targetPosition = result.Position	else	targetPosition = rayOrigin + rayDirection	end	else	targetPosition = mouse.Hit.Position	end	if targetPosition then	fireWeapon:FireServer(targetPosition)	end end UserInputService.TouchStarted:Connect(function(input, gameProcessedEvent)	if not gameProcessedEvent then	tapStart = tick()	end end) UserInputService.TouchEnded:Connect(function(input, gameProcessedEvent)	if gameProcessedEvent then	return	end	local tapDuration = tick() - tapStart	if tapDuration < TAP_THRESHOLD and equipped and tool.Enabled and humanoid.Health > 0 then	shoot()	end end) UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)	if input.UserInputType == Enum.UserInputType.MouseButton1 or input.KeyCode == Enum.KeyCode.ButtonR2 and not gameProcessedEvent and equipped and tool.Enabled and humanoid.Health > 0 then	shoot()	end end) tool.Unequipped:Connect(function()	mouse.Icon = offIcon	equipped = false	tool.Enabled = false end) tool.Equipped:Connect(function()	mouse.Icon = onIcon	equipped = true	tool.Enabled = true end) 

Server code

local ReplicatedStorage = game:GetService("ReplicatedStorage") local Players = game:GetService("Players") local Debris = game:GetService("Debris") local Workspace = game:GetService("Workspace") local tool = script.Parent local handle = tool:WaitForChild("Handle") local shotPart = handle:WaitForChild("ShotPart") local hitSound = handle:WaitForChild("Hit") local fireSound = handle:WaitForChild("Fire") local reloadSound = handle:WaitForChild("Reload") local reloadTime = reloadSound.TimeLength local eventsFolder = ReplicatedStorage:WaitForChild("Events") local playerKilledEvent = eventsFolder:WaitForChild("KilledEvent") local player repeat	task.wait()	player = Players:GetPlayerFromCharacter(tool.Parent) until player local character = tool.Parent local humanoid = character:WaitForChild("Humanoid") local animations = {	R6 = {	Shoot = "rbxassetid://79982511838181",	Idle = "rbxassetid://137613173471058",	Reload = "rbxassetid://98606465452921",	},	R15 = {	Shoot = "rbxassetid://82248551381958",	Idle = "rbxassetid://134190544576252",	Reload = "rbxassetid://91459325337687",	} } local function killedFunction(killer, victim)	if killer and victim then	playerKilledEvent:Fire(killer, victim)	end end local function raycast(origin, direction, blacklist, range)	local params = RaycastParams.new()	params.FilterType = Enum.RaycastFilterType.Exclude	params.FilterDescendantsInstances = blacklist	params.IgnoreWater = true	local result = Workspace:Raycast(origin, direction.Unit * range, params)	if result then	return result.Instance, result.Position	end end local function createBullet(position, color)	local bullet = Instance.new("Part")	bullet.Shape = Enum.PartType.Ball	bullet.Size = Vector3.new(0.1, 0.1, 0.1)	bullet.Material = Enum.Material.SmoothPlastic	bullet.CanCollide = false	bullet.Anchored = true	bullet.CastShadow = false	bullet.Color = color	bullet.CFrame = CFrame.new(position)	bullet.Parent = Workspace:FindFirstChild("Bullets") or Workspace	Debris:AddItem(bullet, 5)	return bullet end local function createTrail(startPosition, endPosition)	local distance = (endPosition - startPosition).Magnitude	local midPoint = (startPosition + endPosition) / 2	local trail = Instance.new("Part")	trail.Size = Vector3.new(0.1, 0.1, distance)	trail.Anchored = true	trail.CanCollide = false	trail.Material = Enum.Material.Neon	trail.Color = Color3.fromRGB(255, 255, 255)	trail.CFrame = CFrame.new(midPoint, endPosition)	trail.Parent = Workspace	Debris:AddItem(trail, 0.1) end local humanoid = character:WaitForChild("Humanoid") local animator = humanoid:FindFirstChildOfClass("Animator") or Instance.new("Animator", humanoid) local rigType = humanoid.RigType == Enum.HumanoidRigType.R6 and "R6" or "R15" local shootAnim = Instance.new("Animation") shootAnim.AnimationId = animations[rigType].Shoot local shootTrack = animator:LoadAnimation(shootAnim) local idleAnim = Instance.new("Animation") idleAnim.AnimationId = animations[rigType].Idle local idleTrack = animator:LoadAnimation(idleAnim) idleTrack.Looped = true idleTrack:Play() local reloadAnim = Instance.new("Animation") reloadAnim.AnimationId = animations[rigType].Reload local reloadTrack = animator:LoadAnimation(reloadAnim) local function shoot(_, target)	if not tool.Enabled or humanoid.Health <= 0 then	return	end	local direction = (target - shotPart.Position).Unit	local hitPart, hitPos = raycast(shotPart.Position, direction, {character, handle, shotPart}, 400)	tool.Enabled = false	fireSound:Play()	shootTrack:Play()	if hitPos then	createBullet(hitPos, hitPart and hitPart.Color or Color3.fromRGB(255, 255, 255))	createTrail(shotPart.Position, hitPos)	if hitPart and hitPart.Parent then	local hitHumanoid = hitPart.Parent:FindFirstChildOfClass("Humanoid")	if hitPart.Parent:IsA("Accessory") or hitPart.Parent:IsA("Hat") then	hitHumanoid = hitPart.Parent.Parent:FindFirstChildOfClass("Humanoid")	end	if hitHumanoid and hitHumanoid ~= humanoid and hitHumanoid.Health > 0 and not (hitPart.Parent:FindFirstChildWhichIsA("ForceField") or hitPart.Parent.Parent:FindFirstChildWhichIsA("ForceField")) then	if fireSound.Playing then	fireSound:Stop()	end	hitSound:Play()	hitHumanoid.Health = 0	killedFunction(player, Players:GetPlayerFromCharacter(hitHumanoid.Parent))	end	end	end	task.wait(0.5)	if not reloadTrack.IsPlaying then	reloadSound:Play()	reloadTrack:Play()	end	task.wait(reloadTime)	tool.Enabled = true end tool.Equipped:Connect(function()	idleTrack:Play() end) tool.Unequipped:Connect(function()	if idleTrack.IsPlaying then	idleTrack:Stop()	end	if reloadTrack.IsPlaying then	reloadTrack:Stop()	end	if shootTrack.IsPlaying then	shootTrack:Stop()	end end) local fireEvent = tool:WaitForChild("FireWeapon") fireEvent.OnServerEvent:Connect(shoot) 
1 Like

“shotpart” is inside the wall whenever you shoot, it should be used for visualization rather than actually firing from it, use humanoidrootpart, or head, depends on what you’re looking for i suppose

1 Like

If a raycast starts inside of a part, that part will not collide with the raycast. Try casting from the HumanoidRootPart or Head instead!

2 Likes

But if I shoot something up close it will be inaccurate (sorry for my English, I’m translating this from the translator)

A solution i’ve seen be used is that from the server you raycast from the shoot part to the HumanoidRootPart/Head, i don’t have any code example unfortunately, but that’s something you can try

Not exactly what i had in mind, but what is the issue? the raycast from the shoot part to the model should be a debounce and not interfere with the actual gun

use this as reference:

local function GetDestination()	local MouseLocation = UserInputService:GetMouseLocation()	local UnitRay = CurrentCamera:ViewportPointToRay(MouseLocation.X, MouseLocation.Y)	local origin, direction = UnitRay.Origin, UnitRay.Direction * 1024	local RaycastResult = workspace:Raycast(origin, direction, RaycastParams)	local destination = RaycastResult and RaycastResult.Position or origin + direction	createVisual(destination, RaycastResult and Color3.new(1, 1, 0) or Color3.new())	return destination end local function OnActivated()	local destination = GetDestination()	local origin = RootPart:GetPivot().Position	local direction = (destination - origin).Unit * 1024	local RaycastResult = workspace:Raycast(origin, direction, RaycastParams)	local pos = RaycastResult and RaycastResult.Position or origin + direction	createVisual(pos, RaycastResult and Color3.new(0, 1, 0) or Color3.new(1, 0, 0)) end 

you should set the ray origin to head or something.

I don’t know what would happen for third person, but I think it is a common issue for most fps games though


I remember once I saw this ridiculous scene on some Valorant pro league. (sorry I couldnt find a video)

2 Likes

I made a raycast from hrp, but the trail came from the shootpart

Do a raycast from the HumanoidRootPart to check if it hits a wall. If theres no wall, do the shooting raycast from the gun.

Edit: Make the raycast from the HumanoidRootPart be slightly longer than the distance from the HumanoidRootPart to the tip of the gun

1 Like

Don’t change the ray cast for the bullet itself, check if the player character and the shoot part can see each other in a separate ray cast