Making smooth curves for my Tower Defense

So in TDS and TDX there are smooth turns that the enemies make, does anyone have any help with this where the Bezier curve doesn’t make it all curved?

1 Like

You can try using Chaikin’s algorithm.

This is more of a more complex approach, do you think just explain how I would be able to use Bezier curves to make the Enemy go around corners but not straight baths

Well, I will try explaining it using Bhristt’s Bezier Curve Module.

  • Install the Module:

  • Download the module from the Roblox Developer Forum.
  • Insert it into your game’s ReplicatedStorage for easy access.
  • Define Control Points:

  • Identify key waypoints that your enemy should pass through.
  • For smoother transitions, especially around corners, add additional control points to shape the curve appropriately.
  • Create the Bezier Curve:

  • Require the module in your script:
  • local Bezier = require(game.ReplicatedStorage:WaitForChild("Bezier"))
    
  • Initialize a new Bezier curve with your control points:
  • local bezierCurve = Bezier.new(controlPoint1, controlPoint2, controlPoint3, controlPoint4)
    
  • Replace controlPoint1, controlPoint2, etc., with your actual Vector3 positions or BasePart instances.
  • Calculate Positions Along the Curve:

  • To move your enemy along the curve, calculate positions at intervals:
  • for t = 0, 1, 0.01 do
      local position = bezierCurve:CalculatePositionAt(t)
      -- Move your enemy to 'position'
      wait(0.1) -- Adjust the wait time as needed
    end
    
  • Here, t ranges from 0 to 1, representing the start and end of the curve.
  • Align Enemy Orientation:

  • To ensure the enemy faces the direction of movement, calculate the derivative (tangent) at each point:
  • local tangent = bezierCurve:CalculateDerivativeAt(t)
    enemy.CFrame = CFrame.new(position, position + tangent)
    
  • This sets the enemy’s CFrame to face along the path.
  • Incorporate Tweening for Smooth Motion: (OPTIONAL)

  • Utilize the module’s tweening support to create smooth transitions:
  • local tweenInfo = TweenInfo.new(5, Enum.EasingStyle.Linear)
    local tween = bezierCurve:CreateCFrameTween(enemy, {CFrame = CFrame.new()}, tweenInfo)
    tween:Play()
    
  • This creates a tween that moves the enemy along the curve over 5 seconds.

Hope that helps. Note that I am human and can make mistakes too, so I highly recommend checking the documentation page about that.

1 Like

Sorry for the long wait, but this worked out great! I just needed to fix {CFrame = CFrame.new()} into {"CFrame = CFrame.new()"}

Sure, nice work. I am happy to help.

But how would I make it for every corner?

Also I kind of wanted this to be generated before the enemy spawns

Yea, sure. I can help with that.

To handle every corner, ensure you add control points for each critical waypoint or sharp turn.
Use additional intermediate points between corners to make the curve flow naturally. Pre-plan these waypoints based on your map layout. Recode your script and you’re good to go.

For pre-generating paths, create the Bezier curve during game initialization or map loading. Save the generated curve data (control points and positions) in a table or object for reuse when spawning enemies. This avoids recalculating the curve repeatedly and ensures consistent movement paths for all enemies.

While I’m trying to explain this, the best way to assist would be sharing the “AI” script for the enemy to provide more specific help. Ideally, if you could share edit permissions to the game, that would allow direct fixes and improvements—but I understand that may not be feasible.

1 Like

Thanks, this helped a lot and saved me so much time