Tower Defense Simulator Enemy System

I have been wondering how to make an enemy system Similar to TDS. I have been struggling on making one for the past 6 hours, the thing I’ve been struggling on is the smooth curve tween or whatever it is.
image
I don’t want to use MoveTo as I heard it’s terrible for performance

local Tween = game:GetService("TweenService")
local enemy = workspace.EnemyBasePart
local Path = workspace.Map.Movement.Note
local spawn = workspace.Map.Movement.Spawn

local speed = 5
local rotspeed = 1

function SpawnEnemy()
	local entity = enemy:Clone()
	entity.CFrame = Path.CFrame
	entity.Parent = workspace
	MoveEnemy(entity)
end

function MoveEnemy(entity)
	local End = false
	local Note = Path
	while End == false do 
		local NextNote = Note:GetDescendants()
		if (#NextNote > 0) then
			Note = NextNote[1]
			local ParentNode = Note.Parent
			local Distance = (Note.Position-entity.Position).Magnitude
			if Distance >= 10 then
				local Goal = {}
				Goal.CFrame = CFrame.lookAt(entity.Position, Note.Position)
				
				local Info2 = TweenInfo.new(
					1,
					Enum.EasingStyle.Sine,
					Enum.EasingDirection.InOut,
					0,
					false,
					0
				)
				local TurnTween1 = Tween:Create(entity, Info2,Goal)
				TurnTween1:Play()
			end
			local Movement = Tween:Create(entity, TweenInfo.new(speed, Enum.EasingStyle.Linear), {Position = Note.Position})
			Movement:Play()
			Movement.Completed:Wait()
		else
			End = true
		end
	end
end

while true do
	SpawnEnemy()
	wait(2)
end

Help would be appreciated

1 Like

From the looks of it, the problem seems to be because it is taking the shortest path between the path end and path start while rotating.

image

My recommendation is to basically check if it is a turn, and then offset forward the end position by x studs and the start position of the next node backwards by x studs as well. Of course, x would ideally be a number a little less than half the width of the path (you choose what that might be). That way, the direct line would be shorter and less noticeable.

image

Now, if you do not care about having them turn near the middle of the intersection and you just want a smooth turn, then I suggest you take a look at Bezier Curves. They are far smoother and way more customizable, so they’ll give you a much better result if you are looking for the smoothest 90-degree turn.

it seems that I forgot to explain something, the image is a screenshot from a video of how I would like it to be. Sorry for not being clear enough :sweat_smile:
And thanks


this is a video of how it is now, it’s not much and pretty ugly looking. There is also a problem which the “Enemy” stops to plays the tweens and then teleports a few studs away from the Node, I am trying to fix the problems but it hasn’t been going too well.

I see the problem. Your approach uses something like this:

The yellow is the junction between the two paths, and the singular point of reference when it comes to movement. If you want it to look nicer, something like this would be much better:

In short, the end of a path and the start of another are two different points, and the script will have to Tween between them. This will add an actual “turning motion” to the mix which will look much nicer.

One problem that arises from this (which is due to the use of TweenService) is the fact that the motion is linear. What do I mean? The “tower” will follow a straight motion between the points like the yellow line below:

Now, a way to somewhat hack around this system is to “offset” the location of the ending nodes (in the script) so that they are further in to each other so the straight line isn’t as noticeable (basically what I said in my initial reply). This is how this looks like:

image

This way, the linear motion isn’t that noticeable and it doesn’t looks half bad since it is near the center.

If you are truly yearning for a smooth 90-degree curve, then you have to use Bezier Curves. In short, these allow you to create smooth turns and configure them in whatever way you want. Here’s an example of how a Bezier Curve looks like at a 90-degree angle (each gray part represents a location at the curve):

image

Of course, when going for this system, you’ll have to either make a special Tween case of the corners (and also make sure to code it in a way so that the points near the “middle” of the curve aren’t that condensed and are evenly spaced out), or you’ll have to follow a different movement approach that uses a set speed, which means that you could probably avoid having to evenly space out all points. Regardless, if you go for a Bezier Curve approach, make sure you read the Roblox article here as it has a lot of good information about them. You can also find tutorials on YouTube as well.

4 Likes

Thank you, this was an absolute lifesaver after 6 whole hours of struggling!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.