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

Поделиться
HTML-код
  • Опубликовано: 27 окт 2024

Комментарии • 70

  • @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 9 месяцев назад +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  9 месяцев назад

      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 4 месяца назад

    very clear, straightforward and good tutorial

  • @Nico121Niku
    @Nico121Niku 3 месяца назад

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

  • @nitokoshiro5904
    @nitokoshiro5904 Год назад +5

    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 🙏

  • @wukerplank
    @wukerplank 7 месяцев назад

    Piece of art! Thank you!

  • @TomCrowKid
    @TomCrowKid 6 месяцев назад

    This is a fantastic tutorial!

  • @JorgeRosa
    @JorgeRosa Год назад +3

    Brilliant! 👍

  • @quentindelvallet
    @quentindelvallet 5 месяцев назад

    Very useful video, thank you!

  • @andriiandrieiev2805
    @andriiandrieiev2805 2 месяца назад

    Thank you sir!

  • @HavingFunTimes
    @HavingFunTimes Год назад +1

    I love this thank you for making it

  • @mattseaton5832
    @mattseaton5832 9 месяцев назад +3

    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  9 месяцев назад +3

      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 ^^

  • @motizukilucas
    @motizukilucas 4 месяца назад

    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  3 месяца назад

      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.

  • @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!!

  • @JohnStonexDj
    @JohnStonexDj 6 месяцев назад +1

    how you made this snap funktion?

    • @BeauSeymour
      @BeauSeymour  5 месяцев назад +1

      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

  • @Jackhenrey
    @Jackhenrey 6 месяцев назад +1

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

    • @BeauSeymour
      @BeauSeymour  6 месяцев назад +1

      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 6 месяцев назад +1

      @@BeauSeymour thank you now i know where to start

  • @NINJAETS7
    @NINJAETS7 8 месяцев назад +1

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

    • @BeauSeymour
      @BeauSeymour  7 месяцев назад

      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 5 месяцев назад

      @@BeauSeymour thanks for replyin! appreciate dat

  • @StaredownGames
    @StaredownGames Год назад +1

    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!

  • @EeVeE3D
    @EeVeE3D Год назад +2

    Cool

  • @anthonyhalpin66
    @anthonyhalpin66 9 месяцев назад

    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  9 месяцев назад

      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 9 месяцев назад

      @@BeauSeymour Excellent, thank you very much!

  • @lillysmith6123
    @lillysmith6123 Год назад +1

    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  Год назад +1

      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 Год назад +2

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

    • @BeauSeymour
      @BeauSeymour  Год назад +1

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

  • @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!

  • @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.

  • @Artriix_
    @Artriix_ Год назад +1

    How i can make this water??🥺

    • @BeauSeymour
      @BeauSeymour  Год назад +1

      I basically use the same approach as I discuss in this video: ruclips.net/video/T1Eri8ql7Sg/видео.html

  • @UltimatePerfection
    @UltimatePerfection 5 месяцев назад +1

    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  4 месяца назад +4

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

  • @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...