Hey guys (@HeadClot, @duke22), sorry for letting you wait. Here some details about my current traffic system.
1. The Vehicle
The vehicles are quite simple, just Static Meshes being pushed by linear forces for acceleration/breaking and turned by torque. As long as the car is slower than the “allowed maxSpeed” more force is added.
The vehicles are set up to follow a spline in that way that I have two waypoints that are always set in front of the car, directly on the spline. One of them is relatively close (600 units) and is used for calculating how much torque is needed. The second one is further ahead and is used for detecting if a sharp curve is ahead. The “allowed maxSpeed” is then decreased accordingly in order to avoid the cars to race through sharp corners^^
Each car has an overlap box in front of itself that, if something overlaps, makes the car break. Furthermore the car stops if it overlaps with a trigger box at traffic lights.
2. The Street system
I think that might be the more interesting part… I thought a lot of how to make the cars find their lanes and stick to them. Eventually I decided to put as much information as possible in the streets so that at runtime I dont need to perform a lot of calculations. My streets are not only static meshes but blueprint-components that include manually placed splines for each lane. Have a look on the following screenshot, showing the splines on the streets:
It is only a bit of work to place these, since I can use them in a highly modular manner. And the usage is very simple: Each spline has only two points and the tangents are adjusted to have them follow the lanes in a smooth manner. The car will find its closest spline and then simply copy the positions and locations of the spline points to its own spline that is used for steering (more details below).
Furthermore the street-blueprints generate VehicleSpawnLocations, you can see them on the screenshot as the dots on the lanes of the straight streets. I will come back to them later.
3. Lane finding
I needed to find a logic for the car for detecting on which lane it is and when to update the splines. That is actually quite easy:
Whenever the car reaches the end of its current spline it performs an overlap check at the end of the spline for finding new splines that originate from there. Since I placed and aligned them manually in the BluePrint-editor that works quite nicely. If there are multiple splines possible from that point, one is selected randomly.
For illustration, here are two sub-sequentially taken screenshots from a car driving approaching the intersection and then updates its own spline to match the predefined spline for a right turn:
4. Blueprint Overview
Here a quick overview over the vehicle’s blueprint:
Let me walk you through by explaining what the individual functions do:
Find and set spline: As described above, find splines that originate from position, select one randomly if multiple are available and update own spline accordingly.
Is on current spline: Simply check if the vehicle is still not at the end of its own spline. If it reaches the end, “Is On Current Spline” is set to false.
Get Current Speed: Just get the current linear velocity in km/h.
Break: Decrease velocity and make car stop.
Get Distance And Angle: I have to confess that at the moment I don’t remember what distance is calculated… But within this function he definitely calculates the angles between car forward-vector and car-to-waypoint (to near and far waypoint).
Set Waypoints: Both, far and near waypoint, are set to be in a certain distance to the car and directly on the spline.
Get Current MaxSpeed: Depending on the angle to the far waypoint the currently allowed MaxSpeed is decreased.
Perform Driving: Apply force and torque to the car, depending on current speed, currentMaxSpeed and AngleToWaypoint.
I just realized again that the entire script is still a bit messed-up. It evolved through a lot of stages and now, that it appears to be working, I have to clean it up and organize it a bit better^^ And optimize it performance-wise. Currently all functions are performed each tick, but I can have some functions (is on current spline, get angle to waypoint, …) be done only every fifth tick or so, I guess…
Ah, and I should not forget…
For spawning/deleting the ai_vehicles in the map I simply use a box that is attached to the player. The box tracks the number of cars within itself and also the overlapping SpawnPoints that I mentioned in the beginning.
If the number of cars is less than a defined number, the script randomly selects a SpawningPoint and checks, if it is within the player view frustum. If not, it checks if something overlaps with it. If not, it spawns a car on that point.
If you have any more questions, just let me know. Also, if you have comments or tipps, please let me know as well. Iam still in a steep learning curve