Что это: Поля в коде: _id, _dontDestroyOnLoad (сериализуемые). Публичное свойство Id только для чтения.
Как использовать: см. разделы ниже.
SingletonById<T> — базовый класс для объектов, которых в игре может быть несколько разных типов, но по одному экземпляру на каждый уникальный Id. В отличие от обычного Singleton<T> (один экземпляр на весь проект), здесь один экземпляр на Id: например, один менеджер с Id "Music", другой с Id "SFX" и т.д.
Подходит для:
- нескольких «синглтонов» одного и того же типа с разными ролями (по Id);
- объектов, которые должны переезжать между сценами (опция DontDestroyOnLoad) и при этом не дублироваться по Id.
Правило при совпадении Id: если уже существует экземпляр с таким Id, при появлении нового уничтожается предыдущий (остаётся новый). Так при загрузке сцены с тем же Id новый объект заменяет старый.
- Пространство имён:
Neo.Tools - Файл:
Assets/Neoxider/Scripts/Tools/Managers/SingletonById.cs
- Один экземпляр типа
Tна каждый уникальный строковый Id. - При появлении второго объекта с тем же Id старый уничтожается (побеждает новый).
- Опция DontDestroyOnLoad — объект не уничтожается при смене сцен.
- Доступ по Id через статический метод
Get(id). - Регистрация в
Awake, снятие с регистрации вOnDestroy.
| Поле | Тип | Описание |
|---|---|---|
Id |
string | Уникальный идентификатор (например "Music", "SFX"). Не оставлять пустым. |
DontDestroyOnLoad |
bool | Если включено, объект не уничтожается при загрузке новых сцен. |
Поля в коде: _id, _dontDestroyOnLoad (сериализуемые). Публичное свойство Id только для чтения.
| API | Описание |
|---|---|
Get(string id) |
Возвращает экземпляр T с данным Id или null. |
Has(string id) |
Возвращает true, если есть живой экземпляр с данным Id. |
Переопределяйте при необходимости:
Awake()— вызывается после регистрации (и опционально DontDestroyOnLoad). Вызовитеbase.Awake()если переопределяете.OnDestroy()— вызывается при уничтожении; снятие с регистрации делается в базовом классе. Вызовитеbase.OnDestroy()если переопределяете.
using Neo.Tools;
using UnityEngine;
public class AudioChannel : SingletonById<AudioChannel>
{
[SerializeField] private AudioSource _source;
public void Play(AudioClip clip)
{
if (_source != null)
_source.PlayOneShot(clip);
}
}- Создайте GameObject, добавьте компонент
AudioChannel. - В Inspector задайте Id (например
"Music"или"SFX"). - При необходимости включите DontDestroyOnLoad.
// Получить канал по Id
var music = AudioChannel.Get("Music");
var sfx = AudioChannel.Get("SFX");
if (music != null)
music.Play(someClip);
if (AudioChannel.Has("Music"))
Debug.Log("Music channel exists.");- В сцене два объекта с компонентом
AudioChannelи Id"Music". При запуске первый регистрируется, второй при своёмAwakeуничтожит первый и зарегистрируется сам — останется один с Id"Music". - Объект с DontDestroyOnLoad и Id
"Music"уже есть; загружается сцена, в которой тоже есть объект с Id"Music". После загрузки у «старого» вызовется уничтожение (его уничтожит новый при своёмAwake), останется экземпляр из новой сцены.
| Singleton<T> | SingletonById<T> | |
|---|---|---|
| Экземпляров типа T | Всегда один на проект | Один на каждый Id |
| Доступ | MyManager.I |
MyManager.Get("id") |
| Дубликат | Второй уничтожается (остаётся первый) | При том же Id старый уничтожается (остаётся новый) |
| Использование | Один глобальный менеджер | Несколько «синглтонов» по ролям (Id) |
- Singleton<T> — один экземпляр на весь проект: Singleton.md.