Gun System is not working correctly

So I made custom Gun, and its almost like what I want, but it has a couple bugs. It cannot take damage from the player (sometimes). It can also (sometimes) create the bullet, but won’t make a the bullet where the players mouse in pointing. Otherwise, it will work most of the time. Let me know what I can do, sense I’m struggling to make it work correctly.

Server (Normal Script in Tool):

local tool = script.Parent
local shoot_part = tool:WaitForChild("Handle")
local remote = tool:WaitForChild("OnShoot")

local Workspace = game:GetService("Workspace")
local ServerStorage = game:GetService("ServerStorage")

remote.OnServerEvent:Connect(function(player, position)
	local origin = shoot_part.Position
	local direction = (position - origin).Unit*300
	local result = Workspace:Raycast(origin, direction)

	local intersection = result and result.Position or origin + direction
	local distance = (origin - intersection).Magnitude

	local bullet_clone = ServerStorage.Bullet:Clone()
	bullet_clone.Size = Vector3.new(0.1, 0.1, distance)
	bullet_clone.CFrame = CFrame.new(origin, intersection)*CFrame.new(0, 0, -distance/2)
	bullet_clone.Parent = Workspace
	
	local PlayerName = Instance.new("StringValue")
	PlayerName.Name = "Attacker"
	PlayerName.Value = player.Name
	PlayerName.Parent = bullet_clone

	if result then
		local part = result.Instance
		local humanoid = part.Parent:FindFirstChild("Humanoid") or part.Parent.Parent:FindFirstChild("Humanoid")

		if humanoid and humanoid.Parent.Name ~= bullet_clone.Attacker.Value then
			humanoid:TakeDamage(math.random(10,14))
			print("Humanoid is shot.")
			local db = false
			if humanoid.Health <= 0 then
				if db == false then
					db = true
					player.leaderstats.Points.Value += 15
					task.wait(1.2)
					db = false
				end
			end
		end
	end

	wait(0.25)
	bullet_clone:Destroy()
end)

Client (LocalScript in Tool):

local tool = script.Parent
local remote = tool:WaitForChild("OnShoot")
local maxAmmo = 14
local CoolDown = 0.002
local ammo = maxAmmo
local reloading = false

local Players = game:GetService("Players")
local client = Players.LocalPlayer
local cursor = client:GetMouse() 
local CAS = game:GetService("ContextActionService")
local Camera = game:GetService("Workspace").CurrentCamera

local plrgui = client.PlayerGui
local text = plrgui:WaitForChild("Ammo").AmmoCount

local BoolValue = script.Parent:WaitForChild("EquippedValue")

local ZoomTypes = { Enum.UserInputType.MouseButton2, Enum.KeyCode.ButtonL2 }
local ReloadTypes = { Enum.KeyCode.R, Enum.KeyCode.ButtonX }
local FireTypes = { Enum.UserInputType.MouseButton1, Enum.KeyCode.ButtonR2 }
local gunCooldown = false

local function GunHandler(ActionName, inputState, inputObject)
	if ActionName == "WeaponZoom" and BoolValue.Value and inputState == Enum.UserInputState.Begin and (table.find(ZoomTypes, inputObject.UserInputType) or table.find(ZoomTypes, inputObject.KeyCode)) then
		Camera.FieldOfView = 40
		client.Character:WaitForChild("Humanoid").WalkSpeed = 14.5
		plrgui:WaitForChild("HotBarGUI").Enabled = false
	end

	if ActionName == "WeaponZoom" and inputState == Enum.UserInputState.End and (table.find(ZoomTypes, inputObject.UserInputType) or table.find(ZoomTypes, inputObject.KeyCode)) then
		Camera.FieldOfView = 70
		client.Character:WaitForChild("Humanoid").WalkSpeed = 17.5
		plrgui:WaitForChild("HotBarGUI").Enabled = true
	end

	if ActionName == "Reload" and BoolValue.Value and table.find(ReloadTypes, inputObject.KeyCode) and not reloading then
		reloading = true
		tool.Handle.reload:Play()
		task.wait(1)
		ammo = maxAmmo
		reloading = false
	end

	if ActionName == "FireWeapon" and BoolValue.Value and (table.find(FireTypes, inputObject.UserInputType) or table.find(FireTypes, inputObject.KeyCode)) and not reloading and ammo > 0 and not gunCooldown then
		gunCooldown = true
		ammo = ammo - 1
		task.wait(CoolDown)
		remote:FireServer(cursor.Hit.Position)
		tool.Handle.gunshot:Play()
		tool.Handle.PointLight.Enabled = true
		task.wait(0.2)
		tool.Handle.PointLight.Enabled = false
		task.delay(CoolDown, function() gunCooldown = false end)
	elseif ActionName == "FireWeapon" and BoolValue.Value and (table.find(FireTypes, inputObject.UserInputType) or table.find(FireTypes, inputObject.KeyCode)) and not reloading and not gunCooldown then
		reloading = true
		tool.Handle.reload:Play()
		task.wait(1)
		ammo = maxAmmo
		reloading = false
		tool.Handle.gunshot:Stop()
	end
end

task.spawn(function()
	while true do
		text.Text = (ammo).." / "..tostring(maxAmmo)
		task.wait()
	end
end)

