Application.wantsToQuit and Application.quitting causing crash

Hey so I setup the wantsToQuit and quitting listeners, what I want to create is a “Are you sure you wish to close” popup before closing the application below is my implementation but 9 times out of 10 my game would crash or the popup will appear and then it’d crash.

So far its only popped up and functioned proprly before.

It’d be much appreciated if somebody could give me some advice for approuching this issue.

public class WindowController : MonoBehaviour
{
public static WindowController instance;
public UnityEvent ExecuteBeforeClose;
bool quitConfirmation = false;
public GameObject windowPopup;

[RuntimeInitializeOnLoadMethod]
static void RunOnStart()
    {
        Application.wantsToQuit += WantsToQuit;
        Application.quitting += Quit;
    }

static bool WantsToQuit()
    {
        if (instance.quitConfirmation)
        {
            return true;
        }
        else
        {
            RequestQuitConfirmation();
        }
        return false;
    }

    static void RequestQuitConfirmation()
    {
        DisplayOptionPane("Are you sure you wish to quit?", response =>
        {
            if (response)
            {
                instance.ExecuteBeforeClose?.Invoke();
            }
        });
    }

    static void Quit()
    {
            instance.quitConfirmation = true;
            Application.Quit();
    }

    static void DisplayOptionPane(string msg, Action<bool> response)
    {
        WindowPopup popup = instance.windowPopup.GetComponent<WindowPopup>();
        instance.windowPopup.SetActive(true);
        popup.header.text = "Notice";
        popup.message.text = msg;
        popup.accept.gameObject.SetActive(true);
        popup.reject.gameObject.SetActive(true);

        popup.accept.onClick.RemoveAllListeners();
        popup.accept.onClick.AddListener(() =>
        {
            response.Invoke(true);
            instance.windowPopup.SetActive(false);
        });

        popup.reject.onClick.RemoveAllListeners();
        popup.reject.onClick.AddListener(() =>
        {
            response.Invoke(false);
            instance.windowPopup.SetActive(false);
        });
}
    }

I would not use this method. For one, it behaves differently on different OSes, as documented in its API page.

I just make an extra “Verify quit game?” scene, accept input in there, and either just quit the app, or else return to the main menu.

1 Like

Just like Kurt said, the way I go about it is the “Exit/Quit” UI button pops another UI that asked “Are you sure?” and that one calls Application.quit

1 Like

What if I wanted this popup to appear if the user pressed Alt+F4, or clicked the red close button? Regardless of what OS they are on?

Aren’t alt F4 and the top close button OS dependent?
I only do windows so I’m now sure how it works on various linux distros or mac

I think you’re starting to go into sketchy territory with the OS when doing stuff like that

2 Likes

I think you are calling Quit a lot of times and causing a Stack Overflow.

Read your output.log file in the AppData folder for your game, or put a break point in the editor, debug it out.

I use wantsToQuit and it works flawlessly with Alt + F4 and X button events.

It makes no sense for this event to be OS dependent, it is kind of obvious that Unity fires up this event on the appropriate way for each OS, depending on your build settings.

The documentation has only one situation where it behaves differently that expected:
IMPORTANT: The return has no effect on iPhone. Application can not prevent termination under iPhone OS.

But then again, Apple is Apple, what to expect :-\

2 Likes

This is how I currently do it:
I hook into Application.wantsToQuit and link it to my CallQuitWindow-Function, which will open my confirmation window and return false, to abort the quitting.
If the confirmation button is pressed, I unsubscribe my Function from the event, and than call Application.Quit() normally.
I hope this guides you into the right direction.

using UnityEngine;

public class ConfirmQuitting : MonoBehaviour
{
    [SerializeField] private GameObject confirmationWindow;
    private static ConfirmQuitting instance;


    [RuntimeInitializeOnLoadMethod]
    static void RunOnStart()
    {
        Application.wantsToQuit += CallQuitWindow;
    }


    private void Awake()
    {
        instance = this;
    }


    public static bool CallQuitWindow()
    {
        // Call Confirmation-Window and abort the quitting
        instance.confirmationWindow.SetActive(true);
        return false;
    }


    // Attached to Conformation-Button
    public void Confirm()
    {
        // When pressing Confirmation-Button, unsubscribe from Event and the Quit Application
        Application.wantsToQuit -= CallQuitWindow;
        Application.Quit();
    }
}