Randomly Build a Race road

Hi,
I am making a JS which builds a random race road for my game,

It uses a prefab pieces of roads to build the road an shown :

My problem now that sometimes blocks interferes with each other :

I want to know what is your opinions on solving this problem, how can i detect the surrounding?

Concept of solution is enough but i would appreciate a script references for the solution.

Note : This is not an infinite road but it will be built once only, so i can’t destroy the blocks because other player vehicles could be on them.

This is my current code :

#pragma strict
private var Me : Transform;
var Sections : int;

var SectionBlockNo : int;
@Range(0,100) var TurnPer : int;

var BeginPieces : Transform[];
var StraightPieces : Transform[];
var TurnPieces : Transform[];
var SpecialPieces : Transform[];

function Awake ()
{
    Me = transform;
    Level ();
}

function Level ()
{
    MakeLevel(SectionBlockNo);
}

function MakeLevel (BlockNo : int)
{
    var InstPosition : Vector3;
    var Piece : Transform;
    var NewPiece : Transform;
    var RoadPiece : RoadPiece;
   
    Piece = BeginPieces.GetValue(Random.Range(0,BeginPieces.Length));
   
    NewPiece = Instantiate (Piece , Me.position , Me.rotation);
   
    RoadPiece = NewPiece.gameObject.GetComponent("RoadPiece");
   
    Me.position = RoadPiece.EndPoint.position;
    Me.rotation = RoadPiece.EndPoint.rotation;
   
    for (var i : int = 0; i < BlockNo;i++)
    {
        var RandomChance : int = Random.Range(0,100);
       
        if(RandomChance >= TurnPer)
        {
            Piece = StraightPieces.GetValue(Random.Range(0,StraightPieces.Length));
        }
        else
        {
            Piece = TurnPieces.GetValue(Random.Range(0,TurnPieces.Length));
        }
       
        NewPiece = Instantiate (Piece , Me.position , Me.rotation);
       
        RoadPiece = NewPiece.gameObject.GetComponent("RoadPiece");
       
        Me.position = RoadPiece.EndPoint.position;
        Me.rotation = RoadPiece.EndPoint.rotation;
    }
}

Can you post your current code

Added to the post

Here’s my understanding. You could detect if a piece is at the desired position with OverlapSphere or a simple raycast, and then instantiate properly based on wether or not the desired position is occupied.

The problem is, you could end up creating a box of roads and turn INSIDE of it, and then you’d get to the point where there are no logical places to go as you would be stuck between 4 roads.

I could very well be wrong, but to me it sounds like you’d need some fairly complex algorithm that would consider every roads positions and see if you’re headed into a dead end.

Here’s an alternative, although it may not be the most optimized way to go.

  • Figure out your detection logic before you start, wether it’s raycasting at the target position, or using overlapsphere linked above.
  • Create a prefab with nothing but a collider that has the same size than your roads.
  • Create a GameObject array that has the same length than your number of roads. Fill it with instances of the prefab. These will serve as detection dummies.
  • Create an int array that has the same length than your number of roads.
  • Run your code, and instead of instantiating the roads directly, move the corresponding GameObject*,* from the GameObject array we just created, to the position where the road was to be instantiated. Store the road piece you just randomized into the integer array we created, to remember what road piece will be used for the current value of int “i”, if the path is successful.

If you make it to the last piece without getting stuck, then run your instantiating logic using the integer array to remember what piece goes where, then destroy the gameobjects in the array we created.

If you get stuck in the way, reset the function/values and run it again.

It may take a few iterations before your road is created, depending on the length of your road mainly.

EDIT:
Another way to do this could be to:

  • Create a script with a public function used to check if the object is overlapping with another road piece, using overlapsphere or raycast. Attach it to your roads prefabs.
  • Run your randomizing logic on the first road piece, and position the rest of the straight road pieces accordingly. Call the detection function on all the pieces that have been moved and if no problems have occurred, move to the next road piece. If a problem has occurred, reroll the current piece.

Pro: This option ensures that you always have a path available and you don’t have to start a new iteration from scratch.

Con : Lets say you have 10 pieces of roads that you want to place. If the first and the second are straight paths, the third turns left, the 4th is straight, the 5th turns left and then the 6th turns left again. In theory, at this point, this would still be a possible path, but with the current option, it won’t work because it’ll calculate that the 8th path is overlapping with the second path, and will recalculate because of that. Therefore, this option drastically reduces the amount of potential paths.

Thanks a lot that what i was thinking,

also i have an idea if making the road rises above of drops below when there is an interfere,
this roads are on nature places like forest or desert so it will be good to make some caves and bridge roads,

so if there is a box of roads I stuck on it then the builder can make a bridge or cave piece(s) that goes above or below the bath.

I would set a max size for your world and make a 2d array storing your references to your trackparts. so you could also make something like for example in your second picture
if lastSet trackpart ist left from current && current ist already straight up part make a crossing part.