City traffic Lanes

It’s been a while, but I’ve returned to working on an open city world in unity. I know how to script a car, and have it follow waypoints and so on, what I’m struggling with is how to have the cars in lanes, so opposing sides of the road move in opposite directions.

I know you could have ‘sets’ of waypoints, but then, how would you make sure the cars moved in random directions? So when they get to junctions, how do they decide whether they are going to go left, or right, or straight on?

My gripe is that games over the years have made it look so simple; from the obvious like Grand Theft Auto, to just being part of the race in games like Need For Speed. Is there just a set of formulae or something that people have used? Who knows.

So yeah, any assistance would be great.

[EDIT] Having figured most of the problem is about the multiple choice decisions the cars need to make at each junction, this is the main problem. Having the cars make different choices already solves the 2-way road problems, so I just need to grasp how to get each car to make a decision and then take the appropriate set of waypoints.

Here’s a suggestion… This won’t solve the problem, but it might help to get outside the box…

Use one set of waypoints, running down the middle of the street.

But instead of having your cars try to line up the center of the car with the waypoint path, have the car line up with a point set just outside the driver’s side door.

That way, cars can use either set, and the side of the road they are on will be defined by the way they are going.

Would only work for two lane roads, but I could see the use of a Lane variable that would move the car farther and farther away from the middle…

Car AI is quite a challenging thing to do (as is any form of AI actually). The easiest solution that I can think of, is to just check which side of the road your car is on and adjust the steering behaviour accordingly. For checking, you can do something like

Vector3 v_direction = v_currentWaypoint - v_lastWaypoint; 
// assume waypoints are Vector3s and set in the middle of the road
Vector3 v_right = Vector3.Cross(v_direction, Vector3.up);
if(Vector3.Dot(transform.position - v_lastWaypoint, v_right) > 0)
    // you're on the right side
    // you're on the left side

Alternatively, you could define your navmesh(es) by using one-way waypoints only. So you basically have a set of waypoints for each lane and only allow traversing them in one direction (this can usually be achieved by just not setting the previous waypoint as a neighbour of the following one.

For decisions on crossroads: I would just randomly select any waypoint on the navmesh and let the pathfinding do the rest. If the car reaches the waypoint, just pick another one. Or you could just scrap pathfinding altogether for that and random pick one of the neighbouring waypoints.

Quick Edit:
This will only take care of your very basic navigation needs. You will still have to deal with stuff like avoiding obstacles, trafic signals and so on