Unity 6.3
0 онлайн 13 гостей 3 в системе
Вход

Inspector-настраиваемые пользовательские события

Unity предоставляет события UnityEvent API в качестве альтернативы стандартным событиям Unity C# и делегирует. Основное преимущество событий Unity по сравнению со стандартными событиями C# заключается в том, что события Unity можно сериализировать, то есть вы можете настроить их в окне Inspector.

UnityEvent может быть добавлен к любому MonoBehaviour и выполняется во время выполнения как стандартный делегат C#. Когда UnityEvent объявляется в MonoBehaviour, он появляется в окне Inspector, где можно определить обратные вызова, которые сохраняются между временем редактирования и временем выполнения.

События Unity имеют ограничения, аналогичные стандартным делегатам C#:

  • Они содержат ссылки на целевой объект, что препятствует сбору мусора с целевого объекта.
  • Если у вас есть управляемый (C#) UnityEngine.Object в качестве цели и неуправляемый (C++) соответствующий объект был уничтожен, обратный вызов не будет вызван. Дополнительную информацию см. в Объект.

Настройка событий Unity

Предварительные условия

  • Создайте скрипт MonoBehaviour, который включает using UnityEngine.Events
  • Объявить хотя бы одно поле типа UnityEvent

Настройка обратных вызовов в окне Inspector:

  1. Выберите GameObject с компонентом скрипта, который содержит объявленную вами UnityEvent field(s).

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

  3. Выберите UnityEngine.Object, который вы хотите получить обратный вызов. Вы можете использовать селектор объектов или перетащить объект в поле.

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

  5. Повторите действия 1-4 по мере необходимости, чтобы добавить дополнительные обратные вызова для того же события.

Настройка обратных вызовов для событий Trigger Entered и Trigger Exited в окне Inspector
Настройка обратных вызовов для событий Trigger Entered и Trigger Exited в окне Inspector

Статические и динамические вызовы

При настройке UnityEvent в окне Inspector поддерживаются два типа вызовов функций:

  • Статические вызова полностью предварительно настроены во время создания, с их целевыми и параметрическими значениями, определенными в окне Inspector. При вызове обратного вызова, целевая функция вызвана со значениями параметров, определенными в Inspector. Это подходит для значений, которые не будут меняться во время выполнения, например, когда вы хотите уменьшить значение состояния на заданное количество каждый раз, когда происходит определенная коллизия. Статически связанные функции появляются под Статические параметры в списке выбора функций.
  • Динамические вызовы вызываются программно из вашего кода, с параметрами, соответствующими вызванному типу UnityEvent. Это подходит для значений, которые изменяются во время выполнения, например, float, представляющего изменяющееся количество повреждений, которые персонаж получает при каждой атаке. UI фильтрует обратные вызова и показывает только динамические функции с подписями, которые действительны для типа UnityEvent. Например, если у вас есть UnityEvent<string>, селектор функций перечисляет все функции, которые принимают параметр string под заголовком Динамическая строка.
Choosing between static or dynamic functions whose signatures match the event type in the Inspector window
Выбор между статическими и динамическими функциями, сигнатура которых соответствует типу события, в окне Inspector

Общая поддержка в UnityEvent

По умолчанию UnityEvent в Monobehaviour динамически связывается с функцией void. Но вы можете создать UnityEvent с четырьмя параметрами общего типа, как показано в следующем примере:

using UnityEngine;
using UnityEngine.Events;

public class GenericTest : MonoBehaviour
{
    public UnityEvent<int, int, bool, string> myEvent;
    
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        if (myEvent == null)
        {
            myEvent = new UnityEvent<int, int, bool, string>();
        }
        myEvent.AddListener(Ping);
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.anyKeyDown && myEvent != null)
        {
            myEvent.Invoke(5, 6, true, "Hello");
        }
    }

    void Ping(int i, int j, bool print, string text)
    {
        if (print)
        {
            Debug.Log("Ping: " + text + i + j);
        }
    }
}

Дополнительные ресурсы

  • Настройка дверей, триггеров и т.д. с помощью событий перетаскивания
  • UnityEvent API ссылка