Search Unity

How to make branching splines ?

Discussion in 'Scripting' started by softwizz, Oct 8, 2016.

  1. softwizz

    softwizz

    Joined:
    Mar 12, 2011
    Posts:
    793
    I want to try my hand at a game similar to those where you flick switches to guide trains to the relevant station without crashing.

    I searched for spline branching and branching splines etc but the results are like this:


    I dont think I've ever had Google return 1 result before
    So any help ?
     
    Last edited: Oct 8, 2016
  2. Teravisor

    Teravisor

    Joined:
    Dec 29, 2014
    Posts:
    654
    You mean a curve that smoothly splits into two? You do tricks or differential math or you bruteforce.
    Look at bezier curve. It has at least 3 points, right? Now the trick is that when line starts from first point, its differential vector is directed into second point. And when exiting from last point it's always directed from previous point. Now how can we use it?
    You place a bezier curve. Now you already know where differential vector in end point, so you can create several bezier curves, place all their starting points into that end point, place all theirs second points on same line as end point and point before it was... And you get smooth splitting curve no matter where their end points are.
    Problem with using it as-is is that parameter t in bezier curve is not linear, so if you pass train onto bezier curve, it will move slower/faster on curve (maybe that can be intentional, but you can't properly control its speed). So you approximate it by sampling a lot of points along it and making discreet line with enough points in-between (you'd need that to render curve anyway).

    If you don't like Bezier, in general, you need to solve math problem: you need to calculate differential vector (f_x(t)' and f_y(t)', that can be calculated by just taking small enough difference) of spline in its end point you already have and find functions f1_x(t), f1_y(t) and f2_x(t), f2_y(t) for two curves (f1_x is x coordinate of first curve, f1_y is y coordinate of first curve, same for f2; t is same as in previous functions f_x(t), f_y(t) you have) that will have same differential vector in end point of first spline and pass where you want (only direction needs to be same; orientation and length of differential vector do not matter).

    Third way is brute force: you make a spline into a lot of points and make a discreet line with finite amount of points. Then set maximum angle one small segment can rotate, and start doing same things as rail companies do to place rails: you go along them and turn them how you want, then place next rail (point on small distance) then repeat. This requires no more than simple vector math (rotate previous vector from -angle to angle depending on what you want and then place next point small distance along that direction, rotate, move from new point, place, repeat). You can branch from anywhere this way with how many rails you want.

    Summary: First way is good if you want to represent things in editor for others to show or make premade levels.
    Second way... I'm not sure why I listed it. It's hard to do that properly.
    Third way is if you're just going to program it and forget. I'd suggest to use recursions, but they tend to overflow stack.

    TL;DR:
    Do one of three: use Bezier curve and place them so where they link they have 3 points on same line. OR use math and calculate curves. OR just iterate through railing while imagining you're rail construction worker who places new rails.
     
    Last edited: Oct 9, 2016
    Kurt-Dekker and softwizz like this.
  3. softwizz

    softwizz

    Joined:
    Mar 12, 2011
    Posts:
    793
  4. Teravisor

    Teravisor

    Joined:
    Dec 29, 2014
    Posts:
    654
    They do it much simpler. They have tilemap and each of tiles has one of graphics where track goes. Then they just swap graphics (and logic where train goes through that tile).
    In assets they most likely have a line rail and 90 degree curve rail and then just rotate those sprites to fit in.
     
  5. softwizz

    softwizz

    Joined:
    Mar 12, 2011
    Posts:
    793
    Yes its the path following and logic at the point the track switched that I am not sure how to do it.
     
  6. Teravisor

    Teravisor

    Joined:
    Dec 29, 2014
    Posts:
    654
    Where's problem? It seems so simple that I don't see one.
    First make graphics. Just translate and rotate tiles.
    Then make logic. Simply make two arrays: vectors making a line (two points) and vectors making a circle (depends on resolution you want). When train enters tile, he checks what is in tile (is it line or curve?), rotates corresponding array and follows it.

    Or you go for maths and do line formula (x(t)=5, y(t)=1+t/speed for example where 5 and 1 are tile coordinates) and circle formula (x = x0+r*cos(t/speed_in_circle), y = y0+r*sin(t/speed_in_circle)) and just place train there while offsetting t by needed amount.
     
  7. softwizz

    softwizz

    Joined:
    Mar 12, 2011
    Posts:
    793
    Indeed Teravisor the visual aspect of rotating or changing image to show a track straight or curved is simple.

    I was just unsure of how to approach the actual path the train takes as in programming there are always more ways than 1 to achieve the same result and since I have not used this type of logic before I was unsure of how to proceed.

    What I might try is the 2 array method you suggest.

    Thanks.
     
  8. Teravisor

    Teravisor

    Joined:
    Dec 29, 2014
    Posts:
    654
    In most cases, choose fastest one you can make. It needs to work.
    Optimizations and such come later.
     
    softwizz likes this.