I have a script for a gun system but I am trying to improve it so that it acts as a tool inside the starter pack and is only run when equipped through the hotbar.
The gun system consists of a local script inside StarterPlayerScripts, which is the main script. A script in ServerScriptService for the damage, and a gun and arm model along with a module script remote event and animation in replicated storage.
I have tried a few changes like adding all replicated storage things into the tool of the gun and renaming ReplicatedStorage inside the script along with some help with ChatGPT but it ended up ruining it and I had to go back through the version history.
The main script inside StarterPlayerScripts is this it refers back to replicated storage to make everything work.
local Character = Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local HRP = Character.HumanoidRootPart
local Camera = workspace.CurrentCamera
local Mouse = Player:GetMouse()
local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local GuiService = game:GetService("GuiService")
local TS = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remote = ReplicatedStorage.Gun
local SpringModule = require(ReplicatedStorage.SpringModule)
local Viewmodel = ReplicatedStorage.Viewmodel:Clone()
Viewmodel.Parent = Camera
local Gunmodel = ReplicatedStorage.LaserGun:Clone()
Gunmodel.Parent = Viewmodel
local Joint = Instance.new("Motor6D")
Joint.Part0 = Viewmodel.Primary
Joint.Part1 = Gunmodel.Handle
Joint.Parent = Gunmodel.Handle
Joint.C1 = CFrame.new(0, .2, .2)
local Animations = {
["Idle"] = Viewmodel.AnimationController.Animator:LoadAnimation(ReplicatedStorage.Idle)
}
Animations.Idle:Play()
local MouseSway = SpringModule.new(Vector3.new())
MouseSway.Speed = 20
MouseSway.Damper = .5
local MovementSway = SpringModule.new(Vector3.new())
MovementSway.Speed = 20
MovementSway.Damper = .4
local GunSpring = SpringModule.new(Vector3.new())
GunSpring.Speed = 20
GunSpring.Damper = .4
local RecoilSpring = SpringModule.new(Vector3.new())
RecoilSpring.Speed = 25
RecoilSpring.Damper = 1
local Aiming = false
local AimingCF = CFrame.new()
local AUTO = false
local CD = 5
local CanShoot = true
local Shooting = false
local RANGE = 500
local KICK = Vector3.new(10,-1,10)
local RECOIL = Vector3.new(5,-0,10)
local RESETRECOIL = .2
local OOC = 2
local REC = 1
local RECOILS = {
{-1,1},
{-2,2},
{-4,4},
{-8,8},
{-10,10},
{-20,20},
}
local RECOILDAMPNENER = 1
local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Blacklist
Params.FilterDescendantsInstances = {Viewmodel, Character, workspace.FX}
local function GetBobbing(Addition, Speed, Modifier)
return math.sin(time()* Addition * Speed) * Modifier
end
UIS.InputBegan:Connect(function(Input, GPE)
if Input.UserInputType == Enum.UserInputType.MouseButton2 then
Aiming = true
elseif Input.UserInputType == Enum.UserInputType.MouseButton1 then
Shooting = true
CanShoot = false
local StartShoot = time()
local Shots = 0
repeat
if Shots < #RECOILS then
Shots+=1
end
GunSpring.Velocity += KICK
local Recoil = RECOIL
if time() - StartShoot > OOC then
Recoil += Vector3.new(0,(math.sin(10 * (time() - StartShoot)) * 25),0)
elseif time() - StartShoot > REC then
Recoil += Vector3.new(0,(math.cos(5 * (time() - StartShoot)) * 12),0)
end
local x = math.random(RECOILS[Shots][1]*10, RECOILS[Shots][2]*10)/10 - RECOILS[Shots][1]
local y = math.random(RECOILS[Shots][1]*10, RECOILS[Shots][2]*10)/10
local z = 0
Recoil += Vector3.new(x,y,z)
Recoil/= RECOILDAMPNENER
RecoilSpring.Velocity+= Recoil
task.delay(RESETRECOIL, function()
RecoilSpring.Velocity-=Recoil
end)
--TODO
local EndPos
local BStart = Gunmodel.FirePart.Position
local Dir = (Mouse.Hit.Position - BStart).Unit
local Shoot = workspace:Raycast(BStart, Dir * RANGE, Params)
if not Shoot then
EndPos = BStart + Camera.CFrame.LookVector * RANGE
else
EndPos = Shoot.Position
end
if Shoot then
local RTable = {}
RTable.Instance = Shoot.Instance
RTable.Position = Shoot.Position
RTable.Distance = Shoot.Distance
RTable.Normal = Shoot.Normal
RTable.Origin = BStart
Remote:FireServer(RTable)
else
local RTable = {}
RTable.Position = EndPos
RTable.Distance = RANGE
RTable.Origin = BStart
Remote:FireServer(RTable)
end
RenderBullet(BStart, EndPos, Shoot)
task.wait(CD)
until Shooting == false or AUTO == false
end
end)
UIS.InputBegan:Connect(function(Input, GPE)
if Input.UserInputType == Enum.UserInputType.MouseButton2 then
Aiming = false
elseif Input.UserInputType == Enum.UserInputType.MouseButton1 and Shooting then
Shooting = false
end
end)
function RenderBullet(BStart, EndPos, Result)
local Beam = script.Bullet:Clone()
Beam.Parent = workspace.FX
Beam.CFrame = CFrame.new((BStart + EndPos)/2, EndPos)
Beam.Size = Vector3.new(.2,.2,(BStart - EndPos).Magnitude)
local Attach1 = Instance.new("Attachment", Beam)
Attach1.WorldCFrame = CFrame.new(BStart, EndPos)
local Attach2 = Instance.new("Attachment", Beam)
Attach2.WorldCFrame = CFrame.new(EndPos, BStart)
Beam.Beam.Attachment0 = Attach1
Beam.Beam.Attachment1 = Attach2
local Flash = script.Flash:Clone()
Flash.Parent = Attach1
Flash:Emit(3)
local Spotlight = script.SpotLight:Clone()
Spotlight.Parent = Attach1
TS:Create(Spotlight, TweenInfo.new(.3), {Brightness = 0}):Play()
if Result then
if Result.Instance then
if Result.Instance.Parent:FindFirstChild("Humanoid") == nil then
local Hole = script.Hole:Clone()
Hole.CFrame = CFrame.new(Result.Position, Result.Position + Result.Normal)
Hole.Parent = workspace.FX
task.delay(5, function()
Hole:Destroy()
end)
end
end
end
task.spawn(function()
task.wait(.1)
Beam.Beam.Enabled = false
task.wait(.5)
Beam:Destroy()
end)
end
RS:BindToRenderStep("Viewmodel", 301, function(DT)
local MouseDelta = UIS:GetMouseDelta()
MouseSway.Velocity += (Vector3.new(MouseDelta.X / 250,MouseDelta.Y / 250))
local MovementSwayAmount = Vector3.new(GetBobbing(10,1,.2), GetBobbing(5,1,.2),GetBobbing(5,1,.2))
MovementSway.Velocity += ((MovementSwayAmount / 25) * DT * 60 * HRP.AssemblyLinearVelocity.Magnitude)
if Aiming then
AimingCF = AimingCF:Lerp(Gunmodel.AimPart.CFrame:ToObjectSpace(Viewmodel.Primary.CFrame), .3)
else
AimingCF = AimingCF:Lerp(CFrame.new(), .3)
end
MovementSway.Velocity += ((MovementSwayAmount / 25) * DT * 60 * HRP.AssemblyLinearVelocity.Magnitude)
Camera.CFrame *= CFrame.Angles(math.rad(RecoilSpring.Position.X),math.rad(RecoilSpring.Position.Y),math.rad(RecoilSpring.Position.Z))
Viewmodel:PivotTo(
Camera.CFrame * CFrame.Angles(MovementSway.Position.X / 2,MovementSway.Position.Y / 2,0)
* AimingCF
* CFrame.Angles(0,-MouseSway.Position.X,MouseSway.Position.Y)
* CFrame.Angles(0,MovementSway.Position.Y,MovementSway.Position.X)
* CFrame.Angles(GunSpring.Position.X,GunSpring.Position.Y,0)
* CFrame.new(0,0,GunSpring.Position.X * 5)
)
end)
Remote.OnClientEvent:Connect(function(Result)
RenderBullet(Result.Origin, Result.Position, Result)
end)
Player.CharacterAdded:Connect(function(character)
Character = character
Humanoid = Character:WaitForChild("Humanoid")
Params.FilterDescendantsInstances = {Viewmodel, Character, workspace.FX}
end)
I also made a tool called LaserGun, which is where I plan on having the gun work. I would greatly appreciate some help.