How to Make Roads with Bezier Curves - Godot 4.0 Behind the Scenes!

Поділитися
Вставка
  • Опубліковано 24 сер 2024

КОМЕНТАРІ • 71

  • @BeauSeymour
    @BeauSeymour  Рік тому +10

    Thanks for watching! Let me know what kinda tutorial you want to see next and like/subscribe! 🥳

    • @somedude5951
      @somedude5951 Рік тому +1

      A tutorial I would like, would be some way to generate the map by the player. Like, when digging a tunnel.

    • @car_meh
      @car_meh Рік тому +1

      Beau! Bézier Curves are so pleasing to behold! Have you considered using these nicely curved paths in an endless racer game? Merging some of your existing projects/concepts from last year such as Twilight City? Your own ideas for videos and projects are great on their own, and I look forward to what's next. Thanks for sharing all your work in Godot game development!

    • @BeauSeymour
      @BeauSeymour  Рік тому +2

      Thanks for the feedback and glad you liked my other vids ^^. I don't think this approach would work for an endless runner necessarily, as there's a cost to moving CSGMeshes realtime which may end up prohibitive. I might revisit some old Surface Tool code which should be more performant. I got the path mesh to work from memory, I was just having issues with UVs, so fixing for that would need to happen first!

    • @BeauSeymour
      @BeauSeymour  Рік тому

      Not sure I know what you mean, but you can make a CSGMesh subtractive which will allow you to tunnel through other CSGMeshes. Something that I toyed with but couldn't get materials to play nice procedurally.

    • @somedude5951
      @somedude5951 Рік тому

      @@BeauSeymour Well, I'm looking for a way to tunnel, if there is, to tunnel to new area. Making mesh where there is none. As in open worlds, but instead of a landscape, tunnels to dig.

  • @mch43856
    @mch43856 Рік тому +8

    The amount of work that goes into tutorials like these is admirable, great job!!

  • @paulmaguire872
    @paulmaguire872 7 місяців тому +1

    Wow, brilliant sir. This will take a few watches. I also love your, what I assume, is your default work environment within GODOT which has sparked ideas of my own. Cheers

    • @BeauSeymour
      @BeauSeymour  7 місяців тому

      Glad you liked it ^^. It certainly was my default for a while but for reasons unknown I don't use it anymore (but should!)

  • @muhammadmujtaba611
    @muhammadmujtaba611 2 місяці тому

    very clear, straightforward and good tutorial

  • @Nico121Niku
    @Nico121Niku Місяць тому

    Thank you for this video! I had many questions but everything is clear now!

  • @andriiandrieiev2805
    @andriiandrieiev2805 11 днів тому

    Thank you sir!

  • @nitokoshiro5904
    @nitokoshiro5904 Рік тому +4

    Would you be willing to make a follow-up tutorial where you expand this spline track system further? Most racing games would require track tilt and track width parameters per spline point as well as perhaps the ability to create forks for optional shortcuts. As far as I am aware, no tutorial maker ever dared to touch on these topics before. Games could hardly be made without them, though.

    • @BeauSeymour
      @BeauSeymour  Рік тому +2

      Well tilt is largely available though finicky using the Path3D handles. One issue with this is the curve handles affect the tilt along the entire spline, so granular per-point controls is not there (yet, there's a github issue where someone talks about adding tilt vector factoring for CSGPolygons, so may be available in future).
      Per point width is stepping into custom mesh solution rather than a built in node solution, which is even more finnicky. The Riverways plugin I think is close to what you'd want, so could look at that as a basis and build something off the back of it.

    • @nitokoshiro5904
      @nitokoshiro5904 Рік тому

      @@BeauSeymour Personally, I'd always build the track visuals entirely by hand, so this additional spline data would be used exclusively for non-graphical purposes. AI racers, for instance, would need the width data for track navigation. Cameras would use the tilt vector to remain upright without the need for raycasts.
      I've taken a look at Riverways in the past, and it's very close to what I'm looking for. A combination of lackluster code documentation and my own inability forced me to give up eventually. I'll surely come back to it some day.

  • @AbdouMadjidi_.
    @AbdouMadjidi_. Рік тому +10

    Sebastian lague godot version

    • @BeauSeymour
      @BeauSeymour  Рік тому +8

      Haha I'll take that compliment! Thanks 🙏

  • @JorgeRosa
    @JorgeRosa Рік тому +3

    Brilliant! 👍

  • @wukerplank
    @wukerplank 5 місяців тому

    Piece of art! Thank you!

  • @TomCrowKid
    @TomCrowKid 4 місяці тому

    This is a fantastic tutorial!

  • @quentindelvallet
    @quentindelvallet 2 місяці тому

    Very useful video, thank you!

  • @HavingFunTimes
    @HavingFunTimes Рік тому +1

    I love this thank you for making it

  • @thomasrodriguez3107
    @thomasrodriguez3107 Рік тому +1

    Thank you !!!

  • @motizukilucas
    @motizukilucas 2 місяці тому

    Thank you for this amazing content!
    I had a question tho, considering this CSG is a 3D node, is there an equivalent way for 2D?

    • @BeauSeymour
      @BeauSeymour  Місяць тому

      I don't really dabble with 2D, but does the Line2D node not cover most of it? Otherwise you'd probably want to spring your own mesh by iterating each point pair and calculating the perpendicular vector to determine width and assigning UVs accordingly.

  • @EeVeE3D
    @EeVeE3D Рік тому +2

    Cool

  • @n41sd
    @n41sd Рік тому +2

    great video!! Following the channel. A doubt I have (I asked this question in another video on a similar subject) would you know how to place objects only when there is a curve? I wanted to put signs pointing curves on the track but I don't know what is the best way to detect the curvature of the track and direction to define the side where the pointing signs will be placed.

    • @BeauSeymour
      @BeauSeymour  Рік тому +1

      Great idea and can think of a few ways you could attack the problem, though will need to test them out. First thing that comes to mind would be to iterate the baked points to take a moving average of turn vectors, then defining a threshold but there's probably better ways.

    • @n41sd
      @n41sd Рік тому

      @@BeauSeymour I have a racing game project that I created a track system with this technique about 3 years ago (I ended up pausing the project at the time due to Godot 3.x limitations and I'm resuming work now with Godot 4). I tried some ways to do this, what I can say is that in practice the signposts should start to be placed before the curves so that the player is informed in advance (maybe an offset). At the time I made a raycast walking on the curve with an object ahead of it, then I could detect the curve, but it wasn't very efficient.
      I'll take a look at what you said, but one thing I realized is that it's necessary to have a curvature control that also detects the length of the curve, because if not in very short and smooth curves it puts the signs that maybe not are necessary.

    • @BeauSeymour
      @BeauSeymour  Рік тому +2

      Bit late to reply, but had a break from this project for a while. The following is how I (now) detect corners to autopopulate curve signs:
      func get_curvature_3d(point1:Vector3, point2:Vector3, point3:Vector3):
      # Get the direction vector of the line between point1 and point2
      var d1 = point2 - point1
      # Get the direction vector of the line between point2 and point3
      var d2 = point3 - point2
      # Calculate the cross product of the two direction vectors
      var cross = d1.cross(d2)
      # Calculate the magnitude of the cross product
      var magnitude = cross.length()
      # Calculate the dot product of the two direction vectors
      var dot = d1.dot(d2)
      # Calculate the curvature
      var curvature = magnitude / abs(dot)
      return curvature
      You then feed it point1 (which would be some distance behind the current point on the curve), point2 (the currently sampled point on the curve) and point 3 (some distance ahead on the curve). I may cover this more in another video as I've revamped a lot of the code from this one already to make it do more.

    • @BeauSeymour
      @BeauSeymour  Рік тому +1

      If you want to see what that looks like:
      twitter.com/Bimbam_tm/status/1619664573531062273?s=20

    • @n41sd
      @n41sd Рік тому

      @@BeauSeymour Thanks for this function! It will be very useful!!

  • @mattseaton5832
    @mattseaton5832 7 місяців тому +2

    This is a nice method, but quick question. What if I wanted to make something more than a simple loop? What if I wanted to build city roads with intersections? Do you know how one would go about doing that using this approach? I could intersect the curve on itself but the textures would be wrong and the side of the road meshes need to be deleted somehow. Or perhaps I would have to put the intersection pieces first and then connect them with individual curves?

    • @BeauSeymour
      @BeauSeymour  7 місяців тому +2

      I'm not sure what the 'correct' method is, but suspect the only reasonable way to handle intersections is to precreate them as models, then snap the road curve to them at defined entry/exit points. Anything else I can think up just breaks the moment you try to automate texturing it :S Maybe some I'll have to investigate in a later video but caught up with another project ATM ^^

  • @anthonyhalpin66
    @anthonyhalpin66 7 місяців тому

    Nice tutorial but I'm getting completely stuck at 03:07 when you create the other kerb. No idea how you've done it, you skip through at lightening speed.

    • @BeauSeymour
      @BeauSeymour  7 місяців тому

      If you pause at 2:58 you will see in the top right that the four points on screen that represent the road shape are 2D coordinates. (0.0,0.0) -> (0.0,0.1) -> (0.1,0.1) -> (0.1,0.0). This is a closed loop, so the last link to (0.0,0.0) is implied. The Y component defines the height of the road mesh, the X component the width of the road.
      I just copy this csgmesh that represents the road and tweak at 3:02 to make the 'curb' segments for the left-hand side. All I am doing is making the points start at (0.0,0.0) but then move left of it (negative on the X axis) and slightly higher than the road on the Y axis.
      The right-hand side is the same again, but I am moving the points further right of 0.1 on the X axis, and the same amount higher on the Y axis as before.
      Hopefully that helps but let me know how you go!

    • @anthonyhalpin66
      @anthonyhalpin66 6 місяців тому

      @@BeauSeymour Excellent, thank you very much!

  • @Jackhenrey
    @Jackhenrey 4 місяці тому

    Thats amazing but how to edit track in packaged game not in editor

    • @BeauSeymour
      @BeauSeymour  4 місяці тому

      You would need to build the GUI interface for the user to interact with, which then interfaces with the Path3D node under the hood. This is by definition unique to your implementation, but any GUI tutorials will help get you started.

    • @Jackhenrey
      @Jackhenrey 4 місяці тому

      @@BeauSeymour thank you now i know where to start

  • @NINJAETS7
    @NINJAETS7 5 місяців тому

    can you please tell me how u opened the top orthogonal window?

    • @BeauSeymour
      @BeauSeymour  5 місяців тому

      Where it says 'top orthogonal' in the top left of the window is a button with several drop down options for different views. Alternatively clicking the 'Y' of the gizmo in the top right does the same.

    • @NINJAETS7
      @NINJAETS7 3 місяці тому

      @@BeauSeymour thanks for replyin! appreciate dat

  • @gusteen3292
    @gusteen3292 Рік тому

    Question, Does this tool have the ability to organically add split paths and gaps into the track for more dynamic design, and does this tool also allow you to widen or thin certain parts of the track. If there is where can I learn about doing that?

    • @BeauSeymour
      @BeauSeymour  Рік тому +2

      None of the above, and all of that would require using a custom mesh implementation (though you could still sample a curve to define the track). Godot's Surface Tool is the easiest approach. Making track wider/thinner situationally is fairly easy, I did it in a later clip just by having a path for the inner and outer edge of the track, but ultimately there comes a point where it's easier to just custom model the solution. I highly doubt any aspect of Mario Kart was procedural for example. If it had to be procedural I would probably prefab a bunch of track splitting models and have the path end snap to the location needed for a seamless transition, then two new paths start on the other side. It would likely be quite finicky/bespoke though so don't expect a general tool to exist. The alternative I can only imagine would have some horrible vertex proximity lookups with some kinda smoothing and the UV situation would be diabolical.

  • @StaredownGames
    @StaredownGames Рік тому

    Man, I was hoping I could utilize this in 3.5 but for whatever reason it will NOT accept "$Spawn".
    It even auto-completes, but I just get "Can't use get_node with absolute paths outside of active scene tree". Bummer!
    I tried onready var spawn = $Spawn. Nothing. Thanks for sharing!

    • @BeauSeymour
      @BeauSeymour  Рік тому

      Hmm in principle it should work the same in G3.x so not sure what's going on here :(

    • @StaredownGames
      @StaredownGames Рік тому

      @@BeauSeymour no worries, I have 4.0 now. Thank you!

  • @antonsimkin
    @antonsimkin Рік тому

    I have problems with big scale. At 5:18 you suggested to bake meshes to be static. Could you please elaborate a bit more or give a link to tutorial or something what do you mean exactly?

    • @BeauSeymour
      @BeauSeymour  Рік тому +2

      For Godot 3.x there was a at least one plugin to export/bake csg meshes to a static .obj file. I've not used them as never hit performance issues, but for example you could look at the code for this and convert to Godot 4.0 here: godotengine.org/asset-library/asset/563

    • @antonsimkin
      @antonsimkin Рік тому

      @@BeauSeymour thank you!

  • @lillysmith6123
    @lillysmith6123 Рік тому

    Two questions:
    How bad are the performance issues, (And where are they)?
    How does this interact with collisions? (Could this be used to generate collissions as well?)

    • @BeauSeymour
      @BeauSeymour  Рік тому

      Re. Performance, I've only really noticed it when editing and it's minor fps dips. The moment you let go of the mouse it's back to normal, though I can't say how big a impact there would be at scale or when combining with other Boolean objects. I think ultimately it's fine for static tracks, but would likely fall over if you wanted real-time track updates during gameplay (which tbh would have it's own quirks to deal with anyway re. Collisions).
      Re. Collisions in general, already there as CSGMeshes have the option by default.

    • @lillysmith6123
      @lillysmith6123 Рік тому +1

      @@BeauSeymour So Satisfactory belts should be fine, but Mario Kart wiggly tracks are out?
      Good enough for me :D

    • @BeauSeymour
      @BeauSeymour  Рік тому

      @@lillysmith6123 wiggly tracks is something I'm eyeballing, but not using CSGMeshes for. Future video perhaps if I get it working.

  • @JohnStonexDj
    @JohnStonexDj 3 місяці тому

    how you made this snap funktion?

    • @BeauSeymour
      @BeauSeymour  3 місяці тому

      Just iterate the defined path and raycast down for each position to find ground position, store these as a new path and replace the old one with it when finished

  • @Artriix_
    @Artriix_ Рік тому

    How i can make this water??🥺

    • @BeauSeymour
      @BeauSeymour  Рік тому

      I basically use the same approach as I discuss in this video: ua-cam.com/video/T1Eri8ql7Sg/v-deo.html

  • @maniksharma9736
    @maniksharma9736 Рік тому

    What is a surface tool???

    • @BeauSeymour
      @BeauSeymour  Рік тому +1

      Surface tool is one of the methods in Godot to define meshes manually (by specifying every vertex position/UV etc.). It enables completely customisable mesh generation, but is a fair amount more involved to get into and is entirely driven by code.

    • @maniksharma9736
      @maniksharma9736 Рік тому +1

      @@BeauSeymour oo i get it now...
      Btw great tutorial...

  • @UltimatePerfection
    @UltimatePerfection 2 місяці тому

    And how about actual production games? CSG nodes are basically useless for real games, only for prototyping as they don't have UVs.

    • @BeauSeymour
      @BeauSeymour  2 місяці тому +1

      I didn't realise Triplanar mapping wasn't used in 'real games'.