Tweening model with CFrame makes it rotate a way I don't want it to?

I am building a custom rig (no humanoid) and it works well. I’m making simple walk code for it; tweening its root position to a point. I obviously want the rig to face the direction it’s walking, which it does. At first. The character then starts slowly rotating (while still moving) to face roughly 0,0,0. I assume this is due to the fact that I’m tweening the character’s CFrame without giving it a rotation, but this raises all kind of issues on its own (ex. how to stop tween from affecting rotation). I’ve looked all over the place, the only thing I can find that seems related is this article, but it was never answered.

I’ve already tried tweening position, but that doen’t do well with the rig’s joints (check this link to see). So, what do I do to make it so tweening CFrame doesn’t affect the rotation of an object? Or, if I’m wrong, what is the issue and how to solve it?

(This is a video that shows my issue. Sorry, gyzao was refusing to work)
robloxapp-20231130-1745446.wmv

My code:

local walkTI = TweenInfo.new((root.Position-walkPosition).Magnitude/stat.Speed.Value,Enum.EasingStyle.Linear,Enum.EasingDirection.In)
walkTween = TS:Create(root,walkTI,{["CFrame"] = CFrame.new(walkPosition)})
walkTween:Play()
lookFrame = CFrame.lookAt(root.Position,walkPosition)

I have code below it that stops the tween after it gets close enough to the requested position, but I don’t think it’s affecting anything. If anyone wants to see the full script, I’ll post it.

Any help would be greatly appreciated!

Can you send the rest of the code?

Yes:

local root = script.Parent.HumanoidRootPart
local stat = script.Parent.Stats
local me = script.Parent
local state = "wary" --active: loop every 0.01 seconds. wary: loop every 0.1 seconds. idle: loop every 2 seconds
local activeDist = math.max(stat.Range.Value * 3,50)
local lastAttacked = 0
local walkTrigger = false
local walking = true
local walkAnim = script.Parent.Animator:LoadAnimation(me.Walk)
local walkTween
local TS = game:GetService("TweenService")
local walkPosition = Vector3.new(-91.044, 3, -69.387)
local lookFrame
task.wait(5)
while true do
	local closestEnemy =  nil
	local closestDistance = 10000
	-- SELECT CLOSEST ENEMY
	if walking and walking ~= walkTrigger then
		walkTrigger = true
		walkAnim:Play()
		local walkTI = TweenInfo.new((root.Position-walkPosition).Magnitude/stat.Speed.Value,Enum.EasingStyle.Linear,Enum.EasingDirection.In)
		walkTween = TS:Create(root,walkTI,{["CFrame"] = CFrame.new(walkPosition)})
		walkTween:Play()
		lookFrame = CFrame.lookAt(root.Position,walkPosition)
	elseif not walking and walkTrigger ~= walking then
		walkAnim:Stop()
		walkTween:Pause()
		walkTrigger = false
	end
	if walking then
		if (root.Position-walkPosition).Magnitude <= stat.Range.Value then
			walking = false
		else
			root.CFrame = lookFrame
		end
	end
	for _,folder in pairs(workspace.TeamObjects:GetChildren())do
		if folder.Name ~= stat.Team.Value then --make sure we don't target friendlies
			for _,obj in pairs(folder.Noobs:GetChildren()) do
				if obj.Stats.Health.Value > 0 and obj ~= me then
					if (root.Position - obj.HumanoidRootPart.Position).Magnitude < closestDistance then
						closestDistance = (root.Position - obj.HumanoidRootPart.Position).Magnitude
						closestEnemy = obj
					end
				end
			end
		end
	end
	if closestEnemy then
		
	end
	if state == "idle" then
		task.wait(2)
	elseif state == "wary" then
		task.wait(0.1)
	else
		task.wait(0.01)
	end
end

This is an AI script I’m working on that will be put in soldiers. It’s not finished yet.