How to make a linear bezier curve movement in the enemies system?

Hello.

Already a long time I’m working on the enemy system for my tower defense game. I’ve already made version which uses RemoteEvent to send all data about the enemies to the client, so the client creates enemy model and then moves it using TweenService. Problem of this version is that there is a lot of tweens which client creates (since I sent data every 10th RunService.Heartbeat event), so enemies lag and teleport sometimes, which is result that I don’t really want to achieve in alpha release of the game. I want to have good enemies system which will make players’ experience really good. Also problem is that a lot of data sending so often, so Recieve may just die when there will be around 500 enemies (Do not say, that I can reduce it with bitpacking, I’ve already done that). So I want to make a new one version for my tower defense game.

How this should work:
For example, we spawn enemy on the server using EntitiesModule:Spawn(). Basically enemy on the server is just an array with some data. Example:

EnemyData = {
    CFrame = CFrame.new(0, 0, 0);
    Replicator = NewReplicator;
    Debuffs = {};
}

You may ask, what is a “Replicator”? Here is the answer:
Replicator is a Folder in ReplicatedStorage.Storage.Enemies which stores enemy’s Health, Speed, SpawnedTime (this is os.clock() time) and any other stats that should be seen to the client.

About movement:
On the server we just go through every single enemy every RunService.Heartbeat and move it. Here the problem appears. When rotation is not needed and we are not even close to the TargetPoint we can just move enemy using code below:

local LookCFrame = CFrame.lookAt(EnemyStatements.CFrame.Position, TargetPoint.CFrame.Position)
local WalkedCFrame = CFrame.new(LookCFrame.Position + (LookCFrame.LookVector * (Speed / 60)) * LookCFrame.Rotation
EnemyStatements.CFrame = WalkedCFrame

But when we are close to the target point (for example magnitude between enemy’s CFrame and TargetPoint is 3 studs) then of course we need to smoothly rotate enemy, and here I prefer to use Bezier Curves.
I found Bhristt’s Bezier Curve Module. That’s what I need because it calculates curves where all points are created on the constant distance among each other.

I’ve tried to make a linear movement using Speed Constant for a lot of days and still didn’t find working solution. I want to know, how to make linear and smooth movement using the Speed constant and bezier curves. Currently, rotation in my code is really bad and it’s not linear, for somewhy it gets faster when Bezier Rotation Time is like 0.25 or 0.75.

Here’s the place file where you can see what I`ve done while working on the server part of this enemies system. I hope someone can help me with that. Also I’m sorry that code looks bad. Since I was working on the test version, I didn’t care a lot about it’s readability.
EnemySystemCodeShowcase.rbxl (58,7 КБ)

Anyway if someone want to know what’s next after this server side movement:
I want to replace data sending with client calculating, that’s why we need SpawnedTime attribute created in Replicator folder. So we spawn enemy’s model on the client and calculate how much it walked using this time. Basically we also should use DeltaTime in this calculations, since RunService.Heartbeat event is based on client FPS. If you have better suggestions for this enemy system then you can contact me.
Thanks everyone for trying to help, I will credit people with best answers in my game.

2 Likes

This seems like great progress for an open sourced non-humanoid system.