Getting "wrong way" indicator right when track goes Y shape?

Started by
7 comments, last by Aybe One 3 weeks, 5 days ago

Simple problem I'm struggling to figure out a solution for…

Here's an image with explanations:

  • track is made of sections
  • sections are made of quads
  • spheres indicate section centers
  • magenta line means section has a junction
  • blue/orange lines mean section is a junction (start/inside)
  • triangle is the player

I get the wrong way by doing dot(ship direction, section forward), this works fine when there is no junction.

To try address this when there is one, I do dot twice, 1st with section, 2nd with junction then do dot = max(dot1, dot2).

I also lower the dot threshold a bit for this particular case.

It looks better but still doesn't feel quite right…

Any clues in getting this more robust are welcome!

Thank you 😁

Advertisement

I see 3 options. Probably you should combine at least two:

  1. Relax the waypoints, which would give a smoother representation like this:

2. Take N segments around the player and average them. E.g. with N = 5, to smooth it out further.

3. Use a exponential temporal average for even more smoothness. This adds some latency, but games usually take some time to show the wrong way indicator anyway.

Regarding #1, since I'm still on the new engine for an old game, I undo-ed my ‘section center smoothing’, original data is like you suggested, centers are offset somehow:

I more or less implemented it getting forward like the one you drew, right before junction. But it was only marginally better, even when accounting for edges cases (e.g. very late turn).

Didn't try #2 because I don't really understand what you meant by averaging.

But #3… 😁👌It removes the false warnings, still need to tweak it but it's already dope! And that late trigger effect is definitely spot on!

Thanks!!! 🥳💯

Your relaxation picture shows the opposite result of what's expected.

The simplest algorithm would be to set each waypoint to the average from it's adjacent points.
Ofc. you can do only a few iterations of that to preserve enough detail, but should be enough.

Aybe One said:
Didn't try #2 because I don't really understand what you meant by averaging.

I mean to make an average from a few nearby segments, like marked here in yellow:

Like all my ideas, it's a low pass filter intended to remove noise.
So this one would be a spatial filter, while option 3 is a temporal filter.
Combining both would make it more stable fixing most problems, but as always filtering also might add some new ones.

JoeJ said:
Take N segments around the player and average them.

This would be my first approach. If the target is always the next dot it's too close. I'd take the next 3 to 5 or so markers, depending on how distantly you've placed them, because that's the general direction the player ought to be going. I think I'd also skip the nearest ‘next’ marker.

Using only one “next” marker, if the player is sitting off to the right of the single marker it will be pointing directly to the left instead of forward. Similarly, if they're left of the marker it will be pointing to the right instead of forward. As they travel the course passing markers it will jump to the right or left as they approach each one. By including the next several markers in the distance, even if the player isn't directly in line with the current marker they'll still be directed in the correct “travel this way” direction.

frob said:
I'd take the next 3 to 5 or so markers,

Personally i'm unsure if taking only next (or future) markers is better, or if including previous (past) markers as well is better. Then i thought it's about the ‘current’ position and direction, so i have proposed the latter. But surely worth to try out both.

Remembering games which do this, i think they often showed the indicator only after i was driving the wrong way already for some time. Maybe they track the distance to the right path as well to prevent false positives from such filtering methods.

Well, it's been a frustrating experience to say the least…

The main problem I haven't been able to solve was ‘wrong way’ when the ship is at the face in the middle of the picture; i.e. 2nd section with junction, close where the wall splits in two. If I stay there and look to the right junction, I get ‘wrong way’, very frustrating.

So, by lack of making progress, I decided to start from scratch with no idea behind.

First, I ensured to grab a better region of interest:

Then I thought of trying to make a ‘dynamic’ dot (red) on the yellow line:

And that works pretty well along exponential smoothing! 🙂
The ship can turn around up to a direction that a human still considers as not ‘wrong way’.
I tried to clamp projection in line segment but I failed so I just let it overshoot…

Another thing I also tried, is to set max dot to -1 in this region, i.e. disable the indicator in this region. It works from player perspective although it feels a bit weird when leaving the zone.

Well, well, well… 🤣

Today, I just remembered that I had the source code of a commercial game sitting in my HDD.

All they did is this:

            if (dot < settingsShip.Dot)
            {
                WrongWayTimer += Time.deltaTime;
            }
            else
            {
                WrongWayTimer = 0.0f;
            }

            playerShip.Flags.SetFlags(ShipFlags.DIRECTION, WrongWayTimer < settingsShip.WrongWayTimerLimit);

I tried, it works perfectly…

No need to fuss with projections and whatnot anymore…

But I kept your suggestion of smoothing exponentially the dot!
This is because it looked weird to immediately suppress the indicator when facing forward.
It triggers late on wrong direction, so should it be on the right direction.

Another lesson learned the hard way (again)…

It seems that no matter how long one might have been programming, sometimes a very simple thing can make one completely lose his rational sense… (at least for me)

Time to celebrate and move on, thanks guys! 🥳

Advertisement