Camera target lock on system help

  1. What do you want to achieve?
    I have used someone else Over the Shoulder camera module (as I am not great at camera manipulation) but I have added in my own code to have a target lock on system which works really well. However, when I unlock from a target I want the camera CFrame to remain where it is but then the player can move their camera freely.

  2. What is the issue?
    https://gyazo.com/177b07f313190561a085537ab4c98798
    As you can see when I unlock from the target it returns to it’s previous CFrame before locking on to a target. Which during gameplay can be very jarring. I am unsure on how to resolve this.

  3. What solutions have you tried so far?
    I have tried a couple things like setting up a variable that stores the camera CFrame when unlocking from the target and that didn’t work. The code below isn’t the full CameraModule script but just the main 3 functions that control the camera and lock on function.

-- Main function which modifies the Camera
local function updateCamera()
	local currentCamera = workspace.CurrentCamera
	local activeCameraSettings = OTS_Cam.CameraSettings[CameraMode]

	currentCamera.CameraType = Enum.CameraType.Scriptable

	--// Moves camera based on Input //--
	local inputDelta = getDelta()
	OTS_Cam.HorizontalAngle -= inputDelta.X/currentCamera.ViewportSize.X
	OTS_Cam.VerticalAngle -= inputDelta.Y/currentCamera.ViewportSize.Y
	OTS_Cam.VerticalAngle = math.rad(math.clamp(math.deg(OTS_Cam.VerticalAngle), VERTICAL_ANGLE_LIMITS.Min, VERTICAL_ANGLE_LIMITS.Max))
	----

	local humanoidRootPart = Character ~= nil and Character:FindFirstChild("HumanoidRootPart")
	if humanoidRootPart then -- Disable if Player dies

		currentCamera.FieldOfView = Lerp(
			currentCamera.FieldOfView,
			activeCameraSettings.Field_Of_View,
			activeCameraSettings.Lerp_Speed
		)

		--// Address shoulder direction //--
		local offset = activeCameraSettings.Offset
		offset = Vector3.new(offset.X * OTS_Cam.ShoulderDirection, offset.Y, offset.Z)
		----

		--// Calculate new camera cframe //--
		local newCameraCFrame = CFrame.new(humanoidRootPart.Position) *
			CFrame.Angles(0, OTS_Cam.HorizontalAngle, 0) *
			CFrame.Angles(OTS_Cam.VerticalAngle, 0, 0) *
			CFrame.new(offset)

		newCameraCFrame = currentCamera.CFrame:Lerp(newCameraCFrame, activeCameraSettings.Lerp_Speed)
		----

		--// Raycast for obstructions //--
		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {Character}
		raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
		local raycastResult = workspace:Raycast(
			humanoidRootPart.Position,
			newCameraCFrame.p - humanoidRootPart.Position,
			raycastParams
		)
		----

		--// Address obstructions if any //--
		if raycastResult ~= nil then
			local obstructionDisplacement = (raycastResult.Position - humanoidRootPart.Position)
			local obstructionPosition = humanoidRootPart.Position + (obstructionDisplacement.Unit * (obstructionDisplacement.Magnitude - 0.1))
			local x,y,z,r00,r01,r02,r10,r11,r12,r20,r21,r22 = newCameraCFrame:GetComponents()
			newCameraCFrame = CFrame.new(obstructionPosition.x, obstructionPosition.y, obstructionPosition.z, r00, r01, r02, r10, r11, r12, r20, r21, r22)
		end
		----

		--// Address character alignment //--
		if OTS_Cam.IsCharacterAligned == true then
			local newHumanoidRootPartCFrame = CFrame.new(humanoidRootPart.Position) *
				CFrame.Angles(0, OTS_Cam.HorizontalAngle, 0)
			humanoidRootPart.CFrame = humanoidRootPart.CFrame:Lerp(newHumanoidRootPartCFrame, activeCameraSettings.Lerp_Speed/2)
		end
		----
		
		currentCamera.CFrame = currentCamera.CFrame:Lerp(newCameraCFrame, activeCameraSettings.Lerp_Speed)
		
	else
		OTS_Cam.Disable()
		CameraWasEnabled = true
	end
