This is a very simple but non-ideal and time-consuming solution.
Create new Blueprint named BP_WayPoint. The blueprint will have a variable of type Int wchis is public (with name Index). Within the compoent setup, add a spahre or box collsion component and Block to false, but make sure Generate Overlap is enabled. Inside you Charcter blueprint add a varible of type Int (named ActiveIndex).
During level design, you will place instances of BP_WayPoint along your rece-track and edit the Index variable from 0,1,2… ie The waypoint at start of the track will have index 0, the next one will have 1 and so on. This is the time-consuming part.
In the Character blueprints BeginPlay event, you will set ActiveIndex to 0.
In the BP_WayPoint blueprint’s event graph, add event for BeginOverlap. In this event, you check if the value Index variable of the overlapped WayPoint is greater than ActiveIndex. If it is, then you are going in the proper direction. Otherwsie you are going the wrong way. In either case, you will update the ActiveIndex with the Index of the overlapped WayPoint
You will need addiotnal logic to make sure the message is not shown when you are reversing (sicne the index will decrement in this case).
The accuracy of this method depnds on how well you place the WayPoint objects. In a strignt road, you only need one at the start and end. But at turns, you might need more WayPoints.
Actually you could reduce the level designers work (of setting indices) by making the WayPoint obejects hold a refrence to each other (like a linked list). But once you get this simple emthod working, you will be able to figure taht out yourselves.
Advantages:
Very simple logic.
No tracing so better performance.
You can make ti work in tight curves… by poerply placing the WayPoints.
Disadvantages:
Time consuming. In bigger tracks, setting all the indices is very tiring.
Will not work if the track has branches.