Задача: разработать пользовательский интерфейс для кнопки оплаты с помощью ползунка, кнопки и системы событий Unity.

Сегодня мне нужно было разработать кнопку зарядки, которая заряжает полосу только при нажатии и сбрасывается до нуля при отпускании кнопки с помощью интерфейсов Unity EventSystem. Я использовал два интерфейса для разработки этой функции:

IPointerDownHandler: это интерфейс с функцией OnPointerDown. Это вызывается всякий раз, когда указатель мыши находится над определенным объектом, и вы нажимаете кнопку мыши.

IPointerUp: то же самое, но вызывается, когда вы отпускаете кнопку мыши.

В моей сцене у меня есть холст со следующими фоновыми объектами, кнопкой, ползунком и текстом заряда.

К ползунку прикреплен скрипт зарядки, а к кнопке прикреплен скрипт кнопки зарядки.

Поскольку я хочу, чтобы указатель мыши взаимодействовал только с кнопкой, я прикрепил два интерфейса событий к сценарию кнопки зарядки. У меня есть два события в сценарии, вызываемом при нажатии и отпускании мыши.

using System;
using UnityEngine;
using UnityEngine.EventSystems;

public class ChargeButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    public event EventHandler OnClick;
    public event EventHandler OnRelease;
    public void OnPointerDown(PointerEventData eventData) {
        OnClick?.Invoke(this, EventArgs.Empty);;
    }

    public void OnPointerUp(PointerEventData eventData) {
        OnRelease?.Invoke(this, EventArgs.Empty);
    }
}

Для своего скрипта зарядки я собрал ссылки на нужные мне объекты и создал логическое значение, когда бар заряжается.

В методе запуска я подписываю метод на оба события в сценарии кнопки и запускаю сопрограмму. Эта сопрограмма представляет собой функцию зарядки, которая запускается в цикле в фиксированном обновлении. Когда кнопка заряжается, она добавляет к ползунку +2f, а когда они отпускают, значение ползунка равно -5f.

using System;
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class ChargeSystem : MonoBehaviour
{
    [SerializeField] private Slider _slider;
    [SerializeField] private ChargeButton _button;
    [SerializeField] private TMP_Text _chargeText;
    [SerializeField] private Animator _animator;
    private bool _isCharging;
    void Start()
    {
        _button.OnClick += _button_OnClick;
        _button.OnRelease += _button_OnRelease;
        _chargeText.text = "Not Charging...";
        StartCoroutine(ChargeRoutine());
    }

    private void _button_OnRelease(object sender, System.EventArgs e) {
        _isCharging = false;
        _chargeText.text = "Not Charging...";
    }

    private void _button_OnClick(object sender, System.EventArgs e) {
       _isCharging = true;
        _chargeText.text = "Charging...";
    }

    IEnumerator ChargeRoutine() {
      while (true) {
            if (_isCharging) {
                _slider.value += 2f;
            }
            else {
                _slider.value -= 5f;
            }
            yield return new WaitForFixedUpdate();
        }
    }


}

Затем в качестве дополнительного бонуса я добавил анимацию на заливку ползунка и кнопку. Для обоих объектов в собственном аниматоре я создал ключевые кадры для привязки к цвету заливки и кнопки, меняющие темный оттенок цвета на светлый.

Slider создал новую анимацию в папке проектов, назвал ее fill, прикрепил ее к объекту заливки в ползунке и анимировал ее цвет.

Конечный продукт