Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

"How Do I Change The Shoulder Camera Script In The "Auto Rifle" Model By Roblox Continuation?

Asked by 3 years ago

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

1 answer

Log in to vote
0
Answered by 3 years ago
--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
0
check my post "How Do I Change The Shoulder Camera Script In The "Auto Rifle" Model By Roblox Continuation 2?" MrSarp_shoot 37 — 3y
Ad

Answer this question