Player clipping into ground while locking on

I am trying to make a lock on system similar to For Honor, you lock on, face the enemy, and the camera offsets over the shoulder a little.

The issue is that when I lock onto the enemy, I clip into the ground, the camera does track them but my body clips or teleports into the ground instead of facing the enemy.

I have looked through my code and I’m quite confused, I actually restarted from the beginning multiple times, and all of my attempts resulted in a similar effect of the player clipping into the ground, this was actually my 4th attempt.

I did look through posts and a lot of tutorials on youtube, infact most of my basis is actual off of tutorials (likely the issue), I tried my best to understand how the code works, and I think I got the general idea and understand it all a bit better but I couldn’t fix the issue

I am sorry if I overlooked something really simple and don’t mean to waste anyone’s time, I tried not to post anything on the dev forum and attempt to understand how to make something like this on my own but I’ve given up and would really appreciate some help on this.

-- Services

local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer

-- Camera Settings

local CameraSettings = {
	ViewLeft = 0,
	ViewRight = 15,
	ViewUp = 7,
	ViewDown = 0,
	ViewForwards = -25,
	ViewBackwards = 0,

	ViewRotationLeft = -10,
	ViewRotationRight = 0,
	ViewRotationUp = 0,
	ViewRotationDown = 0,
	ViewRotationForwards = 0,
	ViewRotationBackwards = 0,

	LockFieldOfView = 0,
	FieldOfView = 70,
}

local LockOnRange = 20
local LockOn = false
local CurrentTarget = nil
local LastTarget = nil

-- Functions

local function getClosestEnemy()
	local closestDistance = math.huge
	local closestEnemy = nil

	for _, obj in pairs(workspace:GetChildren()) do
		if obj:IsA("Model") and obj:FindFirstChild("Humanoid") and obj:FindFirstChild("HumanoidRootPart") and obj ~= LocalPlayer.Character then
			local distance = (obj.HumanoidRootPart.Position - LocalPlayer.Character.HumanoidRootPart.Position).magnitude
			if distance < closestDistance and distance <= LockOnRange then
				closestDistance = distance
				closestEnemy = obj
			end
		end
	end

	return closestEnemy
end

local function updateLockOn()
	if not LockOn or not CurrentTarget or not CurrentTarget.Parent then
		LockOn = false
		CurrentTarget = nil
		return
	end

	local distanceToTarget = (CurrentTarget.HumanoidRootPart.Position - LocalPlayer.Character.HumanoidRootPart.Position).magnitude
	if distanceToTarget > LockOnRange then
		local closestEnemy = getClosestEnemy()

		if closestEnemy then
			CurrentTarget = closestEnemy
		else
			LockOn = false
			CurrentTarget = nil
			return
		end
	end

	local lookVector = (CurrentTarget.HumanoidRootPart.Position - LocalPlayer.Character.HumanoidRootPart.Position).unit
	local rotation = CFrame.new(Vector3.new(), Vector3.new(lookVector.x, 0, lookVector.z))
	LocalPlayer.Character:SetPrimaryPartCFrame(CFrame.new(LocalPlayer.Character.HumanoidRootPart.Position) * rotation)

	local rotationAngle = math.rad(CameraSettings.ViewRotationLeft)
	local rotatedLookVector = Vector3.new(
		lookVector.x * math.cos(rotationAngle) - lookVector.z * math.sin(rotationAngle),
		lookVector.y,
		lookVector.x * math.sin(rotationAngle) + lookVector.z * math.cos(rotationAngle)
	)

	local cameraOffset = Vector3.new(
		CameraSettings.ViewRight,
		CameraSettings.ViewUp,
		CameraSettings.ViewForwards
	)
	local currentCFrame = workspace.CurrentCamera.CFrame
	local targetCFrame = CFrame.new(
		LocalPlayer.Character.HumanoidRootPart.Position + cameraOffset,
		LocalPlayer.Character.HumanoidRootPart.Position + cameraOffset + rotatedLookVector
	)
	workspace.CurrentCamera.CFrame = currentCFrame:Lerp(targetCFrame, 0.1)
end

local function toggleLockOn()
	LockOn = not LockOn
	if LockOn then
		CurrentTarget = getClosestEnemy()
		updateLockOn()
	else
		CurrentTarget = nil
	end
end

UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
	if not gameProcessedEvent then
		if input.KeyCode == Enum.KeyCode.LeftControl then
			toggleLockOn()
		end
	end
end)

RunService.RenderStepped:Connect(function()
	if LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("Humanoid") then
		updateLockOn()
	end
end)

maybe add a vertical offset to the cframe that sets the player’s position when locking on

I have tried this to where when locking on it would move the player up 3 studs so they wouldn’t clip into the ground, but I am hoping there’s a better way to do this and I am worried this will also cause issues in the future