tool.Equipped:Connect(function()
	BoolValue.Value = true

	cursor.Icon = "rbxassetid://42445293"

	plrgui.Ammo.Enabled = true
	text.DisableScript.Disabled = true
	plrgui.Shop.Enabled = false
	plrgui.Inventory.Enabled = false

	CAS:BindAction("FireWeapon", GunHandler, true, Enum.UserInputType.MouseButton1, Enum.KeyCode.ButtonR2)
	CAS:BindAction("Reload", GunHandler, true, Enum.KeyCode.R, Enum.KeyCode.ButtonX)
	CAS:BindAction("WeaponZoom", GunHandler, true, Enum.UserInputType.MouseButton2, Enum.KeyCode.ButtonL2)

end)

script.Parent.Unequipped:Connect(function()
	plrgui.Ammo.Enabled = false
	text.DisableScript.Disabled = false
	plrgui.Shop.Enabled = true
	plrgui.HotBarGUI.Enabled = true
	plrgui.Inventory.Enabled = true

	BoolValue.Value = false

	Camera.FieldOfView = 70
	client.Character:WaitForChild("Humanoid").WalkSpeed = 17.5
	plrgui:WaitForChild("HotBarGUI").Enabled = true

	CAS:UnbindAction("FireWeapon")
	CAS:UnbindAction("Reload")
	CAS:UnbindAction("WeaponZoom")
end)

Let me know what I can do to fix the problem.

Sincerely,

papahetfan

1 Like

Instead of raycasting use this

T = Interation
p0 = Origin Position
p1 = Height Vector
p2 = Destination

function lerp(a, b, c)
	return a + (b - a) * c
end
local function BezierCurve(t, p0, p1, p2)
	
		local l1 = lerp(p0, p1, t)
		local l2 = lerp(p1, p2, t)
	        local quad = lerp(l1, l2, t)
	
		
	
	
	return quad

end

also if you wondering how to get height vector this is how:

local H = 5
local Height = Origin - ((Origin-Destination)/Vector3.new(2,2,2))
	
	Height = Height + Vector3.new(0,H,0)

Destination would equal to = mouse.hit.Position and Origin would equal to humanoidrootpart.Position

So where would I have to put those 2 parts in the script(s)?

robloxapp-20220624-1055011.wmv (1.1 MB)
I made a place where I made it working so you can copy it from the as it is uncopylocked.

But here are the scripts too, if you wanna add the things in replicatedStorage yourself.
GunModuleScript:

function lerp(a, b, c)
	return a + (b - a) * c
end

local PistolModule = {}

function PistolModule.BezierCurve(t, p0, p1, p2)

	local l1 = lerp(p0, p1, t)
	local l2 = lerp(p1, p2, t)
	local quad = lerp(l1, l2, t)




	return quad

end

return PistolModule

GunScript

local PistolModule = require(script.Parent)

local replicatedStorage = game:GetService("ReplicatedStorage")

local Curve = 1.2 

local breaker = false

local wWorkspace = game:GetService("Workspace")

local RS = game:GetService("RunService")

replicatedStorage.FlightEnd.Event:Connect(function()
	
	breaker = true
	
end)

replicatedStorage.GunFired.OnServerEvent:Connect(function(plr, origin, destination)
	
	
	local Height = origin - ((origin-destination)/Vector3.new(2,2,2))

	Height = Height + Vector3.new(0,Curve,0)
	
	local Bullet = replicatedStorage.Bullet:Clone()
	
	Bullet.Parent= wWorkspace
	
	for Iteration = 0, 1000, 0.1 do
	
		local CurrentVector = PistolModule.BezierCurve(Iteration, origin, Height, destination)
		
		Bullet.Position = CurrentVector
		
		if breaker==true then
			
			break
			
		end
		
		RS.Heartbeat:Wait()
		
	end
	
	
end)

GunLocalSCript

local players = game:GetService("Players")
local plr = players.LocalPlayer

local tool = script.Parent.Parent
local equipped = false
local activated = false

local mouse = plr:GetMouse()

local FireDelta = os.time()
local fireCooldown = .5
local LightAndSmokeEffectDelay = .4

local connection

local replicatedStorage = game:GetService("ReplicatedStorage")

local function GunShootEffect()
	task.wait(LightAndSmokeEffectDelay)
	tool.Handle.PointLight.Enabled = true
	task.wait(LightAndSmokeEffectDelay)
	tool.Handle.PointLight.Enabled = false
	
end

tool.Equipped:Connect(function()
	equipped=true
	activated=false
	
	if connection then
		connection:Disconnect()
		connection = nil
	end
end)

tool.Unequipped:Connect(function()
	equipped=false
	activated=false
	
	if connection then
		connection:Disconnect()
		connection = nil
	end
end)

tool.Activated:Connect(function()
	if equipped==true and activated==false then
		if FireDelta < os.time()-fireCooldown then
			activated=true
			connection = GunShootEffect()
			tool.Handle.Fire:Play()
			replicatedStorage.GunFired:FireServer(tool.Handle.Position,mouse.Hit.Position)
			--Trigger Pressed
		end
	end
end)

tool.Deactivated:Connect(function()
	if equipped==true and activated==true then
		activated=false
		--Gun Uncogged
		if connection then
			connection:Disconnect()
			connection = nil
		end
	end
end)

And lastly this is the 2 script you should put in bullet part

wait(6)

script.Parent:Remove()

and second

local replicatedStorage = game:GetService("ReplicatedStorage")

script.Parent.Touched:Connect(function()
	
	replicatedStorage.FlightEnd:Fire()
	
end)

Oviously you can change this bullet script so when the bullet hits a player it damages him and disapears…