Как сделать синглтон unity

Добавил пользователь Владимир З.
Обновлено: 04.10.2024

Комментарии • 43

Спасибо, очень познавательные уроки!

урок оказался действительно полезным. жду следующий. удачи )

Очень понравилось. Подписался. Жду следующий урок. Было бы интересно послушать еще про паттерны, про Ioc контейнеры(зачем, как, для чего), про стек ассетов(как для 2d и 3d), которые будут полезны unity-программисту.
Спасибо!

Урок очень полезный оказался. Правда я как сравнительно начинающий программист где то после 70% видео я уже немного "поплыл", т.к не совсем понимал о чём речь. Если автор будет добавлять к разным темам затрагиваемым в ролике разные ссылки на другие ролики которые объясняют конкретику того что он делает, было бы вообще шикарно. Но и так всё равно лайк.

Благодарю, я понял как правильно использовать синглтон, круто объяснил)

Долго пользовался подобной конструкцией по совету автора и возможно потому что я начинающий девелопер и чего-то не понимаю, но при таком сценарии во многих проектах ловил неплохой такой фриз каждый раз когда обращался к синглтону впервые изза функции FindObjectOfType(), что делает подобную конструкцию не особо юзабельной. Да, в теории все круто, мы создаем синглтон, который куда более соответсвует смыслу самого паттерна, но какой в этом смысл если мы имеем в итоге фризы в самом проекте? За видео конечно лайк в любом случае ибо много чего подчерпнул нового для себя, пусть это новое и добавило проблем в свое время)

Да, я об этом тоже подумал. Надо потом будет сделать поправочку : )

Пожалуйста продолжи писать видео, очень полезно и позновательно.

Давайте обниму, очень полезно разъяснили. 🤗 Спасибочки

Делайте уроки по ООП пожалуйста

Убирай камеру (вебку), когда показываешь консоль в юнити, а то из за нее мало чего видно, а так, в целом видео понравилось, подписался, продолжай :)

красавчик, а что на гцуп не заливаешь видосы в топик. Наконец-то полезный материал
спосибо большое пиксайй

Благодарю, супер, удачи!

Божички, неужели моя проблемы с нул референс синглтонов решена! Спс!

Если делаешь действительно Singleton в юне, то добавляешь в Awake "if(FindObjectsOfType().Length > 1)< Destroy(gameObject); return; >" - затем, чтобы любые копии этого одиночки при инициализации самоуничтожались, оставляя единственным на сцене объект-первенец. Т.е. если ты даже очень захочешь запихнуть на сцену несколько экземпляров, любые новые тут же уничтожаются. И тут вплывает это "гениальное решение" переключать при дестрое булевую переменную, которую затем проверяет любое обращение к нашему !не уничтоженному объекту! - он все еще на сцене, но которое возвращает тебе null, т.к. булево значение переключено. Это может быть если ты загружал сцену скажем для тестов когда-то и ты запихнул на неё префаб с менеджером, на сцене до этого был создан менеджер, ты переходишь на сцену с его копией и при его удалении обращение к первичному объекту возвращает null. Так ли эта проверка m_ShuttingDown нужна? Были ли на практике прецеденты или это всё очередная перестраховка? Да по сути и вариант с проверкой на копии одиночки это тоже излишняя перестраховка, но она покрайней мере соответствует основному смыслу паттерна. PS. фиг с ним, добавил в OnDestroy проверку "if (FindObjectsOfType().Length == 0)"

@Wi1dLife
можно так выйти из положения
foreach (var item in FindObjectsOfType())

if(item != FindObjectsOfType()[0]) Destroy(item.gameObject);

>
мы перебираем все объекты с целевым компонентом и удаляем все кроме того что с индексом "0". это кстати будет последний добавленный в сцену объект, юнька почему то обрабатывает объекты в обратном порядке их добавления в сцену. если требуется сохранять первый что был добавлен то нужно в индексе указывать соответственно последний элемент.

"if(FindObjectsOfType().Length > 1)< Destroy(gameObject); return; >" удалит все объекты

Facebook

Twitter

Reddit

Урок по Unity, посвященный практическим примерам использования паттерна проектирования под названием Синглтон (Singleton) в разработке игр.

Մեկնաբանություններ: 25

Годный контент, меньше воды, больше дела. Конечно не хватает наглядности работы скриптов для полного понимания. Я как новичок, так вообще тук-тук, и сложно воспринимать: Что? Зачем? Почему? Надеюсь со временем придет). Но все равно респект 👍 и буду следить 🔔🙂

Наглядность работы скриптов я делаю через логи) не помню, есть в этом видео или нет, но в основном через логи. Этого достаточно, чтобы понять, что все работает и минимум времени, чтобы показать ту самую наглядность)

А если создать синглтон с ссылками на экземляры других классов, этакий хаб, чем это грозит?

@Лавка Разработчика ну не все, а самые часто вызываемые, уроки конечно посмотрю. Давно толковых каналов не попадалось

Это вопрос архитектуры. Один синглтон не может содержать абсолютно все ссылки, это неудобно и неправильно. Смотри уроки по архитектуре, там я буду об этом говорить

