Please Read Carefully!
Step 1 Sway!
To add sway to a gun hop into your local script, now replace this
RunService.RenderStepped:Connect(function(step)
idle:Play()
script.Parent.PrimaryPart.CFrame = game.Workspace.CurrentCamera.CFrame
end)
with
local mult = 1 -- multiply by
local swayOffset = CFrame.new() -- the cframe
local lastCameraCF = workspace.CurrentCamera.CFrame -- camera cframe
RunService.RenderStepped:Connect(function(step)
idle:Play() -- play idle
local camframe = game:GetService("Workspace").CurrentCamera.CFrame -- camera cframe while playing
script.Parent.HumanoidRootPart.CFrame = camframe + camframe.LookVector * -0.5 + camframe.UpVector * -0.2 + camframe.RightVector * -0.5 -- how much the camera angle is changed by
local rotation = workspace.CurrentCamera.CFrame:toObjectSpace(lastCameraCF) -- the rotation of the camera
local x,y,z = rotation:ToOrientation()
swayOffset = swayOffset:Lerp(CFrame.Angles(math.sin(x)*mult,math.sin(y)*mult,0), 0.1) -- offset
script.Parent.HumanoidRootPart.CFrame = script.Parent.HumanoidRootPart.CFrame * swayOffset
lastCameraCF = workspace.CurrentCamera.CFrame -- the last cframe
end)
This will make your gun sway, read the notes to further understand.
Part 2 Reloads!
Create a new number value inside of the server script, now name it Ammo set the value to the amount of ammo you want. Inside of your server script do at the very top local ammo = script.Ammo
then write ammo.Value -= 1
under script.Parent.Local.RemoteEvent.OnServerEvent:Connect(function(player,mousePos)
At the very bottom write
while true do
wait()
if ammo.Value == 0 then
wait(script.Parent.Handle.Reload.TimeLength)
ammo.Value = 15
end
end
This basically checks if ammo = 0 then if true reloads, set 15 to your amount of ammo.
Now go into the animation editor and make an animation for your gun, then set animation type to animation 2, now inside of your handle make an animation called Reload Anim and paste the animation. Now find a reload sound and rename it to Reload and put it in handle.
Now hop onto your Local Script and replace this
if (Camera.CFrame.Position - Head.Position).Magnitude < 0.8 then -- If in first person
db = true -- start cooldown
script.RemoteEvent:FireServer(Mouse.Hit.Position) -- will fire a server that sets of a server script
script.Parent.Handle.Shoot:Play()
ShootAnim:Play()
wait(0.5) -- time between cooldown
db = false -- end cooldown
end
with this
if (Camera.CFrame.Position - Head.Position).Magnitude < 0.8 then -- If in first person
if script.Parent.Server.Ammo.Value >= 1 then
db = true -- start cooldown
script.RemoteEvent:FireServer(Mouse.Hit.Position) -- will fire a server that sets of a server script
script.Parent.Handle.Shoot:Play()
ShootAnim:Play()
wait(0.5) -- time between cooldown
db = false -- end cooldown
else
ReloadAnim:Play()
script.Parent.Handle.Reload:Play()
db = true
wait(script.Parent.Handle.Reload.TimeLength)
db = false
end
end
This will check if you have to reload and then play anims if you do.
Your final local script should look like this:
local idle = script.Parent:WaitForChild("AnimationController").Animator:LoadAnimation(script.Parent.Handle.Idle)
local ShootAnim = script.Parent:WaitForChild("AnimationController").Animator:LoadAnimation(script.Parent.Handle.ShootAnim)
local ReloadAnim = script.Parent:WaitForChild("AnimationController").Animator:LoadAnimation(script.Parent.Handle.ReloadAnim)
local RunService = game:GetService("RunService")
local mult = 1
local swayOffset = CFrame.new()
local lastCameraCF = workspace.CurrentCamera.CFrame
RunService.RenderStepped:Connect(function(step)
idle:Play()
local camframe = game:GetService("Workspace").CurrentCamera.CFrame
script.Parent.HumanoidRootPart.CFrame = camframe + camframe.LookVector * -0.5 + camframe.UpVector * -0.2 + camframe.RightVector * -0.5
local rotation = workspace.CurrentCamera.CFrame:toObjectSpace(lastCameraCF)
local x,y,z = rotation:ToOrientation()
swayOffset = swayOffset:Lerp(CFrame.Angles(math.sin(x)*mult,math.sin(y)*mult,0), 0.1)
script.Parent.HumanoidRootPart.CFrame = script.Parent.HumanoidRootPart.CFrame * swayOffset
lastCameraCF = workspace.CurrentCamera.CFrame
end)
local RATE_PER_SECOND = 0
RunService.RenderStepped:Connect(function(step)
local increment = RATE_PER_SECOND * step
for index, instance in pairs(script.Parent:GetDescendants()) do
if instance:IsA("BasePart") then
instance.LocalTransparencyModifier = 0
end
end
end)
local db = false
local Camera = game.Workspace.CurrentCamera
local Head = game.Players.LocalPlayer.Character.Head
local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
Mouse.Button1Down:Connect(function() -- if mouse down
if db == false then -- If the debounce is dissabled (Debounce is a cooldown)
if (Camera.CFrame.Position - Head.Position).Magnitude < 0.8 then -- If in first person
if script.Parent.Server.Ammo.Value >= 1 then
db = true -- start cooldown
script.RemoteEvent:FireServer(Mouse.Hit.Position) -- will fire a server that sets of a server script
script.Parent.Handle.Shoot:Play()
ShootAnim:Play()
wait(0.5) -- time between cooldown
db = false -- end cooldown
else
ReloadAnim:Play()
script.Parent.Handle.Reload:Play()
db = true
wait(script.Parent.Handle.Reload.TimeLength)
db = false
end
end
end
end)
and your final server script should look like this:
local ammo = script.Ammo
script.Parent.Local.RemoteEvent.OnServerEvent:Connect(function(player,mousePos) -- gets player and mouse position
ammo.Value -= 1
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {player.Character}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local raycastResult = workspace:Raycast(player.Character.HumanoidRootPart.Position,(mousePos - player.Character.HumanoidRootPart.Position)*1000,raycastParams) -- Were ray starts
if raycastResult then
local hitPart = raycastResult.Instance -- what the ray hits
local model = hitPart:FindFirstAncestorOfClass("Model") -- if ray hits model
if model then
if model:FindFirstChild("Humanoid") then -- if hits model with humanoid
model.Humanoid.Health -= 30 -- hurt player replace number with damage number
end
end
end
end)
while true do
wait()
if ammo.Value == 0 then
wait(script.Parent.Handle.Reload.TimeLength)
ammo.Value = 15
end
end
Final product:
https://www.roblox.com/library/9976650514/Finished-viewmodel