Check my post "How Do I Change The Shoulder Camera Script In The "Auto Rifle Model By Roblox" To Change Plr Camera?"
Script:
--Continuation 2 function ShoulderCamera:onRenderStep(dt) if not self.enabled or not self.currentCamera or not self.currentCharacter or not self.currentHumanoid or not self.currentRootPart then return end -- Hide mouse and lock to center if applicable if self.mouseLocked and not GuiService:GetEmotesMenuOpen() then UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter UserInputService.MouseIconEnabled = false else UserInputService.MouseBehavior = Enum.MouseBehavior.Default UserInputService.MouseIconEnabled = true end -- Handle gamepad input self:processGamepadInput(dt) -- Smoothly zoom to desired values if self.hasScope then ShoulderCamera.SpringService:Target(self, 0.8, 8, { zoomAlpha = self.zoomState and 1 or 0 }) ShoulderCamera.SpringService:Target(self.currentCamera, 0.8, 8, { FieldOfView = self.desiredFieldOfView }) else ShoulderCamera.SpringService:Target(self, 0.8, 3, { zoomAlpha = self.zoomState and 1 or 0 }) ShoulderCamera.SpringService:Target(self.currentCamera, 0.8, 3, { FieldOfView = self.desiredFieldOfView }) end -- Handle walk speed changes if self.sprintEnabled or self.slowZoomWalkEnabled then self.desiredWalkSpeed = self.normalWalkSpeed if self.sprintEnabled and (self.sprintingInputActivated or self:sprintFromTouchInput() or self:sprintFromGamepadInput()) and not self.zoomState then self.desiredWalkSpeed = self.sprintingWalkSpeed end if self.slowZoomWalkEnabled and self.zoomAlpha > 0.1 then self.desiredWalkSpeed = self.zoomWalkSpeed end ShoulderCamera.SpringService:Target(self.currentHumanoid, 0.95, 4, { WalkSpeed = self.desiredWalkSpeed }) end -- Initialize variables used for side correction, occlusion, and calculating camera focus/rotation local rootPartPos = self.currentRootPart.CFrame.Position local rootPartUnrotatedCFrame = CFrame.new(rootPartPos) local yawRotation = CFrame.Angles(0, self.yaw, 0) local pitchRotation = CFrame.Angles(self.pitch + self.currentRecoil.Y, 0, 0) local xOffset = CFrame.new(self.normalOffset.X, 0, 0) local yOffset = CFrame.new(0, self.normalOffset.Y, 0) local zOffset = CFrame.new(0, 0, self.normalOffset.Z) local collisionRadius = self:getCollisionRadius() local cameraYawRotationAndXOffset = yawRotation * -- First rotate around the Y axis (look left/right) xOffset -- Then perform the desired offset (so camera is centered to side of player instead of directly on player) local cameraFocus = rootPartUnrotatedCFrame * cameraYawRotationAndXOffset -- Handle/Calculate side correction when player is adjacent to a wall (so camera doesn't go in the wall) local vecToFocus = cameraFocus.p - rootPartPos local rayToFocus = Ray.new(rootPartPos, vecToFocus + (vecToFocus.Unit * collisionRadius)) local hitPart, hitPoint, hitNormal = self:penetrateCast(rayToFocus, self.raycastIgnoreList) local currentTime = tick() local sideCorrectionGoalVector = Vector3.new() -- if nothing is adjacent to player, goal vector is (0, 0, 0) if hitPart then hitPoint = hitPoint + (hitNormal * collisionRadius) sideCorrectionGoalVector = hitPoint - cameraFocus.p if sideCorrectionGoalVector.Magnitude >= self.lastSideCorrectionMagnitude then -- make it easy for camera to pop closer to player (move left) if currentTime > self.lastSideCorrectionReachedTime + self.timeUntilRevertSideCorrection and self.lastSideCorrectionMagnitude ~= 0 then self.timeUntilRevertSideCorrection = self.defaultTimeUntilRevertSideCorrection * 2 -- double time until revert if popping in repeatedly elseif self.lastSideCorrectionMagnitude == 0 and self.timeUntilRevertSideCorrection ~= self.defaultTimeUntilRevertSideCorrection then self.timeUntilRevertSideCorrection = self.defaultTimeUntilRevertSideCorrection end self.lastSideCorrectionMagnitude = sideCorrectionGoalVector.Magnitude self.lastSideCorrectionReachedTime = currentTime self.isRevertingSideCorrection = false else self.isRevertingSideCorrection = true end elseif self.lastSideCorrectionMagnitude ~= 0 then self.isRevertingSideCorrection = true end if self.isRevertingSideCorrection then -- make it hard/slow for camera to revert side correction (move right) if sideCorrectionGoalVector.Magnitude > self.lastSideCorrectionMagnitude - 1 and sideCorrectionGoalVector.Magnitude ~= 0 then self.lastSideCorrectionReachedTime = currentTime -- reset timer if occlusion significantly increased since last frame end if currentTime > self.lastSideCorrectionReachedTime + self.timeUntilRevertSideCorrection then local sideCorrectionChangeAmount = dt * (vecToFocus.Magnitude) * self.revertSideCorrectionSpeedMultiplier self.lastSideCorrectionMagnitude = self.lastSideCorrectionMagnitude - sideCorrectionChangeAmount if sideCorrectionGoalVector.Magnitude >= self.lastSideCorrectionMagnitude then self.lastSideCorrectionMagnitude = sideCorrectionGoalVector.Magnitude self.lastSideCorrectionReachedTime = currentTime self.isRevertingSideCorrection = false end end end
--Continuation 3 -- Update cameraFocus to reflect side correction cameraYawRotationAndXOffset = cameraYawRotationAndXOffset + (-vecToFocus.Unit * self.lastSideCorrectionMagnitude) cameraFocus = rootPartUnrotatedCFrame * cameraYawRotationAndXOffset self.currentCamera.Focus = cameraFocus -- Calculate and apply CFrame for camera local cameraCFrameInSubjectSpace = cameraYawRotationAndXOffset * pitchRotation * -- rotate around the X axis (look up/down) yOffset * -- move camera up/vertically zOffset -- move camera back self.currentCFrame = rootPartUnrotatedCFrame * cameraCFrameInSubjectSpace -- Move camera forward if zoomed in if self.zoomAlpha > 0 then local trueZoomedOffset = math.max(self.zoomedOffsetDistance - self.lastOcclusionDistance, 0) -- don't zoom too far in if already occluded self.currentCFrame = self.currentCFrame:lerp(self.currentCFrame + trueZoomedOffset * self.currentCFrame.LookVector.Unit, self.zoomAlpha) end self.currentCamera.CFrame = self.currentCFrame -- Handle occlusion local occlusionDistance = self.currentCamera:GetLargestCutoffDistance(self.raycastIgnoreList) if occlusionDistance > 1e-5 then occlusionDistance = occlusionDistance + collisionRadius end if occlusionDistance >= self.lastOcclusionDistance then -- make it easy for the camera to pop in towards the player if self.curOcclusionTween ~= nil then self.curOcclusionTween:Cancel() self.curOcclusionTween = nil end if currentTime > self.lastOcclusionReachedTime + self.timeUntilZoomOut and self.lastOcclusionDistance ~= 0 then self.timeUntilZoomOut = self.defaultTimeUntilZoomOut * 2 -- double time until zoom out if popping in repeatedly elseif self.lastOcclusionDistance == 0 and self.timeUntilZoomOut ~= self.defaultTimeUntilZoomOut then self.timeUntilZoomOut = self.defaultTimeUntilZoomOut end if occlusionDistance / self.normalOffset.Z > 0.8 and self.timeLastPoppedWayIn == 0 then self.timeLastPoppedWayIn = currentTime end self.lastOcclusionDistance = occlusionDistance self.lastOcclusionReachedTime = currentTime self.isZoomingOut = false else -- make it hard/slow for camera to zoom out self.isZoomingOut = true if occlusionDistance > self.lastOcclusionDistance - 2 and occlusionDistance ~= 0 then -- reset timer if occlusion significantly increased since last frame self.lastOcclusionReachedTime = currentTime end -- If occlusion pops camera in to almost first person for a short time, pop out instantly if currentTime < self.timeLastPoppedWayIn + self.defaultTimeUntilZoomOut and self.lastOcclusionDistance / self.normalOffset.Z > 0.8 then self.lastOcclusionDistance = occlusionDistance self.lastOcclusionReachedTime = currentTime self.isZoomingOut = false elseif currentTime >= self.timeLastPoppedWayIn + self.defaultTimeUntilZoomOut and self.timeLastPoppedWayIn ~= 0 then self.timeLastPoppedWayIn = 0 end end -- Update occlusion amount if timeout time has passed if currentTime >= self.lastOcclusionReachedTime + self.timeUntilZoomOut and not self.zoomState then if self.curOcclusionTween == nil then self.occlusionTweenObject.Value = self.lastOcclusionDistance local tweenInfo = TweenInfo.new(self.tweenOutTime) local goal = {} goal.Value = self.lastOcclusionDistance - self.normalOffset.Z self.curOcclusionTween = TweenService:Create(self.occlusionTweenObject, tweenInfo, goal) self.curOcclusionTween:Play() end end -- Apply occlusion to camera CFrame local currentOffsetDir = self.currentCFrame.LookVector.Unit self.currentCFrame = self.currentCFrame + (currentOffsetDir * self.lastOcclusionDistance) self.currentCamera.CFrame = self.currentCFrame -- Apply recoil decay self.currentRecoil = self.currentRecoil - (self.currentRecoil * self.recoilDecay * dt) if self:isHumanoidControllable() and self.rotateCharacterWithCamera then self.currentHumanoid.AutoRotate = false self.currentRootPart.CFrame = CFrame.Angles(0, self.yaw, 0) + self.currentRootPart.Position -- rotate character to be upright and facing the same direction as camera self:applyRootJointFix() else self.currentHumanoid.AutoRotate = true end self:handlePartTransparencies() self:handleTouchToolFiring() end -- This function keeps the held weapon from bouncing up and down too much when you move function ShoulderCamera:applyRootJointFix() if self.rootJoint then local translationScale = self.zoomState and Vector3.new(0.25, 0.25, 0.25) or Vector3.new(0.5, 0.5, 0.5) local rotationScale = self.zoomState and 0.15 or 0.2 local rootRotation = self.rootJoint.Part0.CFrame - self.rootJoint.Part0.CFrame.Position local rotation = self.rootJoint.Transform - self.rootJoint.Transform.Position local yawRotation = CFrame.Angles(0, self.yaw, 0) local leadRotation = rootRotation:toObjectSpace(yawRotation) local rotationFix = self.rootRigAttach.CFrame if self:isHumanoidControllable() then rotationFix = self.rootJoint.Transform:inverse() * leadRotation * rotation:Lerp(CFrame.new(), 1 - rotationScale) + (self.rootJoint.Transform.Position * translationScale) end self.rootJoint.C0 = CFrame.new(self.rootJoint.C0.Position, self.rootJoint.C0.Position + rotationFix.LookVector.Unit) end end function ShoulderCamera:sprintFromTouchInput() local moveVector = nil local activeController = nil local activeControllerIsTouch = nil if self.controlModule then moveVector = self.controlModule:GetMoveVector() activeController = self.controlModule:GetActiveController() end if moveVector and activeController then activeControllerIsTouch = activeController.thumbstickFrame ~= nil or activeController.thumbpadFrame ~= nil end if activeControllerIsTouch then return (moveVector and moveVector.Magnitude >= 0.9) else return false end end function ShoulderCamera:sprintFromGamepadInput() return self.movementPan.Magnitude > 0.9 end