Hello all,
I have recently started working on a tower defense game where everything was going fine until I encountered my first enemy system bug where it waits before continuing to the next node when taking corners.
I mean I want it to behave so that it still rotates to face the next target node whilst moving towards it.
Thank you so much for your time.
function EnemyController:Move(Enemy)
local MovementSpeed = Configurator:GetConfigValue(Enemy, "Base_Walk_Speed")
local Waypoints = workspace:WaitForChild("Map"):WaitForChild("Nodes")
local EnemyRoot = Enemy:WaitForChild("HumanoidRootPart", 5)
local EnemyHumanoid = Enemy:WaitForChild("Humanoid", 5)
local EnemyID = Enemy:GetAttribute("ID")
assert(EnemyRoot, "ERROR: Enemy is not a humanoid model.")
assert(EnemyHumanoid, "ERROR: Enemy does not have a valid humanoid.")
-- Collect and sort waypoints numerically
local sortedWaypoints = {}
for _, wp in ipairs(Waypoints:GetChildren()) do
local num = tonumber(wp.Name)
if num then
table.insert(sortedWaypoints, {num = num, part = wp})
end
end
table.sort(sortedWaypoints, function(a, b) return a.num < b.num end)
for idx, waypointData in ipairs(sortedWaypoints) do
if not Enemy or not Enemy.Parent then break end
local targetPart = waypointData.part
local targetPos = targetPart.Position
-- Calculate movement tween parameters
local currentPos = EnemyRoot.Position
local distance = (targetPos - currentPos).Magnitude
local duration = distance / MovementSpeed
-- Movement tween: tween only the position, keep the current rotation.
-- Extract the current rotation from the EnemyRoot's CFrame.
local currentRotation = EnemyRoot.CFrame - EnemyRoot.Position
local targetCFrame = CFrame.new(targetPos) * currentRotation
local moveTweenInfo = TweenInfo.new(duration, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)
local moveTween = TweenService:Create(EnemyRoot, moveTweenInfo, {CFrame = targetCFrame})
moveTween:Play()
moveTween.Completed:Wait()
-- If there is another waypoint, perform a quick rotation tween to face it.
if idx < #sortedWaypoints then
local nextTargetPos = sortedWaypoints[idx+1].part.Position
-- Create a CFrame at the enemy's current position facing the next waypoint.
local desiredCFrame = CFrame.new(EnemyRoot.Position, nextTargetPos)
local rotateTweenInfo = TweenInfo.new(0.225, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
local rotateTween = TweenService:Create(EnemyRoot, rotateTweenInfo, {CFrame = desiredCFrame})
rotateTween:Play()
rotateTween.Completed:Wait()
else
-- Last waypoint: destroy enemy
self:DestroyEnemy(Enemy)
end
end
end```