Greetings, fellow developers.
So, recently i’ve been working on a tower defense style game with the help of some friends, but we’ve ran into a problem while making the enemies movement:
All of the system works perfectly, except that for some reason, we cannot get the enemies to rotate smoothly after each waypoint. We’ve tried using CFrame.lookAt, BodyGyro, TweenService and others, but nothing seems to be working.
Here’s the Server side code:
local mob = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage:WaitForChild("Events")
local LastUpdate = tick()
local UpdateDT = 0.12
local ClientInfo = {}
local Positions = {}
game:GetService("RunService").Heartbeat:Connect(function(DeltaTime)
local map = workspace:WaitForChild("Map")
for number, data in pairs(Positions) do
local CurrentWaypoint = map.Waypoints:FindFirstChild(data.Waypoint)
local OldWaypoint = map.Waypoints:FindFirstChild(data.Waypoint - 1) or map.Start
if not CurrentWaypoint then
map.Base.Humanoid:TakeDamage(data.SpeedHealth.Y)
ClientInfo[number] = {Dead = true}
Events.UpdatePosition:FireAllClients(ClientInfo)
Positions[number] = nil
continue
end
local distance = (OldWaypoint.Position - CurrentWaypoint.Position).Magnitude
data.Moved += DeltaTime * data.SpeedHealth.X / distance
if data.Moved >= 1 then
data.Waypoint += 1
data.Moved = 0
end
ClientInfo[number] = Vector2int16.new(math.floor(CurrentWaypoint.Position.X*50), math.floor(CurrentWaypoint.Position.Z*50))
end
if tick() - LastUpdate >= UpdateDT then
LastUpdate = tick()
Events.UpdatePosition:FireAllClients(ClientInfo)
end
end)
local num = 0
shared["currentMobs"] = 0
function mob.Spawn(name, quantity, map)
local Exists = ReplicatedStorage.Mobs:FindFirstChild(name)
if Exists then
for i = 1, quantity do
num += 1
if shared["currentMobs"] < 0 then
shared["currentMobs"] = 0
end
shared["currentMobs"] += 1
Positions[num] = {
Waypoint = 1,
SpeedHealth = Vector2int16.new(math.round(Exists.Config.Speed.Value), math.round(Exists.Config.Health.Value)),
Moved = 0
}
Events.Render:FireAllClients(name, num)
task.wait(0.25)
end
end
end
return mob
And here’s the Client side code:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage:WaitForChild("Events")
local LastUpdate = tick()
local ud = 0.01
local Enemies = {}
local positions = {}
local map = workspace:WaitForChild("Map")
local base = map:WaitForChild("Base")
local PS = game:GetService("PhysicsService")
local function animation(object, anim)
Events.AnimateZombie:Fire(object, anim)
end
Events.UpdatePosition.OnClientEvent:Connect(function(info)
positions = info
end)
game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
if tick() - LastUpdate >= ud then
LastUpdate = tick()
for Enemyobject, data in pairs(Enemies) do
if Enemyobject and positions[data] then
local pos = positions[data]
if not pos.X or not pos.Y then
Enemies[Enemyobject] = nil
Enemyobject:Destroy()
continue
end
local Position = Vector3.new(pos.X/50, Enemyobject.PrimaryPart.Position.Y, pos.Y/50)
local Distance = (Enemyobject.PrimaryPart.Position - Position).Magnitude
local speed = Enemyobject.Config.Speed.Value
local cframe = CFrame.new(pos.X/50, Enemyobject.PrimaryPart.Position.Y, pos.Y/50)
Enemyobject.PrimaryPart.CFrame = CFrame.lookAt(Enemyobject.PrimaryPart.Position, Position)
Enemyobject:PivotTo(Enemyobject.PrimaryPart.CFrame:Lerp(cframe, deltaTime*speed/Distance))
end
end
end
end)
Events.Render.OnClientEvent:Connect(function(name, EnemyNumber)
local map = workspace:WaitForChild("Map")
local start = map:WaitForChild("Start")
local enemy = ReplicatedStorage.Mobs:FindFirstChild(name):Clone()
enemy.Parent = workspace.Mobs
if not enemy.PrimaryPart then
enemy.PrimaryPart = enemy.HumanoidRootPart
end
enemy.PrimaryPart.Anchored = true
enemy.PrimaryPart.CanCollide = false
for i, v in pairs(enemy:GetChildren()) do
if v:IsA("BasePart") then
PS:SetPartCollisionGroup(v, "Mob")
end
end
enemy.PrimaryPart.CFrame = start.CFrame + Vector3.new(0, (enemy.PrimaryPart.Size.Y/2 - 1), 0)
Enemies[enemy] = EnemyNumber
animation(enemy, "Walk")
end)
Does anyone know any possible solution? Thanks for reading!