Hey
I’ve been trying to implement racing position for a racing game. I can’t find anything clear on this topic. Why is that? I mean there’s no proper tutorial for this anywhere.
I’ve been trying for a looped Lap race kinda game.
I’m using spline and I got the race progress from that but couldn’t sort the array properly since I’ve separate actor for Player car and AI car.
Can anybody show me a way for this?
I found other answers very unclear, that’s not helping
You could even improve this by creating a Float:Actor map, where you use the DistanceAlongSpline as Key and the Car Actor as Value.
Then create a SortFloatArrayDescending function in C++ like this:
UFUNCTION(BlueprintCallable, Category = "Utilities")
static TArray<float> SortFloatArrayDescending(TArray<float> Array) {
Array.Sort([](const float& a, const float& b) { return a > b; });
return Array;
}
This function can then be used to sort the Keys (Distances) of the Map from High to Low.
Next you could just use the sorted Keys to get the according Car for every Position
I don’t know what I did wrong
but it didn’t work for me.
I need to connect this event to tick, right?
or should I create a timer?
Also what exactly the outcome of current position array after the for loop completed?
will it sort the array from high to low or low to high position?
I wouldn’t call this event every tick. Perhaps every 10th or so…
The CurrentPosition Array is an Array of Actors. Just Actors and nothing special.
It should be filled with every Car Actor (including the player Car).
The RankPosition Array is an Array of Actors again. But it can be left empty, since it gets filled via the event and written back to the CurrentPosition Array.
So… CurrentPosition is the Array you use to get all Position Infos from.
The Event should be placed in a BP that is persistent per level… So… the GameState Blueprint is the BP you put it into.
The reason is a bit of foreshadowing.
The GameState is a BP that syncs rules and options from the GameMode to the Clients and vise versa, sends rule and option request to the GameMode.
So… In your GameState Blueprint:
You will need a Point Type variable,too. Set its X to 0 and Y to How many ticks it needs to call the Event (f.e. 10)
In the GameState, add a Tick event.
Now check for the Point Variable X to be >= Y (with a Branch).
If true, call the Ranking Event and set the X back to 0.
If false, add 1 to X.
Edit:
Just in case you wonder, why i use a Point Type Variable…
You can use two Ints, too.
Or a struct holding current and max…
I looked through a couple of answers but found most too complicated.
I have this actually done and is working perfectly and here is some pseudo code:
Spline distance for measuring between 0 and 1 for tracking player on the current lap.
You add 1 in the case that a player is crossing the finish line. You need a direction check atfinish line and checkpoints on the road to have a solid version of this. Then you create an array of all players where you store the distances + laps so you have a float array which says 0.78,1.23,1.67 and so on . Then you do a copy of this and use this in a function what you call every frame. You must not sort this because you in the function you check what Is the highest float so max of array this is your
player place number one . Do it in a loop an delete the value out of the array so that is empty at the End . You can either save this on an array which would be sorted then or what I do I progress this further to my playerstate where I save the player place. Then you just need to bind this player place to a widget and your done
You can sort without duplicating, resizing or shuffling down into lower indexes. Just do it in a while loop, swap to back the highest and -1 the index on every loop until == 0.
/**
* Max of Array
* @param Array of templated type
* @param Optional pointer for returning the index of the maximum element, if multiple maximum elements the first index is returned
* @return The max value found in the array or default value if the array was empty
*/
template< class T >
static FORCEINLINE T Max(const TArray<T>& Values, int32* MaxIndex = NULL)
{
if (Values.Num() == 0)
{
if (MaxIndex)
{
*MaxIndex = INDEX_NONE;
}
return T();
}
T CurMax = Values[0];
int32 CurMaxIndex = 0;
for (int32 v = 1; v < Values.Num(); ++v)
{
const T Value = Values[v];
if (CurMax < Value)
{
CurMax = Value;
CurMaxIndex = v;
}
}
if (MaxIndex)
{
*MaxIndex = CurMaxIndex;
}
return CurMax;
}