Async Helpers

Using async will simplify the code and helps get rid of callbacks, especially useful in case of multiple nested callbacks.
For this reason, helper scripts have been added to make it easier to implement async support for the own scripts or widgets.
The target script should implement an IAwaitable<TResult> or IAwaitable interface.

Script example:

namespace UIWidgets.Examples
{
   using System;
   using UnityEngine;
   using UnityEngine.EventSystems;
   using UnityEngine.UI;

   public class ConfirmExample : MonoBehaviour, IAwaitable<bool>
   {
      [SerializeField]
      protected Text Message;

      [SerializeField]
      protected Button ButtonOk;

      [SerializeField]
      protected Button ButtonCancel;

      event Action<bool> EvOnComplete;

      public event Action<bool> OnComplete
      {
         add => EvOnComplete += value;
         remove => EvOnComplete -= value;
      }

      public Awaiter<bool> GetAwaiter() => new Awaiter<bool>(this);

      protected virtual void Start() => AddListeners();

      protected virtual void OnDestroy()
      {
         RemoveListeners();
         Cancel();
      }

      void AddListeners()
      {
         ButtonOk.onClick.AddListener(Confirm);
         ButtonCancel.onClick.AddListener(Cancel);
      }

      void RemoveListeners()
      {
         ButtonOk.onClick.RemoveListener(Confirm);
         ButtonCancel.onClick.RemoveListener(Cancel);
      }

      public void Confirm() => Complete(true);

      public void Cancel() => Complete(false);

      void Complete(bool result)
      {
         gameObject.SetActive(false);
         EvOnComplete?.Invoke(result);
      }

      public ConfirmExample Open(string message)
      {
         Message.text = message;
         gameObject.SetActive(true);
         EventSystem.current.SetSelectedGameObject(ButtonOk.gameObject);

         return this;
      }
   }
}

Using:

namespace UIWidgets.Examples
{
   using UnityEngine;

   public class TestConfirm : MonoBehaviour
   {
      [SerializeField]
      public ConfirmExample Confirm;

      public async void Test()
      {
         if (await Confirm.Open("Quit?"))
         {
            Application.Quit();
         }
      }
   }
}