Архитектура игры C# и Unity! 5 советов по улучшению архитектуры проекта!

Поделиться
HTML-код
  • Опубликовано: 8 ноя 2024

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

  • @confeeg
    @confeeg Год назад +6

    Лайки в студию ))) Требуем продолжения! ))

  • @INFinitely_Unregistered
    @INFinitely_Unregistered Год назад +31

    На ютубе сейчас очень мало действительно информативных русскоязычных роликов по Unity, а потому для меня этот канал на вес золота! Спасибо больше Илья за качественный и полезный контент!

    • @chillcompany1028
      @chillcompany1028 Год назад

      Будем честными, англоязычных ещё меньше .. :(

    • @defix_gamedev
      @defix_gamedev Год назад +3

      @@chillcompany1028 наоборот, я часто замечал, что как раз информативного контента на англ ютубе (да и не только ютубе) куда больше, поэтому когда я не могу найти ответ на какой-либо вопрос, сразу обращаюсь к англ сообществу, там куда больше инфы, нежели от снг

    • @veiterio
      @veiterio Год назад

      есть ещё NTC

    • @INFinitely_Unregistered
      @INFinitely_Unregistered Год назад

      @@veiterio Он тоже прекрасен, не спорю, но к сожалению выпускает ролики редко

    • @ОЛЕГШАТНЕНКО-щ4я
      @ОЛЕГШАТНЕНКО-щ4я Год назад

      Пользуйтесь яндекс переводчиком. Англоязычных каналов много

  • @tortik22
    @tortik22 Год назад +38

    Думал будут какие-то бредовые советы как делают большинство ютуберов, а оказалось вполне годно!

    • @vomgame
      @vomgame Год назад +2

      1 совет абсолютный бред 🙄. То есть если у тебя десятки и сотни объектов которые нужно инициализировать, нужен какой то класс который будет иметь ссылки на них, и вызывать метод Initialize. А если эти объекты создаются новые, а потом уничтожаются, значит их еще надо подписать на события. Совет про паттерны хорош, про scriptable object тоже. Если игра маленькая, то можно использовать MonoBehaviour и не беспокоиться.

    • @tortik22
      @tortik22 Год назад

      ​@@vomgame это нужно для старта больших систем в игре. Игрок он как бы один в игре его можно инициализировать тут

    • @каналзаброшен-ч7ж
      @каналзаброшен-ч7ж Год назад

      @@vomgame , автор объяснил сам принцип. На деле же можно это в разы упростить, к примеру использовав какой-нибудь ECS.🤷‍♂️

  • @kitgunmi9631
    @kitgunmi9631 Год назад +2

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

  • @SMT-ks8yp
    @SMT-ks8yp Год назад +8

    Насчёт скриптабл обжектов, дело в том, что все их поля по умолчанию сериализуются. Если вам надо что-то в них менять во время игры через её код, а потом сбрасывать (например, если обжект используется для передачи данных между сценами), ставьте перед нужными полями [System.NonSerialized].

  • @MRSHERMAN-id4fx
    @MRSHERMAN-id4fx Год назад +1

    Оффигеееть, это как раз то что мне было нужно. Благодарю за то, что создаешь такой контент. Жду продолжения 🔥

  • @Андрей-в7и6ь
    @Андрей-в7и6ь Год назад +1

    Очень интересно и понятно, спасибо! Буду ждать продолжение.

  • @bigbluepie8983
    @bigbluepie8983 Год назад +1

    Продолжай, спасибо!
    Даёшь лайки!!!!

  • @danquimby8317
    @danquimby8317 Год назад

    Про Timer круто, я что то не подумал заглянуть в конструктор )) буду только так использовать.

  • @Murrsik_
    @Murrsik_ Год назад +1

    Идея про инициализацию очень прикольная, заюзал в рабочем проекте и доволен как слон)

  • @USSR-Lenin-Stalin-Forever
    @USSR-Lenin-Stalin-Forever 3 месяца назад +1

    1:57 есть отличное правило что в awake инициализируется объект а в start идет обращение уже к другим объектам, так что данную проблему легко избежать

  • @RuslanSmirnovGameDev
    @RuslanSmirnovGameDev Год назад

    Красавчик, советы что надо! Хоть они и кажутся простыми, но на их основе формируются более сложные принципы, которые применяются и в больших проектах

  • @VADIM-SOLOV
    @VADIM-SOLOV Год назад

    Я занимаюсь разработкой игр на Unity уже два года. И могу полностью подтвердить полезность и практичность этих советов! Удивительно, но на своей практике я сталкивался со всеми проблемами озвученными в этом видео. В конечном итоге, через долгое раздумье и множество попыток рефакторинга я приходил именно к тем решениям про которые и говорит автор.
    Это отличный канал и я с нетерпением буду ждать новых видео! Удачи с развитием канала :)

  • @defix_gamedev
    @defix_gamedev Год назад +1

    В основном база, но несколько советов для себя взял, спасибо за видео))

  • @SawyerDeParter
    @SawyerDeParter Год назад

    Привет, слушай я только начинаю свой путь программиста- разработчика инди игр поэтому я благодарен тебе за данное видео . Это поможет мне со старта избавиться от этих проблем в будущем. Только лайк без обсуждения очень качественно и кратко, сам стремлюсь к этому.

  • @alexeydual8455
    @alexeydual8455 Год назад

    Хороший видос. Дал мне определённую пищу для размышлений)

  • @psi4042
    @psi4042 Год назад

    Очень хорошие советы, спасибо
    Как-раз почувствовал проблему с инициализацией сцены, попробую будстрап

  • @lloydlion8959
    @lloydlion8959 Год назад +5

    По поводу 1-ого совета, есть для Юнити такая зачательная штука как Zenject, которая решает кучу вопросов по поводу зависимостей компонентов. Очень было бы интересно посмотреть про эту либу. Она кстати не заменяет bootstrap, а скорее дополняет.

    • @-it394
      @-it394  Год назад

      Да в другом комменте написал про это) Тоже хочу сделать видосик на эту тему

    • @QuizzyBreezy
      @QuizzyBreezy Год назад

      @@-it394 чисто для уточнения, нельзя ли условную ловушку (1:56) конфигурировать в "private void Start()"? Вроде как к этому моменту все компоненты будут гарантировано инициализированы.

    • @КлимНуралин-у4у
      @КлимНуралин-у4у Год назад

      @@QuizzyBreezy если уверен что это ни к чему не приведет -- можно. А привести может к тому, что кто-то в свою очередь будет ждать инициализации ловушек, тогда потребуется какое то событие приделать, крч ни к чему хорошему это не приведет, потому что если это не контроллировать, эти события придется приделывать везде и ещё и утилизировать подписки, забудешь подписку и будут ещё баги. Плюс, если на порядке инициализации возникнет баг, то нигде не написано что ловушки зависят от чьей то инициализации. Вот на опыте скажу, архитектурные решения это решения которые потом сложно сделать снова, если ты начнешь использовать везде события для порядка инициализации то это изменить можно будет ток рефакторингом, и бывает ситуация что цепочка из событий где то на 10 классов по 100 строк, а ещё они имеют скрытые связи, к примеру один класс ждет когда второй класс что то сделает, второй класс ждет когда первый класс что то сделает и так несколько раз, тут ещё проблемы с srp получается, и с плохой архитектурой проблемы с srp решать тяжело

  • @alexandervakhrushev6566
    @alexandervakhrushev6566 Год назад

    За последние годы это единственное видео под которое я поставил лайк!

  • @mrgoodpeople
    @mrgoodpeople 8 месяцев назад

    Я тоже всегда делал какой-то один скрипт, обычно называл его GLOBAL =). И там были ссылки на все нужные объекты и какие-то глобальные переменные, которые мне нужны. Вполне удобно.

  • @ЛеонидМанатов-ъ7о
    @ЛеонидМанатов-ъ7о Год назад +1

    Советы толковые, делай еще)
    По 3 совету - отказ от монобехов.
    В целом совет хороший, но есть куча вытекающих проблем, о которых нужно думать прежде чем отказаться от монобеха.
    Например очень сложно дебажить это из эдитора. Банально хочешь узнать состояние Level или того же таймера, или чтобы геймдизайнер мог это все посмотреть и подергать, добавить кнопки в инспектор и так далее. [Serializable] тут не всегда помощник, часто придется писать какие-то костыли чтобы вывести это в эдитор или прокидывать поля в верхнеуровневые классы, либо условный bootstrap в инспекторе превратится в длинный монстрокласс который только и занимается тем чтобы в инспектор вывести инструменты для внутренних сущностей.
    Поэтому иногда можно пренебречь этим, да архитектура может немного пострадать, но зато не тратишь время на доп инструменты и проще\быстрее с этим работать и геймдизайнерам и программистам, что на самом деле может быть очень важно для бизнеса (не тратить время на супер крутую архитектуру, которая может и совсем не понадобится на проекте)

  • @muse_x4237
    @muse_x4237 Год назад +1

    На ютубе очень не хватает видео про архитектуру Unity-проектов и, в целом, про более сложные вещи. Иной раз бесит, когда ищешь какую-то инфу, а тебе попадаются только тонны тупых видосов для новичков, а-ля "Как сделать инвентарь".
    Респект! 👍

  • @Artem-u5e9c
    @Artem-u5e9c Год назад

    Весьма полезно. Спасибо!

  • @moondi4368
    @moondi4368 Год назад

    Я работаю в анриле и не знаю как всё устроено в юнити, но было интересно, спасибо рекомендациям ютуба. Если что это не сарказм

  • @Darksanderst
    @Darksanderst Год назад +1

    Мужик💪

  • @niplix
    @niplix Год назад

    Очень круто, спасибо

  • @newbieproable
    @newbieproable Год назад +1

    Топ видосик!

  • @guiltyshoes
    @guiltyshoes Год назад

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

  • @nfurtin
    @nfurtin Год назад +1

    В целом порекомендовал бы еще в качестве зависимостей прокидывать классы не напрямую, а через интерфейсы. Например, при работе в команде бывает так, что ты работаешь над задачей которой требуется некоторые данные из других классов, но разработкой нужного функционала занимается другой человек и не понятно когда он будет готов. Для решения этой задачи ты просто создаешь интерфейс который заставляет реализовать некоторый нужный тебе функционал и далее тестируешь все это через какой нибудь example скрипт ,который реализует этот интерфейс.

  • @SALOway
    @SALOway Год назад

    Как многие уже сказали, создание точки входа - действительно неплохая практика. Но вот пример как по мне не очень яркий.
    Я вот например выстроил для себя четкое разделение: Awake() для подготовки данных для роботы, а Start() для работы с данными
    Применяем данную логику к примеру:
    Maze, очевидно, некий компонент, который будет иметь в себе некоторую структуру данных для ячеек лабиринта
    TrapsGenerator - это класс, который генерирует ловушки в ячейках Maze
    То есть, Maze должен инициализироваться в Awake(), для подготовки ячеек, а TrapsGenerator (который в примере вообще не инициализирует никакие свои данные), в методе Start() будет создавать ловушки, обращаясь к референсу Maze
    Может у меня мало опыта, но я лично не могу представить ситуации, в которой есть необходимость инициализации в определенном порядке из-за жестких зависимостей.
    Но даже так, с точки зрения организации архитектуры - это вполне себе

    • @just4funTony
      @just4funTony Год назад

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

    • @SALOway
      @SALOway Год назад

      @@just4funTony В его примере я такого не увидел. Предположить можно что угодно, но я то говорил о конкретном, приведенным им, примере. И как уже и сказал - совет хороший
      P.S. Хотя я могу представить как это можно реализовать без точки входа, но это уже будет вопрос архитектуры и вкусовщины :D

    • @redfox7193
      @redfox7193 9 месяцев назад

      Не так уж и часто важен порядок выполнения. А на этот случай есть события C#. Подписал методы в классах на событие которое вызывается в нужный момент и проблема решена.

  • @АлексейБулаев-р9ъ
    @АлексейБулаев-р9ъ 7 дней назад

    Было бы здорово.

  • @МВолков-с6ж
    @МВолков-с6ж Год назад +2

    Ничего не понял но было очень интересно.

    • @МВолков-с6ж
      @МВолков-с6ж Год назад

      В школе учили Паскалю, вот и люблю его. Синтаксис наикрутейший. Сейчас кроме Делфи ничего другого не признаю.

  • @NoobittoBoy
    @NoobittoBoy Год назад +4

    Ты спецально столько опечаток наделал, чтобы вынудить таких как я на коммент?! Хитрюга))

  • @Eduard0213-x7p
    @Eduard0213-x7p Год назад

    Scriptable objects можно исползывать как дата но через класс player prefs, так можно json сохранить в стринг как класс и так далее

  • @greenbox674
    @greenbox674 Год назад +1

    Про первый пункт - это вообще проблема юньки. Вообще одним из способов решения является DI (dependency injection) и для юньки есть готовое решение: zenject. Я пока сам не юзал его, но слышал хорошие отзывы от других разработчиков

  • @koganboss4874
    @koganboss4874 Год назад

    Привет! Хороший канал у тебя, не бросай это дело, как сейчас модно у всех нормальных ютуберов по Юньке 🤣 Если будет время и желание, очень хотелось бы увидеть подробный разбор ECS с примерами, а то что-то никак не могу вкурить эту систему, а хочется. Удачи.

  • @Soskar
    @Soskar Год назад +1

    На самом деле рассказал довольно качественные советы! Новичкам в геймдеве/кодинге это видео станет полезным 👍

  • @swoolfeek3709
    @swoolfeek3709 Год назад +1

    Ну 4й совет не до конца корректный. Если сбилдить проект тогда изменения в SO не будут записываться, это работает только из едитора, этот вопрос CodeMonkey поднимал в одном из своих видео. А так видео клевое.

  • @ram-1919
    @ram-1919 Год назад +2

    Блин, реально годные советы! Сам разрабатываю и учусь больше 2-х лет, но ты реально крут в своём деле)
    Кстати насчёт сохранения, я думаю зачастую будет довольно уместно делать через Scriptable Object
    Лайк и подписка!

    • @alexzakh
      @alexzakh Год назад

      Насчет сохранения через Scriptable Object ничего не получится. Показанное изменение и сохранение значений полей работает только при симуляции в редакторе. После закрытия редактора или игры (приложения) Scriptable Object восстановит изначальные значения полей (в редакторе это те, что были при последнем сохранении,)

    • @ram-1919
      @ram-1919 Год назад

      @@alexzakhРечь идёт о способе, когда Scriptable Object просто совершает действия сохранения (например запись json) без использования промежуточных значений.
      Я сам так делал, всё прекрасно работало.

  • @mrgoodpeople
    @mrgoodpeople 8 месяцев назад +1

    А меня по началу сбивало с толку, что если компонент отключен, а я в коде напишу строку его включения и тут же строку выполнения какого-то его метода, то сначала выполнится этот метод, а уже потом обработчик Start(). То есть порядок действий поменяется! Это кажется нелогичным, но методы жизненного цикла выполняются в определённой последовательности, поэтому Start() выполнится только после завершения текущего кадра и методов Update() и FixedUdpate(). А вот метод из компонента выполнится сразу, даже если компонент в редакторе отключен.

  • @forcesoftheevil9252
    @forcesoftheevil9252 Год назад

    Годный видос! Автор правильно и понятно рассказал советы.
    Но есть вопрос - Можно ли использовать scriptable object как Model в MVP и файл для сохранения (инвентаря, состояния уровня и т.д.)

  • @DarkIllusoire
    @DarkIllusoire Год назад +3

    Очень полезные советы, особенно для новичков - к сожалению, новички обычно не способны оценить такие советы))

    • @СергейКильянов-в5к
      @СергейКильянов-в5к Год назад

      Вот правда! Понимаю что мне надо это понять, но со второго совета перед глазами как будто белый шум., хоть и пересмотрел уже раз 5. Начинал делать игру ещё до того как узнал о самом понятии архитектуры, наговнокодил около 50 перевязанных между собой как попало скриптов и забросил потому что перестал понимать что сам же понаписал. А архитектуру не знаю даже с чего начать изучать...

    • @DarkIllusoire
      @DarkIllusoire Год назад +1

      @@СергейКильянов-в5к могу посоветовать пописать небольшие игры и делать упор на достаточно простые советы: код стайл, нейминг, научиться избавляться от повторений кода хотя бы в рамках одного класса, научиться разделять и строить алгоритмы внутри метода так, чтобы они были максимально информативны и просты в понимании

    • @DarkIllusoire
      @DarkIllusoire Год назад +1

      @@СергейКильянов-в5к Вот например простой пример класса, которые подсвечивает предмет на который смотрит игрок:
      [CreateAssetMenu(menuName = "Create SingleSelector", fileName = "SingleSelector", order = 0)]
      public class SingleSelector : SelectorBehaviour {
      [SerializeField] private float _maxDistance = 5f;
      public override ISelectable Select(Camera camera, Transform origin) {
      var affected = Physics.OverlapSphere(origin.position, _maxDistance * 2);
      var ray = camera.ScreenPointToRay(GetScreenCenter());
      Physics.Raycast(ray, out var hit, _maxDistance);
      var selectionTarget = hit.transform != null? hit.transform.GetComponent(): null;

      affected.Each(a => {
      if (a.TryGetComponent(out var item)) {
      item.ChangeSelectedState(selectionTarget == item);
      }
      });
      return selectionTarget;
      }
      }

    • @DarkIllusoire
      @DarkIllusoire Год назад

      А это код который его использует:
      [RequireComponent(typeof(Camera))]
      public class Selector : MonoBehaviour {
      [SerializeField, ReadOnly] private Camera _camera;
      [Space]
      [SerializeField] private SelectorBehaviour _behaviour;

      private readonly HashSet _listeners = new();
      private void OnValidate() => _camera = GetComponent();
      public IDisposable Subscribe(ISelectionNoticeable listener) => _listeners.Subscribe(listener);
      private void Update() {
      _listeners.Each(l => l.ChangeSelectedItem(_behaviour.Select(_camera, transform)));
      }
      }

  • @DELOG244
    @DELOG244 Год назад

    Ну 500 лайков есть, ждём новые видео)

    • @-it394
      @-it394  Год назад

      Сегодня/завтра выйдет))) Параллельно работаю над курсом для групповых занятий по паттернам, поэтому немного не успеваю моментально реагировать))

    • @DELOG244
      @DELOG244 Год назад

      @@-it394 о, здорово, а что за курс такой?

    • @-it394
      @-it394  Год назад

      @@DELOG244 t.me/yakovlev_gamedev подробности тут)

  • @sweeepeeee
    @sweeepeeee Год назад

    Что касаемо первого совета он верный, но можно сделать ещё лучше. Завести какой то интерфейс или абстрактный класс с методов Initialize и в буте просто создать очередь из таких объектов. А потом инициализировать в порядке очереди. Так прямо в инспекторе можно будет настраивать очередь

    • @-it394
      @-it394  Год назад

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

    • @sweeepeeee
      @sweeepeeee Год назад

      @@-it394 ну тут уже надо думать, для параметров тоже можно заводить интерфейсы и оборачивать все в объект, потом уже разбирать этот объект. Не знаю правда работает ли это в шарпах, но в ТС пользуюсь подобным

    • @Xummuk97-n1t
      @Xummuk97-n1t Год назад

      @@-it394 по идее набор параметров для конкретного объекта должен определяться как раз в конфигах, в методе Initialize можно из контекста получить нужный ScriptableObject и например по ID чего-либо взять данные. Например при инициализации игрока мы можем получить настройки Character, в зависимости от них получать настройки Weapon, Skins и тд, можно при этом взаимодействовать с моделью, в которой хранятся данные из сохранки. Вариантов много, но вот чтобы прям все объекты так перечислять не очень удобно, в больших играх так точно не делается, тем более все настройки не хранятся в одном месте, проводится декомпозиция. По сути по этому и нужен MVC, мы получаем данные из моделей, на их основе генерируем MonoBehaviour и связываем их с контроллером, а если делать по другому, архитектура достаточно быстро сыпиться.

    • @-it394
      @-it394  Год назад +1

      @@Xummuk97-n1t Да на самом деле если уж так говорить, то нужны фабрики и DI для внедрения нужных зависимостей. В таком случае без проблем можно реализовать эти варианты. Но все таки тут довольно простые советы разбираются, которые сильно помогут при малой затрате сил. Да и для маленьких проектов вполне достаточно такого варианта

  • @DmitryTrump
    @DmitryTrump Год назад

    Привет! Спасибо что делишься знаниями! Когда ~ будет курс от тебя ? Планируешь ли залетать на Udemy ?

    • @-it394
      @-it394  Год назад

      Курс будет проходить в виде групповых занятий (подробности в телеге). Поэтому видеокурса пока не будет, но я рассмотрю варианты как это можно реализовать

  • @kaishifuin
    @kaishifuin Год назад

    Вообще для буста активности канала сними видос про твоё участие в геймджеме. Люди любят такое и многие нынешние ютуберы по юнити именно после этих видео начали активно расти.

    • @-it394
      @-it394  Год назад

      Вообще можно будет как вариант))

  • @AlexandrFedotov009
    @AlexandrFedotov009 Год назад +1

    bootstrap - god object, это не плохо, но если говорить про архитектуру, то это плохо

  • @maxvell-gamedeveloper
    @maxvell-gamedeveloper Год назад +1

    Как вариант, можем вообще вместе создавать игры. И снимать видео на юткб и многое другое. Как думаешь?

    • @-it394
      @-it394  Год назад

      Прости но времени сейчас очень не хватает( Возможно позже что- нибудь придумаем

    • @maxvell-gamedeveloper
      @maxvell-gamedeveloper Год назад

      @@-it394 а как насчет взаимопиарп

  • @НикитаСоколов-х9н
    @НикитаСоколов-х9н Год назад +2

    Насчет первого совета. Разве неправильно проводить первичную инициализацию в Awake() а после работать через Start() с зависимостями? Сама идея звучит привлекательно, но не могу себе представить чтобы в проекте на 200+ скриптов инициализация вызывалась из одного класса с манульаной расстановкой порядка.. Проще же когда ты интуивно знаешь что инициализировать в любом классе в Awake() а что на Start() 🤯

    • @Arendrast
      @Arendrast 11 месяцев назад

      Уж лучше так, чем когда 200+ скриптов управляют собой и потом ты сам запутаешься кто за что отвечает, почему тот объект вызывается позже этого и откуда возникает проблема

  • @jarag9353
    @jarag9353 Год назад

    Ну сразу по первому совету есть базовая рекомендация от юнити, что инициализации в эвейке, а обращения в старте

    • @-it394
      @-it394  Год назад

      Ну при большом количестве обьектов это не спасёт все равно, будет также ситуация. Лучше всего awake использовать только для каких нибудь getcomponent

  • @requiem_for_a_dream5463
    @requiem_for_a_dream5463 Год назад +2

    8:08 А зачем тебе на баре MonoBehaviour, если можно создать экземпляр класса и прокинуть в конструктор картинку(саму полоску) и таймер?

    • @-it394
      @-it394  Год назад +1

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

    • @requiem_for_a_dream5463
      @requiem_for_a_dream5463 Год назад

      @@-it394 Спасибо. Понял. Ну вот у меня тож всегда делема с этим. Стоит ли убирать монобех, если можно обойтись без него, но он с монобехом логичнее получается.

  • @dasic1334
    @dasic1334 Год назад +1

    Всё хорошо, но последний совет - дизинфа. Это работает ТОЛЬКО в эдиторе. Если ты сделаешь это в билде, а затем выключишь игру и запустишь, то SO восстановит свои значения, а не сохранит. Не понимаю, зачем это работает только в эдиторе, но это факт. Будучи зелёным, я пытался сделать сохранения на SO, но оказалось, что это не работает в билде

    • @just4funTony
      @just4funTony Год назад

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

    • @alexzakh
      @alexzakh Год назад

      @@just4funTony Scriptable Object вполне можно использовать, просто не в качестве сохранения данных.

  • @worldofgames2383
    @worldofgames2383 Год назад

    Так же я который может сделать управление персонажем, и при том с кучей ошибок

  • @Indus008
    @Indus008 Год назад

    можно подробное видео по Entry Point

  • @lomion46
    @lomion46 Год назад

    На счёт последнего - не проще ли использовать инстансы SO'шек вместо дополнительных обёрток, если нужно в них что-либо менять в рантайме. Естественно, не забывая убивать после того, как они уже не нужны. По факту это те же ассеты, что и материалы, префабы, etc.

    • @-it394
      @-it394  Год назад

      Вроде нельзя сделать инстанс SO это несовсем тоже самое что и префаб. У материала также есть более гибкие возможности, например работать с ним через property Block. У SO таких вариантов нет, если я правильно понял о чем вы)

    • @DarkIllusoire
      @DarkIllusoire Год назад

      @@-it394 почему, можно: Instantiate(_linkToReferencedSO);

    • @lomion46
      @lomion46 Год назад

      @@-it394 Видимо, неправильно.

  • @CronaxDervish
    @CronaxDervish 11 месяцев назад

    Скриптейблы "сохраняются" только в редакторе. В финальном билде все изменения скриптейбла откатятся назад после перезапуска приложения.

  • @xVitOSx
    @xVitOSx Год назад

    У меня вопрос. В моём прототипе игры есть скрипт, который хранит в себе ссылки на все объекты на сцене, сортирует эти ссылки по группам (враги, здания, остальное) и отправляет их нужным объектам. Нужен ли тут MonoBehaviour? Возможно ли сделать так, чтобы этот скрипт хранил и обрабатывал данные, не находясь на объекте?

    • @-it394
      @-it394  Год назад

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

  • @makxi3795
    @makxi3795 Год назад +1

    Вместо первого совета лучше использовать зенжект и не терять модульность юнити

  • @nycnacubo
    @nycnacubo Год назад

    Может кто-нибудь подсказать, как сделать такие же скрываемые параметры в инспекторе в зависимости от значений других переменных внутри ScriptableObject, как показано на 8:52?

    • @bonbad612
      @bonbad612 11 месяцев назад +1

      Это делается через CustomEditor(SO и монобехи) или PropertyDrawer(для обычных классов или если нужно самому настроить вид инспектора) скрипты. Тебе хватит CustomEditor

    • @nycnacubo
      @nycnacubo 11 месяцев назад

      @@bonbad612 благодарю

  • @B.BiStudios
    @B.BiStudios Год назад

    А зачем таймер создавать с нуля если его можно взять из System.Thearing, Start прописал и пускай считает, надо будет Stop вызвал и готово, время можно получить из timespan

  • @RimuruDev
    @RimuruDev Год назад +2

    База

  • @dev_anim3
    @dev_anim3 Год назад

    4 совет - не прокидывайте в функциональные классы UI.
    Это очень банально и я сомневаюсь что кто-то кому нужны какие либо советы в Архитектуре приложения может так делать.

  • @dev_anim3
    @dev_anim3 Год назад

    3 совет ещё более странный чем 1, если так рассуждать то можно вообще сделать оба этих класса статическими, ведь все необходимое можно просто прокинуть им в поля.

  • @belxsi
    @belxsi Год назад

    1 совет. Ха, да. Это одна из проблем которая у меня возникла. Но я её исправил просто создав булевые переменые которые говорят о готовности классов и поместил всё в Update

  • @dev_anim3
    @dev_anim3 Год назад

    1 совет выглядит как шутка, ладно идея сама по себе ненужная так как есть Start который включается после Awake так ещё ии реализация очень плохая.
    Правильная реализация выглядит как MonoBehaviour с интерфейсом IInit, в bootstrap делаем массив MonoBehaviour где в OnValidate проверяем есть ли на всех элементах массива интерфейс, в Awake проходимся по массиву и вызываем метод. Если нужна более производительная версия вместо интерфейса можно сделать абстрактный класс

  • @dmitriypermyakov5402
    @dmitriypermyakov5402 Год назад

    Интерсно, но ни слова не понял.

  • @GGamess
    @GGamess Год назад +3

    рубрика Вредные советы, удивительно что кто-то называет это базой) Скрипт экзекьюшен ордер как раз и сделан для таких случаев, когда в старте надо сделать несколько вещей и учесть их порядок например для банального DI

    • @lomion46
      @lomion46 Год назад +1

      Чел, Скрипт экзекьюшен ордер необходимо стараться использовать по минимуму, а не пихать туда всё. Не давай вредные советы тоже.

    • @GGamess
      @GGamess Год назад

      @@lomion46 я привел конкретный пример когда он нужен, что не так, чел?

    • @-it394
      @-it394  Год назад

      @@GGamess не так то, что если совать туда все подряд, то там окажется весь проект) Эта штука предназначена для более высокоуровневых вещей, например, какой нибудь сервисы внедрения зависимостей (вроде zenject даже при установке плагина сам закидывается туда)

    • @DarkIllusoire
      @DarkIllusoire Год назад

      Чел ты такую дичь несешь, Di в Awake =D

    • @GGamess
      @GGamess Год назад

      @@DarkIllusoire что не так чел?

  • @KadykovDenis
    @KadykovDenis Год назад

    Автор сам плодит костыли, а избыточный код извиняясь называет "классиком".

  • @il35215
    @il35215 Год назад

    Уже лет 10 делаю игры применяя данные советы. Жаль что большинство разрабов даже в больших западных студиях до сих пор пишут ужасный говнокод и ничего подобного не знают и не применяют. А часто еще и спорят что все это фигня и им проще без этого )

  • @tuttikfruttik6210
    @tuttikfruttik6210 Год назад +1

    8:13 не Example, а Eample =)

    • @nebante
      @nebante Год назад

      И так и так правильно, одинаковые по значению слова.

  • @hardlandingtac
    @hardlandingtac 22 дня назад

    Сомнительные советы.

  • @Filimon_enc
    @Filimon_enc Год назад

    Слишком бегло