Improving a Gun System

I’m making a gun system and it works the way I have it, but sometimes it doesn’t shoot backwards correctly, it can hit the tool handle on accident, and I don’t think it works on mobile. I think my main issue is raycasting since I’ve never really worked with rays before. Any improvements or suggestions would help.

Local Script:

	reloading = false
	local shootEvent = rStorage.Shot
	local mouse = player:GetMouse()
	character.ChildAdded:Connect(function(child)
		if child:IsA("Tool") then
			child.Activated:Connect(function()
				if not reloading then
					reloading = true; plrGui:WaitForChild("MainGame").Reloading.Visible = true
					local head = character:FindFirstChild("Head")
					local headLookVector = head.CFrame.LookVector
					local shootMouse = CFrame.new(head.Position, mouse.Hit.Position).LookVector
					local distance = (headLookVector-shootMouse)
					local gunRayParams = RaycastParams.new(); gunRayParams.FilterType = Enum.RaycastFilterType.Blacklist
					gunRayParams.FilterDescendantsInstances = {character}
					local gunRayResult = workspace:Raycast(head.Position, (mouse.Hit.Position-head.Position).Unit*300)
					local rayInstance; local pos
					if gunRayResult then
						rayInstance = gunRayResult.Instance
						pos = gunRayResult.Position
					end
					shootEvent:FireServer(rayInstance, pos, child)
					local dt = 0
					while dt <= 2 do
						dt += runService.RenderStepped:Wait()
					end
					reloading = false; plrGui:WaitForChild("MainGame").Reloading.Visible = false
				end
			end)
		end
	end)

Server Script:

rStorage.Shot.OnServerEvent:Connect(function(player, part, pos, tool)
		local statsFolder = player.StatsFolder
		tool.ShotSound:Play()
		if part and pService:FindFirstChild(part.Parent.Name) ~= player then
			local distance = (tool.Handle.Position-pos).Magnitude
			local gunTrail=Instance.new("Part");gunTrail.Anchored=true;gunTrail.BrickColor=BrickColor.new("Institutional white")
			gunTrail.CFrame=CFrame.new(tool.Handle.Position,pos)*CFrame.new(0,0,-distance/2);gunTrail.Transparency=.8;gunTrail.CanCollide=false
			gunTrail.Size=Vector3.new(.1,.1,distance);gunTrail.Parent=workspace
			local humanoid = part.Parent:FindFirstChild("Humanoid")
			if humanoid and humanoid.Health > 0 and not part.Parent:FindFirstChildOfClass("ForceField") then
				humanoid.Health -= humanoid.MaxHealth
				statsFolder.KillsValue.Value += 1
				if part.Name == "Head" then
					tool.Headshot:Play()
					statsFolder.SilverValue.Value += math.floor(25*statsFolder.StatMultiplier.Value)
				else
					statsFolder.SilverValue.Value += math.floor(10*statsFolder.StatMultiplier.Value)					
				end
			end
			local gunTrailFade = twService:Create(gunTrail, TweenInfo.new(0.5), {Transparency = 1, Size = Vector3.new(0,0,distance)})
			gunTrailFade:Play(); gunTrailFade.Completed:Wait()
			gunTrail:Destroy()
		end
	end)

I’d recommend checking if the gun is reloading server-side, otherwise it could be bypassed, and exploiters would be able to shoot when the gun is reloading.

In terms of raycasting, you should add the tool to your rayGunParams.FilterDescendantInstances, as well as use your rayGunParams as the third argument to workspace:Raycast(). These changes should resolve your issues with raycasting.

4 Likes

Wow I can’t believe I made those parameters and didn’t even add them to the raycast. Always great to have someone check over your code for you :sweat_smile:

2 Likes