Hello everyone, as of recently I’ve created a new entity system that uses tables and lerping. It was very simple to make and it’s pretty good recv-wise. Though there’s some things that I probably optimize.
Here’s the things that I want to optimize:
A remote event firing everytime an entity spawns.
I want to rework this to only fire one remote event for every quantity that spawn. I tried doing this but I couldn’t get the spawn delay to working. So I just abandoned it completely.
Another thing I’d like to optimize is replacing heartbeats with something else in the client. I can heard this can cause memory leaks and I don’t wanna take any chances. Here is the code for this aswell.
LoadEnemy:Connect(function(Enemy)
local VisualEnemy = EnemyModels[Enemy.Name]:Clone()
local Info = EnemyInfo[Enemy.Name]
local Waypoints = {}
for i=1,#workspace:WaitForChild("Waypoints"):GetChildren() do
local Part = workspace:WaitForChild("Waypoints")[i]
table.insert(Waypoints, Part.Position)
end
local Path = BezierPath.new(Waypoints, 6)
local Lerp: RBXScriptConnection
VisualEnemy.Parent = workspace:WaitForChild("Enemies")
local Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://"..Info.Animation
local Animator = VisualEnemy.AnimationController.Animator
Animator:LoadAnimation(Animation):Play()
Lerp = RunService.Heartbeat:Connect(function(DeltaTime)
local Alpha = (workspace:GetServerTimeNow() - Enemy.StartTime) / (Path:GetPathLength() / Info.Speed)
VisualEnemy:PivotTo(Path:CalculateUniformCFrame(Alpha)*CFrame.new(Enemy.Offset, 0, 0))
if Alpha >= 1 then
print("Finished!")
VisualEnemy:Destroy()
Lerp:Disconnect()
end
end)
end)
--[[LoadTroop:Connect(function(Troop)
local Visual = TroopModels[Troop.Name]:Clone()
Visual:PivotTo(Troop.CFrame)
end)]]
Sorry for the extremely late reply, I just saw this now.
To fix it, I would use one RunService loop to change every enemy’s position. You should also be caching the BezierPath to avoid wasting resources.
Code:
local Enemies = workspace:WaitForChild("Enemies")
local Waypoints = {}
for i, part in workspace:WaitForChild("Waypoints"):GetChildren() do
table.insert(Waypoints, part.Position)
end
local Path = BezierPath.new(Waypoints, 6)
local enemies = {}
LoadEnemy:Connect(function(Enemy)
local Info = EnemyInfo[Enemy.Name]
local VisualEnemy = EnemyModels[Enemy.Name]:Clone()
VisualEnemy.Parent = Enemies
local Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://"..Info.Animation
local Animator = VisualEnemy.AnimationController.Animator
Animator:LoadAnimation(Animation):Play()
enemies[VisualEnemy] = {
Enemy.StartTime,
Enemy.Offset
}
end)
RunService.Heartbeat:Connect(function(DeltaTime)
for enemy, enemyData in enemies do
local Info = EnemyInfo[enemy.Name]
local Alpha = (workspace:GetServerTimeNow() - enemyData[1]) / (Path:GetPathLength() / Info.Speed)
enemy:PivotTo(Path:CalculateUniformCFrame(Alpha) * CFrame.new(enemyData[2], 0, 0))
if Alpha >= 1 then
enemies[enemy] = nil
enemy:Destroy()
end
end
end)
Thanks, but I already optimized my entity system xD, it’s really good as well, I’ve made it have no desync at all, one remote per quantity and one heartbeat for every enemy (using bulkmoveto)
BezierPath module already caches itself or stuff, also i’m pretty sure it’s better to put pivotto after the if statement so you don’t need to update the cframe for no reasons
oh i see you meant in that way ok
yeah it doesn’t cache the actual path but i don’t really see the purpose of caching the path if you need to generate a path like only once in the entire game