Iterate through list one item at a time

I made a list which I add “fuel” objects for a campfire to it OnTriggerEnter and remove OnTriggerExit (colliders) and OnTriggerStay it loops through these objects and “removes health/fuel” until they are at 0 and I run Destroy()

The problem is if I have 2 or more objects in this trigger zone it depletes the health of all objects in parallel but I want it to deplete on just one object at a time.

So 5 or 10 objects take longer to destroy than 2.

I tried to get the first list object but it still iterates through all of them at the same time:

void OnTriggerStay(Collider other)
    {

        for (int i = 0; i < fuelList.Count; i++) {            

            Fuel fuel = fuelList[0].GetComponent<Fuel>();

            if (fuel.fuelType == "timber") {
                print("fuel amount is " + fuel.fuelAmount);

                fuel.fuelAmount -= fuel.burnSpeed;

                if (fuel.fuelAmount <= 0) {
                    
                    fuelList.Remove(other);

                    Destroy(other);
                }

            }


        }

    }

How can I do this?

You could use InvokeRepeating without the for loop or WaitForSeconds in the for loop.

On each occasion you should select just one object and deplete that. Either pick one at random, or find some other way of choosing one, but just one each time. Perhaps you deplete the one with the lowest fuel amount, or oil before timber.

Having picked one, exit the loop with break.

Don’t know if it fits your game logic, but I would deplete all resources at the same time, while dividing the burn speed between them.

And this is how i’d implement it:

  1. Add a dictionary to keep number of resources from each fuel type:
    Dictionary<string, int> fuelAmountByType = new Dictionary<string, int>();
  2. Inside OnTriggerEnter add to this dictionary:
    if(!fuelAmountByType.ContainsKey(fuel.fuelType) fuelAmountByType.Add(fuel.fuelType, 0);
    fuelAmountByType[fuel.fuelType]++;
  3. Inside OnTriggerExit and before destroying the fuel object remember to decrement from that value.
  4. Inside OnTriggerStay, check if there are several elements of this type, and divide the burnSpeed by that number.

General rule, you don’t want to call GetComponent() several times every frame.
So, you can use SendMessage () on fuelList items fuelList*.SendMessage("BurnFuel", amount);assuming you have a method BurnFuel (float amount) { fuelAmount -= amount; } in the Fuel component.*
Or, you can make the list a List of Fuel components List<Fuel> fuelList and use
foreach (Fuel fuel in fuelList)
{
fuel.fuelAmount -= fuel.burnSpeed;
}
You should consider putting the mechanics where it belongs : in the Fuel class.
And to solve your current issue, all objects within the trigger receive the message OnTriggerStay, so if you have ten objects in the trigger, the message is interpreted 10 times, on the 10 objects.
I believe you just don’t need to collect the object in a list and simple use the fuel component of the other game object.
void OnTriggerStay(Collider other)
{
if (other.gameObject.tag != “fuel”) // simple way to exit the method if the object isn’t one you handle
return;

other.gameObject.SendMessage (BurnFuel, amount); // using send message
Fuel fuel = other.GetComponent(); // or using GetComponent (but only once)
if (fuel != null) // make sure there’s one (unless you use tags and are perfectly sure there’s one
{
fuel.fuelAmount -= fuel.burnSpeed;
}
}