А можете поподробнее рассказать, почему плохо этот паттерн пихать в player, bank и всё остальное? Вот много где ругаются на него, но почему, никто не объясняет. Пысы. Спасибо за уроки)

@Лавка Разработчика спасибо за ответы! 🙏

Всегда нужно думать, как обойтись без него, это лучший вариант. Однако, его можно использовать в модулях, например: аналитика, класс самой игры Game (это из урока по архитектуре, который выйдет завтра), управление рекламой в мобильном приложении, управление внутреигровыми покупками - то, что запускается и инициализируется единожды и существует на протяжении всей игровой сессии.

@Лавка Разработчика а по каким критериям определить подходящие и неподходящие для паттерна случаи?

Как минимум два аргумента: 1. Это может стать бесконтрольным. Ваш проект может превратиться в месиво синглтонов, потому что "это же удобно, и у меня никогда не будет больше одного экземпляра этого класса". Бесконтрольное использование синглтона может вылиться в проблему номер 2. 2. Внезапно нужно все-таки создать еще один экземпляр чего-то, что было синглтоном. Например игрок. Вдруг поступило предложение делать локальный мультиплеер. И всё, весь проект накрывается медным тазом, потому что переделывать с синглтона игрока будет долго, мучительно и больно.

Хорошо, если Singleton нельзя использовать тогда все через ссылки делать?? Расскажите как надо тогда?)))

Комментарии • 43

Спасибо, очень познавательные уроки!

урок оказался действительно полезным. жду следующий. удачи )

Очень понравилось. Подписался. Жду следующий урок. Было бы интересно послушать еще про паттерны, про Ioc контейнеры(зачем, как, для чего), про стек ассетов(как для 2d и 3d), которые будут полезны unity-программисту.
Спасибо!

Урок очень полезный оказался. Правда я как сравнительно начинающий программист где то после 70% видео я уже немного "поплыл", т.к не совсем понимал о чём речь. Если автор будет добавлять к разным темам затрагиваемым в ролике разные ссылки на другие ролики которые объясняют конкретику того что он делает, было бы вообще шикарно. Но и так всё равно лайк.

Благодарю, я понял как правильно использовать синглтон, круто объяснил)

Долго пользовался подобной конструкцией по совету автора и возможно потому что я начинающий девелопер и чего-то не понимаю, но при таком сценарии во многих проектах ловил неплохой такой фриз каждый раз когда обращался к синглтону впервые изза функции FindObjectOfType(), что делает подобную конструкцию не особо юзабельной. Да, в теории все круто, мы создаем синглтон, который куда более соответсвует смыслу самого паттерна, но какой в этом смысл если мы имеем в итоге фризы в самом проекте? За видео конечно лайк в любом случае ибо много чего подчерпнул нового для себя, пусть это новое и добавило проблем в свое время)

Да, я об этом тоже подумал. Надо потом будет сделать поправочку : )

Пожалуйста продолжи писать видео, очень полезно и позновательно.

Давайте обниму, очень полезно разъяснили. 🤗 Спасибочки

Делайте уроки по ООП пожалуйста

Убирай камеру (вебку), когда показываешь консоль в юнити, а то из за нее мало чего видно, а так, в целом видео понравилось, подписался, продолжай :)

красавчик, а что на гцуп не заливаешь видосы в топик. Наконец-то полезный материал
спосибо большое пиксайй

Благодарю, супер, удачи!

Божички, неужели моя проблемы с нул референс синглтонов решена! Спс!

Если делаешь действительно Singleton в юне, то добавляешь в Awake "if(FindObjectsOfType().Length > 1)< Destroy(gameObject); return; >" - затем, чтобы любые копии этого одиночки при инициализации самоуничтожались, оставляя единственным на сцене объект-первенец. Т.е. если ты даже очень захочешь запихнуть на сцену несколько экземпляров, любые новые тут же уничтожаются. И тут вплывает это "гениальное решение" переключать при дестрое булевую переменную, которую затем проверяет любое обращение к нашему !не уничтоженному объекту! - он все еще на сцене, но которое возвращает тебе null, т.к. булево значение переключено. Это может быть если ты загружал сцену скажем для тестов когда-то и ты запихнул на неё префаб с менеджером, на сцене до этого был создан менеджер, ты переходишь на сцену с его копией и при его удалении обращение к первичному объекту возвращает null. Так ли эта проверка m_ShuttingDown нужна? Были ли на практике прецеденты или это всё очередная перестраховка? Да по сути и вариант с проверкой на копии одиночки это тоже излишняя перестраховка, но она покрайней мере соответствует основному смыслу паттерна. PS. фиг с ним, добавил в OnDestroy проверку "if (FindObjectsOfType().Length == 0)"

@Wi1dLife
можно так выйти из положения
foreach (var item in FindObjectsOfType())

if(item != FindObjectsOfType()[0]) Destroy(item.gameObject);

>
мы перебираем все объекты с целевым компонентом и удаляем все кроме того что с индексом "0". это кстати будет последний добавленный в сцену объект, юнька почему то обрабатывает объекты в обратном порядке их добавления в сцену. если требуется сохранять первый что был добавлен то нужно в индексе указывать соответственно последний элемент.

