Lambdas, Singleton and Coroutine behaves different on Unity play and Android

Hi, I found myself struggling a lot to understand what is really happening with the following:

Let’s say I have a spawner and some player abilities.
All the abilities are working fine, when I use them, a lambda callback is called with the active effect like this:

private Action<PlayerHandler> HealPlayerAction()
    {
        return (p) => p.HealPlayer((int)value);
    }

Everything fine here.

But the following is happening:
When I call an ability to force enemies to the ground, just changing a boolean, it all works nicely on Unity pressing play, but when I compile and upload it to Google Play to test it, the behaviour is totally different:

    class AbilitiesHandler
    {
     ...
     private Action<PlayerHandler> NoFlyingEnemiesAction()
        {

            //I don't use the p parameter but it should remain there because of the Action expected
            return (p) => EnemySpawnerManager.Instance.ForceAllEnemiesOnGround(true);

        }
     ...
     }



    class EnemySpawnerManager (is a singleton)
     {
     ...
     public void ForceAllEnemiesOnGround(bool enabled)
        {
            _forceGround = enabled;
        }
     ...
     
     public void Spawn()
        {
     ...
             if (!_forceGround)
            {
                enemy.Flying = newEnemy.Flying;
            } else
            {
                enemy.Flying = false;
            }
     ...
     }


}

So, I placed a lot of Logs, and everything is being called right, the ability when pressed… the method on EnemySpawner… BUT, the change on _forceGround is never saw in the Spawn() method, that everytime that checks _forceGround is false.

I can’t debug the code with breakpoints on android because of authentication, and I would really like to understand what might be happening there… are the lambdas working differently on Android? Is the combination between a Singleton and the lambda? First time I face a problem like that, is something so simple as a bool change.

Thanks for the help!

Okay, I tried a lot of different options here, what seems to be very important and I didn’t include before is that the Spawn() method of EnemySpawner, is called from a Coroutine placed inside other script “EnemyWaves”.


If I try to change anything inside EnemySpawner from the ability or player scripts, those changes are not seen inside the said coroutine using Spawn. I have tried:

  • Changing private bool from method.
  • Changing public bool from the other script with the Instance reference.
  • Changing a public static bool.

All those 3 options were always false, so no change being seen.


The twist is, if I make changes from the EnemyWaves, owner of the coroutine calling the Spawn() inside EnemySpawner, just before calling the method Spawn(), the bools are changed, so trying to put a boolean to true produced the next results:

  • Static bool from coroutine owner looked inside the Spawn script: true
  • public bool inside the Spawn script, changed from coroutine owner before calling: true
  • Static bool inside Spawner script changed from anywhere but coroutine owner: false
  • Anything accesing the Spawn script from anywhere but coroutine owner: false

My conclusion here is that on Android, coroutines or singleton (or the addition of both) work differently than running on Unity, and the values of the Spawner script were encapsulated in memory inside the coroutine, making every other change produced outside from coroutine invisible.


Maybe I’m wrong on this assumption, but is the only logical deduction I can make right now.
I would be happy to hear anyone’s oppinion!

Thanks for reading!