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:
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.