Simon Simon - 1 year ago 54
C# Question

Get first item in array where bool is false

I have GameObjects spawning in my game, those objects are being saved in an array.
That array gets sorted by distance from the player.

If the player has got his target (one of the objects) then that object his boolean "Claimed" needs to be set to true so other players cannot get that object anymore.

Instead they need to get the first item of that array where the boolean "Claimed" is false.

public void SearchFood()
AllFood = GameObject
.OrderBy(x => Vector3.Distance(this.transform.position, x.transform.position))

ClosestPieceOfFood = AllFood
.First(Claimed => ClosestPieceOfFood.GetComponent<Food>().Claimed == false);

ClosestPieceOfFood.GetComponent<Food>().Claimed = true;

The 2nd rule of the function is not working, im suspecting the problem being in "Claimed =>" but as im all new to Linq i don't really know where the problem is at.

I do not get any errors in my console log either about what could be the case.

Answer Source

A lambda is just a short hand way to write a function. In the case of First it takes a lamba that is passed in each item of the array and returns a bool and it will stop and return the first item that results in true from the lambda. So I think you actually want something like.

ClosestPieceOfFood = AllFood.First(Food => Food.GetComponent<Food>().Claimed == false);

Or personally I'd prefer

ClosestPieceOfFood = AllFood.First(Food => !Food.GetComponent<Food>().Claimed);

You might also want to consider using FirstOrDefault in case there is no unclaimed food. That will return null in that case where as First would throw an exception. You'd then need to check if ClosestPieceOfFood is null and handle that case appropriately.

Also you can combine the code that creates the array and finds the first unclaimed food together and skip creating the array.

ClosestPieceOfFood = GameObject
    .OrderBy(x => Vector3.Distance(this.transform.position, x.transform.position))
    .Select(x => x.GetComponent<Food>())
    .FirstOrDefault(Food => !Food.Claimed);

if(ClosestPieceOfFood != null)
    ClosestPieceOfFood.Claimed = true;