Reloading scene asynchronously causes stutter as the scene seems to restart a few times in a row.

I have a project with a single scene. When my player dies I reload the scene.
I’ve tried reloading the scene asynchronously, as in:

Application.LoadLevelAsync(Application.loadedLevel);

But both in the editor and iOS what ends up happening is the scene seems to star over 3 times in a row. That is, the scene shows up on screen and a UI animation stars (which is the first thing that happens in my scene), but immediately the scene restarts 2 more times, until the 3rd time, where the scene does stay loaded and the rest of the game proceeds as usual.

The only thing I gathered so far is that when running on iOS, when this stutter / multi reload happens, I get the following in the Xcode console:

(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)

Built-in UI layer disabled. Causes: [Requires OpenGL]

If instead I load the scene synchronously, it takes longer to load but I get the scene restarting only once, as I’d expect.
Also, on a side note, debug mode seems enabled even though I’m making a release build :confused:

Any thoughts?

Just in case, here is what I assume is the relevant code.
This is the code that kills the player and restarts the level, attached to a ‘trap’ object that the player can collide with:

IEnumerator killPlayer(GameObject player) {
    player.transform.parent.gameObject.GetComponent<PL.Model.Vehicle>().Destroy();
    player.transform.parent.gameObject.GetComponentInChildren<AnnouncementsUI>().announce("GAME OVER");
    yield return new WaitForSeconds(1.5f);
  
    AsyncOperation reload = Application.LoadLevelAsync(Application.loadedLevel);
    reload.allowSceneActivation = false;
    
    // Scene fades to grayscale:
    ColorCorrectionCurves[] curves = player.transform.parent.gameObject.GetComponentsInChildren<ColorCorrectionCurves>();
    int curvesDone = 0;
    while (curvesDone != curves.Length) {          
      foreach (ColorCorrectionCurves curve in curves) {
        curve.saturation = Mathf.Lerp(curve.saturation, 0f, Time.deltaTime);
        if (curve.saturation <= 0.01f) {
          curvesDone++;
        }
      }
      
      yield return null;
    }
    
//    Application.LoadLevel(Application.loadedLevel);
    reload.allowSceneActivation = true;
  }

And this is the code that triggers the first animation when the level starts:

public class AnnouncementsUI : MonoBehaviour {
  public Text announcement;
  public Driver driver;
  private Animator animator;
  private int announceState;
  public bool startGame;
  
  void Start() {
    driver.autoThrust = false;
    animator = announcement.GetComponent<Animator>();
    announceState = Animator.StringToHash("CountDown");
  }
  
  void Update() {
    if (startGame) {
      startGame = false;
      StartCoroutine(CountDownToGame(3));
    }
  }
  
  public IEnumerator CountDownToGame(int count) {
    for (int i = count; i > 0; i--) {
      announce(i.ToString());
      yield return new WaitForSeconds(1f);
    }
    
    announce("Go!");
    driver.autoThrust = true;
  }
  
  public void announce(string text) {
    announcement.text = text;
    animator.Play(announceState, -1, 0f);
  }
}

Pretend this never happened…

Basically the problem was that I was starting killPlayer (the coroutine) from OnTriggerEnter and the method was firing 3 times (most probably because of the DontGoThruThings approach, aka, raycasting to get collisions at higher speeds). Since StartCoroutine can be called multiple times, each time dispatching a new copy of the routine, I was literally dispatching 3 routines, each loading the level again.