принцип подписки и отписки на большинство событий в Unity одинаковый. Этот принцип основан на механизме событий и делегатов в C#, и он работает следующим образом:
### Принцип подписки на события:
1. **Подписка на событие**:
Используется оператор `+=`, который добавляет метод-обработчик (делегат) к событию. Например:
```csharp
Selection.selectionChanged += OnSelectionChanged;
EditorApplication.update += MyUpdateMethod;
```
В этих примерах `OnSelectionChanged` и `MyUpdateMethod` — это методы, которые будут вызваны, когда произойдёт событие.
2. **Отписка от события**:
Для отписки от события используется оператор `-=`, который удаляет метод-обработчик из списка делегатов события:
```csharp
Selection.selectionChanged -= OnSelectionChanged;
EditorApplication.update -= MyUpdateMethod;
```
3. **Автоматическая отписка**:
Если вы подписаны на событие и объект, содержащий метод-обработчик, уничтожается, то этот объект автоматически отписывается от события. Однако, для лучшего контроля за ресурсами рекомендуется явно отписываться от событий, когда они больше не нужны (например, в методах `OnDisable` или при закрытии окна редактора).
### Поведение подписок:
- **Множественные подписки**: Если вы подписываетесь на одно и то же событие несколько раз, метод-обработчик будет вызываться столько раз, сколько подписок было сделано. Поэтому рекомендуется следить за тем, чтобы не было лишних подписок.
- **Синхронное выполнение**: Все обработчики, подписанные на событие, вызываются синхронно, по порядку их подписки. Это значит, что каждое событие выполняется последовательно, и если один из обработчиков задерживается или вызывает ошибку, это может повлиять на другие подписчики.
- **Отмена события**: В стандартной системе событий C# нельзя "отменить" событие, то есть предотвратить его дальнейшую обработку другими подписчиками. Все подписанные методы будут вызваны по очереди.
### Исключения и особенности:
- **Редакторские события** (`EditorApplication`, `Selection`, `Undo`) работают только в редакторе Unity и доступны через пространство имён `UnityEditor`. Они недоступны в игровом процессе (runtime).
- **События в runtime** (например, `SceneManager.sceneLoaded`) доступны и в редакторе, и в игровом процессе.
### Пример подписки и отписки:
```csharp
using UnityEditor;
using UnityEngine;
public class MyEditorTool : MonoBehaviour
{
// Подписываемся на события
void OnEnable()
{
Selection.selectionChanged += OnSelectionChanged;
EditorApplication.update += MyUpdateMethod;
}
// Отписываемся от событий
void OnDisable()
{
Selection.selectionChanged -= OnSelectionChanged;
EditorApplication.update -= MyUpdateMethod;
}
void OnSelectionChanged()
{
Debug.Log("Selection changed");
}
void MyUpdateMethod()
{
Debug.Log("Editor update");
}
}
```
В этом примере:
- **Подписка** происходит в методе `OnEnable()`, когда объект активируется.
- **Отписка** происходит в методе `OnDisable()`, когда объект деактивируется, чтобы предотвратить утечки памяти и неиспользуемые вызовы.
Этот шаблон подписки и отписки используется для всех событий, будь то события редактора или runtime-события, такие как загрузка сцены или обновление кадров.