1

TL;DR How can I make filled true if 1 object is in the same position and not all of them? (I had an else statement doing the same thing previously, but changed it to this assuming that was the problem.)

Hello, my drag drop script checks if transform positions match to swap items and organize them for inventories and hotbars. When an item is in the same position as an inventory slot it gets set to filled. I thought it was all working fine until recently I realized that when I added an else to make sure filled gets set to false when an item isn't equal to it's position (When an item gets consumed, moved, etc.), but when I have the else statement on filled is locked to false. I did some testing and the script works properly when there's only 1 item in the array and doesn't when there's more, so I'm assuming it's comparing all of them to see if every single position matches. How can I make it check if atleast 1 position matches for it to become true. Here's what the code in question looks like.

private void Update()
{
       foreach (GameObject g in Updater.barred) 
       { 
             if (g.transform.position == this.transform.position)
             { 
                  this.filled = true; 
             }
       }
}

private void LateUpdate()
{
       foreach (GameObject g in Updater.barred)
           if (this.transform.position != g.transform.position)
           { 
                this.filled = false; 
           }
}
Prasad Telkikar
  • 15,207
  • 5
  • 21
  • 44
Zeelkra
  • 13
  • 2

2 Answers2

2

You can use break to exit for loop as soon as this.filled set to true or false.

The break statement terminates the closest enclosing loop

private void LateUpdate()
{
       foreach (GameObject g in Updater.barred)
           if (this.transform.position != g.transform.position)
           { 
                this.filled = false; 
                break;  //This will exit execution of foreach loop.
           }
}

Or you can use Linq Any(), to set expected value of this.filled, one liner

Determines whether any element of a sequence exists or satisfies a condition.

this.filled = Updater.barred.Any(g => g.transform.position != this.transform.position);
Prasad Telkikar
  • 15,207
  • 5
  • 21
  • 44
  • 1
    Thank you! Something like this is exactly what I was looking for. – Zeelkra Aug 09 '20 at 09:33
  • Comparing two positions may never end up true because of float inaccuracy. You could use Vector3.Distance smaller than a small value. – Everts Aug 09 '20 at 17:54
0

Answering TL;DR - Wouldn't this LINQ expression be sufficient for you:

if (Updater.barred.Count(x => x.transform.position == this.transform.position) == 1)
    this.filled = true;

Also I am not familiar with unity (if this is unity), but are you sure x.transform.position struct/class overrides '==' operator?

J. Doe
  • 1
  • 1
  • 1
  • Count vs Any -> https://stackoverflow.com/a/305156/6299857, your if condition can be converted to `this.filled = Updater.barred.Any(x => x.transform.position == this.transform.position)` – Prasad Telkikar Aug 09 '20 at 09:21
  • Any() would be the same as Count >= 1, not Count == 1 (and would be more efficient if that's what you want). The question is a bit ambiguous as the TLDR implies he's looking for exactly one match while the rest of the question implies he's looking for any matches. But given the context I suspect Any() is what the OP wants. – IceGlasses Aug 09 '20 at 09:31
  • Well OP stated a condition 'if 1 object is in the same position and not all of them', which makes me think that .Any() is unsuitable here as .Any() would return true for a case when all items match the condition, which contradicts with OP's initial question – J. Doe Aug 09 '20 at 10:06
  • @J.Doe Any() would return true for a case when **all** items match the condition -> No. It is `All()`. `Any()` returns true if any of the case satisfies condition – Prasad Telkikar Aug 09 '20 at 10:50
  • My point is .Any() would return true is there is either 1 or N items that match the predicate as Any returns after 1st successful occurence. Whereas according to the question (or at least as I understood it) OP wanted to check for exact 1 match, not at least 1. – J. Doe Aug 09 '20 at 11:36