Please help me with this AimController Module. I’m trying to get the characters camera to tween/lerp to the aimCamera, but the position it completely messing up. I’ve attached a video plus the entire Module script. Everything works except for the viewModel positioning.
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local Constants = require(ReplicatedStorage.WeaponConfig.Constants)
local viewModels = ReplicatedStorage.WeaponConfig.ViewModels
local camera = Workspace.CurrentCamera
local disconnectAndClear = require(ReplicatedStorage.Utility.disconnectAndClear)
local AimController = {}
AimController.__index = AimController
function AimController.new(viewModelController, weapon)
local handle = weapon:WaitForChild("Handle")
local sounds = weapon:WaitForChild("Sounds")
local viewModelName = weapon:GetAttribute(Constants.VIEW_MODEL_ATTRIBUTE)
local viewModelTemplate = viewModels[viewModelName]
local viewModel = viewModelTemplate:Clone()
local muzzle = viewModel:FindFirstChild("MuzzleAttachment", true)
local aimCamera = viewModel:FindFirstChild("AimCamera", true)
local aimSpeed = weapon:GetAttribute(Constants.AIM_SPEED_ATTRIBUTE)
local aimFOV = weapon:GetAttribute(Constants.DEFAULT_FOV - 10)
local zoomDuration = weapon:GetAttribute(Constants.ZOOM_DURATION_ATTRIBUTE)
local self = {
viewModelController = viewModelController,
weapon = weapon,
aimCamera = aimCamera, -- The CFrame of this part determines the aim offset
isAiming = false,
aimSpeed = aimSpeed,
aimFOV = aimFOV,
zoomDuration = zoomDuration,
currentAimCFrame = Constants.VIEW_MODEL_OFFSET, -- Initial CFrame of the view model relative to camera
zoomTween = nil,
connections = {},
}
setmetatable(self, AimController)
-- Connect to RenderStepped for continuous aiming Lerp
table.insert(self.connections, RunService.RenderStepped:Connect(function(deltaTime)
self:updateAim(deltaTime)
end))
-- Connect input for aiming
table.insert(self.connections, UserInputService.InputBegan:Connect(function(input, gpe)
if gpe then return end
if input.UserInputType == Enum.UserInputType.MouseButton2 or input.KeyCode == Constants.KEYBOARD_AIM_KEY_CODE then
self:startAim()
end
end))
table.insert(self.connections, UserInputService.InputEnded:Connect(function(input, gpe)
if gpe then return end
if input.UserInputType == Enum.UserInputType.MouseButton2 or input.KeyCode == Constants.KEYBOARD_AIM_KEY_CODE then
self:stopAim()
end
end))
return self
end
function AimController:startAim()
if self.isAiming then return end
self.isAiming = true
end
function AimController:stopAim()
if not self.isAiming then return end
self.isAiming = false
end
function AimController:updateAim(deltaTime)
local targetOffsetCFrame
local primaryPart = self.viewModelController.model.PrimaryPart
if not primaryPart then return end
if self.isAiming then
targetOffsetCFrame = (primaryPart.CFrame:ToObjectSpace(self.aimCamera.CFrame)):Inverse()
self:zooming(self.aimFOV, self.zoomDuration)
else
targetOffsetCFrame = Constants.VIEW_MODEL_OFFSET
self:zooming(Constants.DEFAULT_FOV, self.zoomDuration)
end
local alpha = math.min(deltaTime * self.aimSpeed, 1)
self.currentAimCFrame = self.currentAimCFrame:Lerp(targetOffsetCFrame, alpha)
self.viewModelController:setAimCFrame(self.currentAimCFrame)
end
function AimController:zooming(targetFOV, duration)
if self.zoomTween then
self.zoomTween:Cancel()
self.zoomTween = nil
end
local tweenInfo = TweenInfo.new(duration, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
local zoomGoal = { FieldOfView = targetFOV }
self.zoomTween = TweenService:Create(camera, tweenInfo, zoomGoal)
self.zoomTween:Play()
self.zoomTween.Completed:Connect(function()
self.zoomTween:Destroy()
end)
end
function AimController:destroy()
disconnectAndClear(self.connections)
if self.zoomTween then
self.zoomTween:Cancel()
self.zoomTween = nil
end
camera.FieldOfView = Constants.DEFAULT_FOV
end
return AimController