end

function lockOnToTarget()
	local humanoidRootPart = Character:FindFirstChild("HumanoidRootPart", true)
	local combatSystem = Character:FindFirstChild("CombatSystem", true)
	local currentCamera = workspace.CurrentCamera
	local activeCameraSettings = OTS_Cam.CameraSettings[CameraMode]
	
	if (humanoidRootPart and combatSystem) then
		local target = combatSystem.CombatProperties:FindFirstChild("Target")
		
		--// Address shoulder direction //--
		local offset = activeCameraSettings.Offset
		offset = Vector3.new(offset.X * OTS_Cam.ShoulderDirection, offset.Y, offset.Z)
		----
		
		local cameraCFrame = CFrame.new(humanoidRootPart.Position, target.Value.PrimaryPart.Position) * CFrame.new(offset.X, offset.Y, offset.Z)
		local newCameraCFrame = currentCamera.CFrame:Lerp(cameraCFrame, activeCameraSettings.Lerp_Speed)
		
		--// Raycast for obstructions //--
		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {Character}
		raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
		local raycastResult = workspace:Raycast(
			humanoidRootPart.Position,
			newCameraCFrame.Position - humanoidRootPart.Position,
			raycastParams
		)
		----
		
		--// Address obstructions if any //--
		if raycastResult ~= nil then
			local obstructionDisplacement = (raycastResult.Position - humanoidRootPart.Position)
			local obstructionPosition = humanoidRootPart.Position + (obstructionDisplacement.Unit * (obstructionDisplacement.Magnitude - 0.1))
			local x,y,z,r00,r01,r02,r10,r11,r12,r20,r21,r22 = newCameraCFrame:GetComponents()
			newCameraCFrame = CFrame.new(obstructionPosition.x, obstructionPosition.y, obstructionPosition.z, r00, r01, r02, r10, r11, r12, r20, r21, r22)
		end
		----
		
		--// Address character alignment //--
		if OTS_Cam.IsCharacterAligned == true then
			local newHumanoidRootPartCFrame = CFrame.lookAt(humanoidRootPart.Position, target.Value.PrimaryPart.Position)
			humanoidRootPart.CFrame = humanoidRootPart.CFrame:Lerp(newHumanoidRootPartCFrame, activeCameraSettings.Lerp_Speed/2)
		end
		----
		
		currentCamera.CameraType = Enum.CameraType.Scriptable
		currentCamera.CFrame = currentCamera.CFrame:Lerp(CFrame.new(newCameraCFrame.Position, target.Value.PrimaryPart.Position), activeCameraSettings.Lerp_Speed)
		
	end
end

function OTS_Cam.Enable()
	OTS_Cam.IsEnabled = true
	CameraWasEnabled = true
	configureStateForEnabled()

	RunService:BindToRenderStep(
		"OTS_CAMERA",
		Enum.RenderPriority.Camera.Value - 10,
		function()
			if OTS_Cam.IsEnabled == true then
				
				local combatSystem = Character:FindFirstChild("CombatSystem")
				
				if (combatSystem) then
					
					local target = combatSystem.CombatProperties:FindFirstChild("Target")
					local humanoidRootPart = Character:FindFirstChild("HumanoidRootPart", true)
					
					if (target and target.Value) then
						
						if ((humanoidRootPart.Position - target.Value.PrimaryPart.Position).Magnitude < 30 and target.Value.Humanoid.Health > 0 and Character.Humanoid.Health > 0) then
							
							lockOnToTarget()
							
						else
							
							updateTargetEvent:FireServer(nil)
							OTS_Cam.SetCharacterAlignment(false)
							
						end
						
					else
						
						updateCamera()
						
					end
				end
				
			end
		end
	)
end
----