How could i upgrade my lock on system?

Hi, i have a lock on system, and i want it to be similar to SS (Soul shatters), there’s a problem, when the enemy root part is very high on the air, the camera won’t exactly look at the dummy from down , and how could i lerp the camera so i can have a smooth transition betwheen locking in, and locking out?

My code :

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
local camera = workspace.CurrentCamera
local Character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
local Root = Character:WaitForChild("HumanoidRootPart")
local aliveCharacters = workspace:WaitForChild("alive characters")



function findClosestCharacter()
	local closestCharacter = nil
	local shortestDistance = math.huge
	local localPlayerPosition = localPlayer.Character and localPlayer.Character:FindFirstChild("HumanoidRootPart") and localPlayer.Character.HumanoidRootPart.Position

	if not localPlayerPosition then return nil end

	for _, character in ipairs(aliveCharacters:GetChildren()) do
		if character ~= localPlayer.Character and character:FindFirstChild("HumanoidRootPart") then
			local distance = (localPlayerPosition - character.HumanoidRootPart.Position).magnitude
			if distance < shortestDistance then
				closestCharacter = character
				shortestDistance = distance
			end
		end
	end

	return closestCharacter
end

function toggleCameraFocus()
	tracking = not tracking
	if tracking then
		trackedCharacter = findClosestCharacter()
		if trackedCharacter and trackedCharacter:FindFirstChild("HumanoidRootPart") then
			camera.CameraType = Enum.CameraType.Scriptable
		end
	else
		camera.CameraType = Enum.CameraType.Custom
		trackedCharacter = nil
	end
end

function OnInputBegan(Input, Processed)
	if Processed then return end
	if Input.UserInputType == Enum.UserInputType.MouseButton1 then
		toggleCameraFocus()
	end
end

local smoothFactor = 1 
local startAngle = nil -- Variable zum Speichern des Startwinkels

local function createTargetCFrame(angle, target, hmrp)
	local target = target-- dein Ziel-Objekt z.B. trackedCharacter.HumanoidRootPart
	local HMRP = hmrp-- HumanoidRootPart des lokalen Spielers
	local midpoint = (target.Position + HMRP.Position) / 2
	local distance = 6 -- Definiere einen festen Abstand, den die Kamera halten soll

	-- Berechnung der neuen Position der Kamera
	local newPosition = midpoint + Vector3.new(math.cos(angle) * distance, 0, math.sin(angle) * distance)
	-- Stelle sicher, dass die Y-Koordinate der Kamera eine feste Höhe hat
	newPosition = Vector3.new(newPosition.X, camera.CFrame.Position.Y, newPosition.Z)

	-- Erstelle einen neuen CFrame für die Kamera, der auf den Mittelpunkt schaut
	return CFrame.new(newPosition, midpoint)
end

local function areCollinear(playerPosition, targetPosition, cameraPosition)
	-- Erstelle Vektoren
	local vector1 = Vector3.new(targetPosition.X - playerPosition.X, 0, targetPosition.Z - playerPosition.Z)
	local vector2 = Vector3.new(cameraPosition.X - playerPosition.X, 0, cameraPosition.Z - playerPosition.Z)

	-- Berechne das Kreuzprodukt (ignoriere Y, da es auf 0 gesetzt ist)
	local crossProduct = vector1:Cross(vector2)

	-- Überprüfe die Kollinearität (das Kreuzprodukt sollte nahe Null sein)
	return math.abs(crossProduct.Y) < 1  -- kleiner Schwellenwert für numerische Präzision
end

local function calculateLineCoefficients(point1, point2)
	-- Diese Funktion berechnet die Koeffizienten A, B und C der Linienformel
	local A = point2.Z - point1.Z
	local B = point1.X - point2.X
	local C = A * point1.X + B * point1.Z
	return A, B, C
end

local function distanceFromLine(point, A, B, C)
	-- Berechnet den Abstand des Punktes von der Linie
	return math.abs(A * point.X + B * point.Z + C) / math.sqrt(A^2 + B^2)
end



function updateCamera(deltaTime)
	if tracking and trackedCharacter and trackedCharacter:FindFirstChild("HumanoidRootPart") and localPlayer.Character and localPlayer.Character:FindFirstChild("HumanoidRootPart") then

		local hrpPos, dummyPos = localPlayer.Character.PrimaryPart.CFrame.Position, trackedCharacter.PrimaryPart.Position
		local CFam = CFrame.new(hrpPos, Vector3.new(dummyPos.X, hrpPos.Y, dummyPos.Z))

		-- making the offset relative to the HumanoidRootPart. It was in world coordinates before.
		local CamCFam = CFam*CFrame.new(3, dummyPos.Y, 7) -- change these numbers to change the offset

		camera.CFrame = CFrame.lookAt(CamCFam.Position, dummyPos)
		localPlayer.Character:SetPrimaryPartCFrame(CFam)
	end
end


UserInputService.InputBegan:Connect(OnInputBegan)
RunService.RenderStepped:Connect(function(deltaTime)
	updateCamera(deltaTime)
end)