- Home /
How can I fix this so it picks out the shortest distance in the for each?
Hello here is my code:
if(GameObject.FindObjectOfType().SR.sprite == GameObject.FindObjectOfType().PS)
{
foreach(GameObject platform in platforms)
{
float shortestDi = Vector2.Distance(transform.position.x - platform.transform.position.x);
float yD = Vector2.Distance(transform.position.x - platforms[].transform.position.x);
if (yD <= 6.43f)
{
}
}
}
what I am trying to fix is to make it I can find the object in the array with the shortest distance, I was just wondering if you guys could help me, thanks!
Answer by JVene · Oct 17, 2018 at 10:33 PM
This pattern can be implemented a number of ways, but the first common theme is to initialize the goal before the loop, in this case, the shortest, so it is retain when the loop is over. The puzzle most stumble on is how to deal with the first entry, or put another way, how to start the comparison of which is shortest. For a short entry, it can't start at zero, as that is the shortest possible difference.
You could chose an arbitrary, very large distance to start things off. Another approach is to use a bool that starts out false, indicating uninitialized, and using the bool to control initialization vs subsequent testing.
Something like:
float shortest = 1000000.0f;
foreach(GameObject platform in platforms)
{
float d = Vector3.Distance( transform.position, platform.transform.position );
if ( d < shortest ) shortest = d;
}
Key notes here, relative to the code you posted, is that Distance of Vector3 (or Vector2) takes two vectors, not a subtraction of two floats as you posted. It returns a distance, which in the example above will very likely be less than the initialized value on the first test, and all subsequent tests will only update 'shortest' when that particular d (from platform) is lower than what 'shortest' is tracking. If you needed to retain which platform, you'll have to create and set a variable of type GameObject when shortest is updated.
If, in future scenario, you find an initial value difficult to predict, you can use a boolean to control initialization with something like this alternative:
float shortest = 0f;
bool initialized = false;
foreach(GameObject platform in platforms)
{
float d = Vector3.Distance( transform.position, platform.transform.position );
if ( initialized == true )
{
if ( d < shortest ) shortest = d;
}
else {
initialized = true;
shortest = d;
}
}
That is a little extra work inside the loop, but it is useful if you can't easily select the first entry of platforms. If you can easily select platforms[0], you can initialize shortest to that distance as a start, even though the loop will repeat that comparison once.
Actually it's easier to use either +infinity as initial value or just use the first element of the list as initial value and just iterate over the rest.
float shortest = float.PositiveInfinity;
Being lazy as I like to be, I would use Linq to keep everything in one simple line
float $$anonymous$$ = list.$$anonymous$$in(platform => Vector3.Distance(platform.transform.position, this.transform.position));
Of course your answer is better if you want to actually learn something, I just wanted to throw in a lazy approach
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
How to compare several distances? 1 Answer
Distribute terrain in zones 3 Answers
Question on Using a Foreach Loop on Nested Children 1 Answer
C# Creating a 2d boundary 1 Answer