"if(FindObjectsOfType().Length > 1)< Destroy(gameObject); return; >" удалит все объекты

У меня есть простой вопрос, который может помочь новым ребятам из Unity быстрее учиться. Как вы знаете, в единстве мы используем синглтон и экземпляр класса. Я понял это, и я хочу быть уверенным в том, о чем думаю. Вы можете помочь мне убедиться?

Я использую instance в некоторых подобных ситуациях;

Если у меня есть сцена, и я хочу использовать экземпляр в качестве слоя для передачи некоторых данных между скриптами. Я создаю пустой игровой объект и назначаю ему этот код как компонент;

Я использую синглтон в некоторых подобных ситуациях;

Если у меня есть сцена, и я хочу использовать одноэлементный шаблон в качестве слоя для передачи некоторых данных между всеми сценами. Я создаю пустой игровой объект и назначаю ему этот код как компонент;

Итак, я хотел быть уверенным, на правильном ли я пути или нет? Это работало до сих пор, но будет ли проблема в большинстве сложных ситуаций в будущем?

Может вам поможет пост это. Я думаю, вам следует выбрать шаблон проектирования singleton для более надежного и точного решения вашей игры :)

На самом деле разница между instance и singleton заключается в следующем: Singleton - это название шаблона проектирования. Instance - это объект типа класса. Так что да, ваша переменная instance в этом случае реализует функциональность singleton . Однако вы можете просто использовать if(!instance) < instance = this; >и пропустить второе условие и просто использовать else < Destroy(gameObject); >. Если вам не нужен этот экземпляр public , сделайте его private . используя удобный побочный эффект наличия этого экземпляра public static будет, вызовет проблемы в будущем из-за невидимых зависимостей;)

Просто быстрый ответ. Экземпляр дает классу фактическое или используемое значение, то есть: Class - это GameCharacter, тогда экземпляром может быть Mario, Luigi, Bowser. Синглтон гарантирует, что у класса будет только один экземпляр на протяжении всего времени его существования, поэтому, учитывая предыдущий пример, если вы создаете экземпляр GameCharacter (Mario), вы не можете создать Luigi, Bowser. Их все еще можно делать, но это противоречило бы цели синглтона.

Единственная разница в двух ваших образцах кода (без учета опечатки > ) - это вызов DontDestroyOnLoad . Использование или неиспользование не меняет того, что у вас есть синглтон, просто ваш экземпляр (и, следовательно, данные d, которые он хранит) живет через границы загрузки сцены.

Draco18s no longer trusts SE

Ответы 1

Ваш код правильный, это основной способ создать синглтон в Unity.

Когда вы говорите об экземпляре или синглтоне, у меня возникает ощущение, что вы не понимаете концепцию: идея синглтона заключается в том, что будет только ОДИН (единственный) экземпляр объекта.

Итак, у вас есть статическое свойство; модификатор static для класса делает его неинформируемым с помощью ключевого слова new . Когда вы добавляете его к свойству (как вы это сделали), это означает, что вы можете получить к нему доступ из любого места, без создания экземпляра содержащего класса.

В MakeInstance () вы проверяете, что экземпляр еще не назначен экземпляру, а затем устанавливаете его для этого экземпляра.

Для дальнейшего следования шаблону Singleton вы, вероятно, захотите убедиться, что ваш объект не разрушен при загрузке новой сцены:

В будущем проблем быть не должно; Шаблон Singleton, однако, плохой, но он полезен при создании прототипов; это просто.

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

Лично я использую класс Singleton для расширения, чтобы гарантировать одинаковую функциональность для всех Singletons и меньшее раздувание в каждом классе Singleton и т. д.:

Что затем используется как:

Использование MySingleton.Instance на самом деле является скорее побочным эффектом шаблона Singleton, и его следует по возможности избегать. Настоящая цель - убедиться, что в сцене есть только один экземпляр класса.

Наличие нескольких одинаковых классов, раздувающих сцену, обычно не имеет значения, поскольку вы собираетесь ссылаться только на один из них (если классы не имеют пассивного поведения). MySingleton.Instance - это способ достижения доступа без создания экземпляра в Unity, поскольку мы вынуждены наследовать от MonoBehaviour, что, как вы сказали, не является определением синглтона, но что-то, что нам нужно сделать, чтобы иметь целенаправленное наполнение синглтона. поведение без добавления инъекции зависимостей, когда вы регистрируете классы как одиночные в контейнере IoC, что, я думаю, было бы предпочтительным способом.

Нет, это не всегда возможно;) Я просто говорю, что основная цель - иметь только один экземпляр . Есть много случаев, когда несколько менеджеров, например могут мешать друг другу и либо замедлять, либо ебать их ^^ С точки зрения нахождения этого экземпляра большинство людей придерживаются синглтонов . и я тоже время от времени (если не использую zenject - хотя .. с моей точки зрения, zenject также является своего рода большим синглтоном, обрабатывающим все ссылки, так что . ). Но, насколько это возможно, вы должны стараться иметь чистые ссылки между компонентами.

Читайте также: