Enemy not able to face the next node

Hello,

I’ve recently started working on an upcoming tower defense game genred project.
Everything is going well thank god however the enemies are not able to turn correctly to the next node. (The nodes are placed correctly, the matrix is probably wrong)

(It’s urgent)

An example of what I mean:
image

Code snippet:

local EnemyReplicator = {}
EnemyReplicator.__index = EnemyReplicator

local TweenService = game:GetService("TweenService")

type Enemy = {}

-- Enemy.new()
function EnemyReplicator.new(ENEMY_NAME: string, ENEMY_AMOUNT: number, ENEMY_SPAWN_DELAY: number)
	for i = ENEMY_AMOUNT, 0, -1 do
		-- Wait ENEMY_SPAWN_DELAY seconds before creating another one
		task.wait(ENEMY_SPAWN_DELAY)
		
		local newEnemy = game.ReplicatedStorage.Contents.Enemies:WaitForChild(ENEMY_NAME):Clone()
		newEnemy.Parent = workspace
		
		-- Set enemy attributes
		newEnemy:SetAttribute("ENEMY_TAG", tostring(ENEMY_NAME))
		newEnemy:SetAttribute("ENEMY_NODE", 1)
		
		-- Create enemy animation
		local enemyAnimation = Instance.new("Animation")
		enemyAnimation.Name = "WALK_ANIM_ENEMY"
		enemyAnimation.AnimationId = "rbxassetid://16851765962"
		
		newEnemy:WaitForChild("Humanoid"):LoadAnimation(enemyAnimation):Play()
		
		-- Set enemy properties and tags 
		newEnemy.Name = ENEMY_NAME..tostring(math.floor(math.random(1, 1000000)))
		newEnemy:AddTag("ENEMY")
		newEnemy:SetPrimaryPartCFrame(workspace.Map.Nodes:WaitForChild(tostring(require(game.ReplicatedStorage.Contents.Dictionaries.Constants).STARTER_NODE)).CFrame)
		
		-- Set part properties
		for i, part: BasePart in pairs(newEnemy:GetDescendants()) do
			if part:IsA("BasePart") then
				part.CanCollide = false
				part.CanTouch = false
			end
		end
	end
end

-- Enemy.move()
function EnemyReplicator.move(ENEMY_LOCATION: Instance)
	local ENEMY_ROOT: BasePart = ENEMY_LOCATION:WaitForChild("HumanoidRootPart")

	-- Create constants
	local mathFormula = 1 -- Will refer to the ENEMY_SPEED in the future

	-- Create tweens for the specific enemy
	if workspace.Map.Nodes:FindFirstChild(tostring(ENEMY_LOCATION:GetAttribute("ENEMY_NODE") + 1)) then
		local nextNode = workspace.Map.Nodes[ENEMY_LOCATION:GetAttribute("ENEMY_NODE") + 1]

		-- Calculate direction vector towards next node
		local direction = (nextNode.Position - ENEMY_ROOT.Position).Unit
		local mag = (nextNode.Position - ENEMY_ROOT.Position).Magnitude

		-- Detect if the enemy is near the next node
		if mag < 1 then
			-- Rotate the enemy smoothly to the next node's position			
			ENEMY_LOCATION:SetAttribute("ENEMY_NODE", ENEMY_LOCATION:GetAttribute("ENEMY_NODE") + 1)
			task.wait(0.2)
			
			TweenService:Create(ENEMY_ROOT, TweenInfo.new(mathFormula / 5, Enum.EasingStyle.Linear, Enum.EasingDirection.Out), {CFrame = CFrame.new(ENEMY_ROOT.CFrame.Position, workspace.Map.Nodes:FindFirstChild(tostring(ENEMY_LOCATION:GetAttribute("ENEMY_NODE") + 1)).Position)}):Play()
		else
			TweenService:Create(ENEMY_ROOT, TweenInfo.new(mathFormula / 2, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {CFrame = ENEMY_ROOT.CFrame:ToWorldSpace(CFrame.new(0, 0, -0.5))}):Play()
		end
	
	else
		-- Their base got damaged
	end
end

return EnemyReplicator

The line that controls the rotation:

TweenService:Create(ENEMY_ROOT, TweenInfo.new(mathFormula / 5, Enum.EasingStyle.Linear, Enum.EasingDirection.Out), {CFrame = CFrame.new(ENEMY_ROOT.CFrame.Position, workspace.Map.Nodes:FindFirstChild(tostring(ENEMY_LOCATION:GetAttribute("ENEMY_NODE") + 1)).Position)}):Play()
 

Thanks for the help.

1 Like