Answer from reddit post: How to select objects in arbitrary 2d space using only arrow keys? : Unity2D
This is probably a bit suboptimal, but you could try this:
Suppose you press the right key. Now you get a list of all the objects to the right of the one that is currently selected. Exclude those that are outside the 90° angle centered on the right-pointing vector (the math here is rather simple I think, you just have to compare the x and y deltas) and then just pick the leftmost one.
This has the downside of being unable to choose an object if it’s the only one to the right but it’s outside the 90 degree angle, so you would have to press a different key to get it. You could fix that, if you want, by removing the 90 degree rule if there is only one object in the initial list of candidates, just automatically choosing it instead.
- get all objects to the right
- if there are none - do nothing, done
- else, cycle though the objects in the list and compile a new list of ones that are inside the right-pointing sector (by comparing x and y deltas; remember to use >= to avoid losing perfect diagonals)
- if 3 is empty, just select the leftmost one
- else, select the leftmost of those you have picked in 3, done
4 is required if you want to be able to select something new even if the candidates are way out of the way, like 1 pixel to the right and then all the way down. If you’re comfortable not selecting those - end the function on that step instead of selecting anything.
Edit: you can also play with the angle to expand the selectable area, if 90 degrees proves too restrictive.
This seems like it will work, thank you! I was actually thinking of something like this, except with doing some sort of 90 degree triangular raycast, and then choosing whichever it hits first. But there isn’t a triangular raycast. However, a raycast isn’t necessary. I like your idea of just making a list of all the objects inside a triangular area, and then choosing the closest one from those. Doing at least 90 degrees is important, since this divides the space into 4 quadrants, with no point excluded.
I would revise “leftmost” in step 5 though. Instead, I would look for the overall nearest point. This turns that theoretical triangle cast to have a rounded edge. See diagram.
Pressing right at A should go to C. Only looking at the x axis distance would cause a conflict between B,C,D.
Also I really appreciate the edge case covered in 4. I think I can code this now, thank you!
I’m only familiar with unity raycasts in theory, but I think this isn’t the case for them. Simple math is more than enough here
Doing at least 90 degrees is
important, since this divides the
space into 4 quadrants, with no point
Yep. I suggested you look into using wider angles to maybe make the user experience a little better. This will make the objects located in the angle overlap selectable by 2 keys, not just 1.
I would revise “leftmost” in steps 3-4
though. Instead, I would look for the
overall nearest point. This turns that
theoretical triangle cast to have a
rounded edge. See diagram.
Good call! My morning brain didn’t catch this. Also, you should take special care of the case when 2 or more objects are equally distant - it’s not obvious which one you should pick, since their location can still affect your decision making.