Tower defense boss tilting to node?

i just finished my tower defense zombie movement, but when i try to spawn a boss, i added a function to rotate the zombie to the node, but sometimes the boss goes too far and is just stuck in that rotation, it’s not a bug, i just want to know how would i fix this?

movement code:
sorry for bad and messy code.

local root = script.Parent.HumanoidRootPart

local path = game.Workspace.path
local TweenService = game:GetService("TweenService")
local config = script.Parent.Config
local node = path

script.Parent.HumanoidRootPart.CFrame = CFrame.new(game.Workspace.spawn.CFrame.X, game.Workspace.spawn.CFrame.Y+1.2, game.Workspace.spawn.CFrame.Z)

-- beginning
local info = TweenInfo.new(0.1, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)

local tween = TweenService:Create(root, info, {
	CFrame = CFrame.new(root.Position, node.Position+Vector3.new(0,root.Size.Y,0)) 
})
tween:Play()
tween.Completed:Wait()

local dist = (root.CFrame.Position - node.CFrame.Position).magnitude
local speed = config.Speed.Value
local Time = dist/speed

local info = TweenInfo.new(Time, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)
local size = script.Parent.HumanoidRootPart.Size.Y/2+script.Parent["Left Leg"].Size.Y-0.5
local tween = TweenService:Create(root, info, {
	CFrame = CFrame.new(node.CFrame.Position.X, node.CFrame.Position.Y+size, node.CFrame.Position.Z)  * CFrame.fromEulerAnglesXYZ(root.CFrame:ToEulerAnglesXYZ())
})
tween:Play()
tween.Completed:Wait()

-- middle

for i, v in pairs(path:GetDescendants()) do
	node = v
	local info = TweenInfo.new(0.1, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)

	local tween = TweenService:Create(root, info, {
		CFrame = CFrame.new(root.Position, node.Position+Vector3.new(0, root.Size.Y, 0)) -- here it is
	})
	tween:Play()
	tween.Completed:Wait()
	
	local dist = (root.CFrame.Position - node.CFrame.Position).magnitude
	local speed = config.Speed.Value
	local Time = dist/speed
	
	local info = TweenInfo.new(Time, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)
	local size = script.Parent.HumanoidRootPart.Size.Y/2+script.Parent["Left Leg"].Size.Y-0.5
	local tween = TweenService:Create(root, info, {
		CFrame = CFrame.new(node.CFrame.Position.X, node.CFrame.Position.Y+size, node.CFrame.Position.Z)  * CFrame.fromEulerAnglesXYZ(root.CFrame:ToEulerAnglesXYZ())
	})
	tween:Play()
	tween.Completed:Wait()
	local decoy = node
	node = decoy:GetChildren()[1]
	print(node.Name)
end

working:

glitch:

you can see in the picture that the zombies humanoid is tilted to the node.

Hello there @Fx0mt !

I believe your problem is when you build your target CFrame inside your tweens. Although it’s good that you use the creation of the CFrame based on the 2 Vectors, the position and lookAt, your lookAt vector is not the correct one. Try modifying as follows:

thanks, even though its not 100 percent what i wanted, at least it works!

If you want some change, you can try explaining and I will try to help :smiley: !

okay, but it might be hard, when a zombie goes up a cliff, i want it to look up, like in the picture:

its fine if you cant do it, your code still works.

Ah okay, this is not hard, I’d say it’s quite simple. In the beginning of the script, store a local value like so:

local offset = Vector3.new(0, root.Position.Y - node.Position.Y, 0)

Careful, only use this in the beginning of the script on the first node!

Afterwards, change to:

local tween = TweenService:Create(root, info, {
	CFrame = CFrame.new(root.Position, node.Position + offset) 
})

it works on the first node, but the other nodes dont.

local root = script.Parent.HumanoidRootPart

local path = game.Workspace.path
local TweenService = game:GetService("TweenService")
local config = script.Parent.Config
local node = path
local offset = Vector3.new(0, root.Position.Y - node.Position.Y, 0)

script.Parent.HumanoidRootPart.CFrame = CFrame.new(game.Workspace.spawn.CFrame.X, game.Workspace.spawn.CFrame.Y+1.2, game.Workspace.spawn.CFrame.Z)

-- beginning
local info = TweenInfo.new(0.1, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)

local tween = TweenService:Create(root, info, {
	CFrame = CFrame.new(root.Position, node.Position + offset) 
})
tween:Play()
tween.Completed:Wait()

local dist = (root.CFrame.Position - node.CFrame.Position).magnitude
local speed = config.Speed.Value
local Time = dist/speed

local info = TweenInfo.new(Time, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)
local size = script.Parent.HumanoidRootPart.Size.Y/2+script.Parent["Left Leg"].Size.Y-0.5
local tween = TweenService:Create(root, info, {
	CFrame = CFrame.new(node.CFrame.Position.X, node.CFrame.Position.Y+size, node.CFrame.Position.Z)  * CFrame.fromEulerAnglesXYZ(root.CFrame:ToEulerAnglesXYZ())
})
tween:Play()
tween.Completed:Wait()

-- middle

for i, v in pairs(path:GetDescendants()) do
	node = v
	local offset = Vector3.new(0, root.Position.Y - node.Position.Y, 0)
	local info = TweenInfo.new(0.1, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)

	local tween = TweenService:Create(root, info, {
		CFrame = CFrame.new(root.Position, node.Position + offset) 
	})
	tween:Play()
	tween.Completed:Wait()
	
	local dist = (root.CFrame.Position - node.CFrame.Position).magnitude
	local speed = config.Speed.Value
	local Time = dist/speed
	
	local info = TweenInfo.new(Time, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)
	local size = script.Parent.HumanoidRootPart.Size.Y/2+script.Parent["Left Leg"].Size.Y-0.5
	local tween = TweenService:Create(root, info, {
		CFrame = CFrame.new(node.CFrame.Position.X, node.CFrame.Position.Y+size, node.CFrame.Position.Z)  * CFrame.fromEulerAnglesXYZ(root.CFrame:ToEulerAnglesXYZ())
	})
	tween:Play()
	tween.Completed:Wait()
	local decoy = node
	node = decoy:GetChildren()[1]
	print(node.Name)
end

Don’t initialize the offset again in the for loop!

Only keep it outside like you did on the top line:

Thanks! the code is working now