Hey guys, I am trying to achieve scripting aim down sights for my roblox game.
I’ve been trying to look for a solution for a while now so I thought I might as well make a post to see if anyone could help me.
This is what my aim down sights looks like right now:
What I would like to accomplish:
Viewmodel Script:
player.CameraMode = Enum.CameraMode.LockFirstPerson
local arms = game.ReplicatedStorage.Storage.Arms:Clone()
arms.Parent = camera --workspace["global_Arms"]
local mouseSway = springModule.new(Vector3.new())
mouseSway.Speed = 20
mouseSway.Damper = 0.5
local movementSway = springModule.new(Vector3.new())
movementSway.Speed = 25
movementSway.Damper = 0.7
local recoilSpring = springModule.new(Vector3.new())
recoilSpring.Speed = 25
recoilSpring.Damper = 1
local function getBobbing(addition, speed, modifier)
return math.sin(time() * addition * speed) * modifier
end
RunService:BindToRenderStep("Viewmodel", 301, function(deltaTime)
local getGunStats = gun.guns[holding[1]]
local movementSwayAmount = Vector3.new(getBobbing(10, 1, 0.2), getBobbing(5, 1, 0.2), getBobbing(5, 1, 0.2))
local humanoidRootPart = player.Character.HumanoidRootPart
-- Checks if the player is scoping
if getGunStats and #holding > 0 and not table.find(holding, "Melee") and getGunStats.Scoping == true then
--Stops the player's arms and mouse from shaking while scoping
movementSway.Damper = 0.7
mouseSway.Damper = 0.6
local mouseDelta = UserInputService:GetMouseDelta()
mouseSway.Velocity += (Vector3.new(mouseDelta.X / 600, mouseDelta.Y / 600))
movementSway.Velocity += ((movementSwayAmount / 40) * deltaTime * 60 * humanoidRootPart.AssemblyLinearVelocity.Magnitude)
else
movementSway.Damper = 0.7
mouseSway.Damper = 0.5
local mouseDelta = UserInputService:GetMouseDelta()
mouseSway.Velocity += (Vector3.new(mouseDelta.X / 450, mouseDelta.Y / 450))
movementSway.Velocity += ((movementSwayAmount / 25) * deltaTime * 60 * humanoidRootPart.AssemblyLinearVelocity.Magnitude)
end
movementSway.Velocity += ((movementSwayAmount / 25) * deltaTime * 60 * humanoidRootPart.AssemblyLinearVelocity.Magnitude)
-- CFrames the arms
arms:PivotTo(
camera.CFrame
* CFrame.Angles(movementSway.Position.X, movementSway.Position.Y / 2, 0)
--* aimingCF
* CFrame.Angles(0, -mouseSway.Position.X, mouseSway.Position.Y)
* CFrame.Angles(0, movementSway.Position.Y, movementSway.Position.X)
)
end)
Gun Script:
function gunModule:equip(gunName)
if not gunName or gunName == "" then
warn("gunName is invalid")
return
end
local gunInfo = gunModule.guns[gunName]
local viewmodel: Model = camera.Arms
local rightArm = viewmodel["Right Arm"]
local gun: Model = game.ReplicatedStorage.Storage.Guns[gunName]:Clone()
local animations: Folder = gun.Animations
-- Sets the gunInfos gun to the gun model
gunInfo.Gun = gun
local animator: Animator = viewmodel.AnimationController.Animator
-- Loads in the all of the gun animations
for _, animation: Animation in pairs(animations:GetChildren()) do
gunInfo.RunningAnimationTracks[animation.Name] = animator:LoadAnimation(animation)
end
-- Parents the gun to the viewmodel
gun.Parent = viewmodel
-- Stops running animation tracks
stopAnimTracks(gunName)
-- Plays the equip animation and than the idle animation
gunInfo.RunningAnimationTracks["Equip"]:Play()
gunInfo.RunningAnimationTracks["Idle"]:Play()
-- Creates a motor6D to connect the gun to the rightArm
local motor6D = Instance.new("Motor6D")
motor6D.Part0 = rightArm
motor6D.Part1 = gun.FRAME -- FRAME is the main part of the gun
motor6D.C0 = gunInfo.Stats.C0
motor6D.Name = "FRAME"
motor6D.Parent = rightArm
if UserInputService.KeyboardEnabled then
gunInfo.Connections["InputBegan"] = UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then
return
end
if typeof(gunModule.guns[gunName].Gun) ~= "Instance" then
return
end
if gunModule.guns[gunName].Owner.Character:FindFirstChildOfClass("Humanoid").Health <= 0 then
return
end
if input.UserInputType == Enum.UserInputType.Keyboard then
if input.KeyCode == Enum.KeyCode.R then
gunModule:reload(gunName)
elseif input.KeyCode == Enum.KeyCode.Q then
gunModule:scope(gunName)
end
elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
-- If the gun is not an automatic gun then do normal click shooting
if not gunInfo.Stats.Auto then
gunModule:shoot(gunName)
else
local lastShot = tick()
local autoShooting = Instance.new("BoolValue")
local wasAiming = false
gunModule.guns[gunName].Connections["AutoShooting"] = RunService.Heartbeat:Connect(function()
--or gunModule.guns[gunName].ReloadDebounce
if
not UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
or gunInfo.Ammo <= 0
or gunInfo.MaxAmmo <= 0
then
--print("Disconnecting Auto...")
gunModule.guns[gunName].Connections["AutoShooting"]:Disconnect()
autoShooting.Value = false
--wasAiming = false
return
end
if (tick() - lastShot) >= gunInfo.Stats.ShootDebounceTime then
--print("Shooting...")
if autoShooting.Value == false then
if gunModule.guns[gunName].Scoping then
wasAiming = true
end
end
autoShooting.Value = true
gunModule:shoot(gunName)
lastShot = tick()
end
end)
autoShooting:GetPropertyChangedSignal("Value"):Connect(function()
if not wasAiming then
gunInfo.RunningAnimationTracks["Idle"]:Play()
else
-- gunInfo.RunningAnimationTracks["AimIn"]:Play()
-- gunInfo.RunningAnimationTracks["AimLoop"]:Play()
-- gunModule.guns[gunName].AimingCF = gunModule.guns[gunName].AimingCF:Lerp(
-- gun.AimPoint.CFrame:ToObjectSpace(camera.Arms.Primary.CFrame),
-- 0.25
-- )
gunModule:scope(gunName)
wasAiming = false
-- if gunInfo.Stats["C0Aim"] then
-- TweenService:Create(camera.Arms["Right Arm"].FRAME, TweenInfo.new(1), { C0 = gunInfo.Stats.C0Aim }):Play()
-- end
end
end)
end
elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
if not gunModule.guns[gunName].Scoping then
gunModule:scope(gunName)
end
end
end)
gunInfo.Connections["InputEnded"] = UserInputService.InputEnded:Connect(function(input, gameProcessedEvent)
if typeof(gunModule.guns[gunName].Gun) ~= "Instance" then
return
end
if gunModule.guns[gunName].Owner.Character:FindFirstChildOfClass("Humanoid").Health <= 0 then
return
end
if input.UserInputType == Enum.UserInputType.MouseButton2 then
if gunModule.guns[gunName].Scoping then
gunModule:scope(gunName)
end
end
end)
elseif UserInputService.TouchEnabled then
local lastShot = tick()
local autoShooting = false
gunModule.guns[gunName].Connections["AutoShooting"] = RunService.Heartbeat:Connect(function(deltaTime)
if autoShooting then
if gunInfo.Owner.Character:FindFirstChildOfClass("Humanoid").Health <= 0 then
return
end
if (tick() - lastShot) >= gunInfo.Stats.ShootDebounceTime then
gunModule:shoot(gunName)
lastShot = tick()
end
end
end)
local function shoot(actionName, inputState, inputObject)
--or gunModule.guns[gunName].ReloadDebounce
if gunInfo.Owner.Character:FindFirstChildOfClass("Humanoid").Health <= 0 then
return
end
if typeof(gunModule.guns[gunName].Gun) ~= "Instance" then
return
end
if not gunInfo.Stats.Auto then
gunModule:shoot(gunName)
else
if inputState == Enum.UserInputState.End then
autoShooting = false
elseif inputState == Enum.UserInputState.Begin then
autoShooting = true
end
end
end
local function reload()
if gunInfo.Owner.Character:FindFirstChildOfClass("Humanoid").Health <= 0 then
return
end
if typeof(gunModule.guns[gunName].Gun) ~= "Instance" then
return
end
gunModule:reload(gunName)
end
ContextActionService:BindAction("ShootButton", shoot, true)
ContextActionService:SetImage("ShootButton", "rbxassetid://15011746962")
ContextActionService:SetPosition("ShootButton", UDim2.new(0.3, 0, 0.155, 0))
ContextActionService:GetButton("ShootButton").Size = UDim2.new(0, 70, 0, 70)
ContextActionService:BindAction("ReloadButton", reload, true)
ContextActionService:SetImage("ReloadButton", "rbxassetid://15011709775")
ContextActionService:SetPosition("ReloadButton", UDim2.new(0.25, 0, 0.58, 0))
ContextActionService:GetButton("ReloadButton").Size = UDim2.new(0, 50, 0, 50)
ContextActionService:BindAction("AimButton", function() end, true)
ContextActionService:SetImage("AimButton", "rbxassetid://15011699699")
ContextActionService:SetPosition("AimButton", UDim2.new(0.585, 0, -0.025, 0))
local aimButton = ContextActionService:GetButton("AimButton")
aimButton.Size = UDim2.new(0, 55, 0, 55)
-- Aiming toggle function for mobile
gunModule.guns[gunName].Connections["AimButton"] = aimButton.MouseButton1Up:Connect(function()
if gunInfo.Owner.Character:FindFirstChildOfClass("Humanoid").Health <= 0 then
return
end
if typeof(gunModule.guns[gunName].Gun) ~= "Instance" then
return
end
gunModule:scope(gunName)
end)
end
end
-- Unequips the gun
function gunModule:unequip(gunName)
local gunInfo = gunModule.guns[gunName]
if gunInfo.Unequipping then
return
end
gunModule.guns[gunName].Unequipping = true
-- print(gunInfo.Connections, "CONNECTIONS BEFORE UNEQUIP")
if gunInfo.Scoping then
gunModule:scope(gunName)
end
-- Disconnects all of the guns connections to boost performance
for _, connection: RBXScriptConnection in pairs(gunInfo.Connections) do
connection:Disconnect()
end
-- Stops the animations
stopAnimTracks(gunName)
-- print(gunInfo.RunningAnimationTracks)
-- Plays the unequip animation
gunInfo.RunningAnimationTracks["Unequip"]:Play()
task.wait(gunInfo.RunningAnimationTracks["Unequip"].Length - 0.1)
if typeof(gunInfo.Gun) == "Instance" then
-- Destroys the gun
gunInfo.Gun:Destroy()
gunInfo.Gun = ""
else
warn("newGun.Gun is not a model")
end
gunModule.guns[gunName].Unequipping = false
end
function gunModule:scope(gunName)
local gunInfo = gunModule.guns[gunName]
if type(gunInfo.Gun) == "string" then
return
end
if gunInfo.ShootDebounce or gunInfo.ReloadDebounce then
return
end
local viewmodel = camera.Arms
local frame: Motor6D = viewmodel["Right Arm"]["FRAME"]
local aimPoint: Attachment = gunInfo.Gun:FindFirstChild("AimPoint")
if gunModule.guns[gunName].Scoping == false then
gunModule.guns[gunName].Scoping = true
stopAnimTracks(gunName)
if gunInfo.Stats["AimFov"] then
TweenService:Create(camera, TweenInfo.new(0.5), { FieldOfView = gunInfo.Stats.AimFov }):Play()
end
TweenService:Create(cursor, TweenInfo.new(0.25), { ImageTransparency = 1 }):Play()
if gunInfo.Stats["C0Aim"] then
TweenService:Create(frame, TweenInfo.new(1), { C0 = gunInfo.Stats.C0Aim }):Play()
end
-- if aimPoint then
-- TweenService:Create(aimPoint, TweenInfo.new(1), { CFrame = aimPoint.CFrame })
-- end
gunInfo.RunningAnimationTracks["AimIn"]:Play()
gunInfo.RunningAnimationTracks["AimLoop"]:Play()
-- gunModule.guns[gunName].AimingCF =
-- gunModule.guns[gunName].AimingCF:Lerp(aimPoint.CFrame:ToObjectSpace(camera.Arms.Primary.CFrame), 0.25)
--gunModule.guns[gunName].AimingCF:Lerp(aimPoint.CFrame:ToObjectSpace(camera.Arms.Primary.CFrame), 0.1)
else
gunModule.guns[gunName].Scoping = false
--stopAnimTracks(gunName)
if gunInfo.Stats["AimFov"] then
local cameraTween = TweenService:Create(camera, TweenInfo.new(0.5), { FieldOfView = 70 })
cameraTween:Play()
end
TweenService:Create(cursor, TweenInfo.new(0.25), { ImageTransparency = 0 }):Play()
if gunInfo.Stats["C0Aim"] then
TweenService:Create(frame, TweenInfo.new(1), { C0 = gunInfo.Stats.C0 }):Play()
end
gunInfo.RunningAnimationTracks["AimLoop"]:Stop()
gunInfo.RunningAnimationTracks["AimOut"]:Play()
gunInfo.RunningAnimationTracks["Idle"]:Play()
--gunModule.guns[gunName].AimingCF = gunModule.guns[gunName].AimingCF:Lerp(CFrame.new(), 1)
end
end
If anyone could help me, I would really appreciate it!