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

Поділитися
Вставка
  • Опубліковано 5 лип 2024
  • 📝Всем шарп! Сегодня я расскажу вам о 5 простых советах, которые улучшат архитектуру твоей игры и помогут избавится от множества багов к которым ведет плохая организация проекта. Разберем простые советы, которые в разы прокачают тебя как разработчика!Если тут на берется 500 лайков, то я выпущу вторую часть с 5-ю советами по разработке игр на Unity и C#! Также залетайте в телеграмм канал, чтобы участвовать в голосовании на проведение занятий по паттернам!
    ⚡️⚡️⚡️ Полезные ссылки ⚡️⚡️⚡️
    🔎 t.me/yakovlev_gamedev - ссылка на мой telegram канал (тут проходит голосование)
    🔎 • Динамическая оптимизац... - урок по оптимизации в Unity
    🔎 / @alexgameryt6256 - ссылка на канал моего младшего брата (подпишись если не сложно)
    🕒Тайм-коды:
    ➜ 00:00 - Вступление
    ➜ 00:14 - 1 совет
    ➜ 03:00 - 2 совет
    ➜ 03:39 - 3 совет
    ➜ 06:12 - 4 совет
    ➜ 08:32 - 5 совет
    ➜ 10:53 - Заключение:)
    🔥🔥🔥 На этом канале вы найдете множество уроков по Unity и C#, а так же различных видео на тему разработки игр, так что не стесняйтесь, заглядывайте на канал и вы обязательно найдете что-то по душе!🔥🔥🔥
    #Unity#ЯковлевИлья#архитектура#architecture

КОМЕНТАРІ • 126

  • @tortik22
    @tortik22 Рік тому +35

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

    • @vomgame
      @vomgame Рік тому +2

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

    • @tortik22
      @tortik22 Рік тому

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

    • @user-qp1pr5ww9z
      @user-qp1pr5ww9z Рік тому

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

  • @MRSHERMAN-id4fx
    @MRSHERMAN-id4fx Рік тому +1

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

  • @user-kf4ye7zy4z
    @user-kf4ye7zy4z Рік тому +1

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

  • @SMT-ks8yp
    @SMT-ks8yp Рік тому +8

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

  • @INFinitely_Unregistered
    @INFinitely_Unregistered Рік тому +29

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

    • @chillcompany1028
      @chillcompany1028 Рік тому

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

    • @defix_gamedev
      @defix_gamedev Рік тому +3

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

    • @veiterio
      @veiterio Рік тому

      есть ещё NTC

    • @INFinitely_Unregistered
      @INFinitely_Unregistered Рік тому

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

    • @user-hk8xz8mg7b
      @user-hk8xz8mg7b 9 місяців тому

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

  • @VADIM-SOLOV
    @VADIM-SOLOV Рік тому

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

  • @RuslanSmirnovGameDev
    @RuslanSmirnovGameDev 11 місяців тому

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

  • @confeeg
    @confeeg Рік тому +6

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

  • @kitgunmi9631
    @kitgunmi9631 Рік тому +2

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

  • @bigbluepie8983
    @bigbluepie8983 Рік тому +1

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

  • @user-wq9oy7hx6z
    @user-wq9oy7hx6z Рік тому

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

  • @psi4042
    @psi4042 Рік тому

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

  • @SawyerDeParter
    @SawyerDeParter Рік тому

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

  • @alexeydual8455
    @alexeydual8455 Рік тому

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

  • @Murrsik_
    @Murrsik_ Рік тому +1

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

  • @danquimby8317
    @danquimby8317 Рік тому

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

  • @niplix
    @niplix Рік тому

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

  • @defix_gamedev
    @defix_gamedev Рік тому +1

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

  • @koganboss4874
    @koganboss4874 Рік тому

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

  • @alexandervakhrushev6566
    @alexandervakhrushev6566 Рік тому

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

  • @newbieproable
    @newbieproable Рік тому +1

    Топ видосик!

  • @Darksanderst
    @Darksanderst Рік тому +1

    Мужик💪

  • @mrgoodpeople
    @mrgoodpeople 4 місяці тому

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

  • @muse_x4237
    @muse_x4237 Рік тому +1

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

  • @user-fy4zk5zu3e
    @user-fy4zk5zu3e Рік тому +1

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

  • @NoobittoBoy
    @NoobittoBoy Рік тому +4

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

  • @mrgoodpeople
    @mrgoodpeople 4 місяці тому +1

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

  • @moondi4368
    @moondi4368 Рік тому

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

  • @forcesoftheevil9252
    @forcesoftheevil9252 Рік тому

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

  • @Eduard02834
    @Eduard02834 Рік тому

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

  • @lloydlion8959
    @lloydlion8959 Рік тому +4

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

    • @-it394
      @-it394  Рік тому

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

    • @QuizzyBreezy
      @QuizzyBreezy Рік тому

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

    • @user-oh5jk6kf4x
      @user-oh5jk6kf4x Рік тому

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

  • @DmitryTrump
    @DmitryTrump Рік тому

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

    • @-it394
      @-it394  Рік тому

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

  • @Soskar
    @Soskar Рік тому +1

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

  • @Indus008
    @Indus008 11 місяців тому

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

  • @nfurtin
    @nfurtin 9 місяців тому

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

  • @guiltyshoes
    @guiltyshoes Рік тому

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

  • @DarkIllusoire
    @DarkIllusoire Рік тому +3

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

    • @user-iv1xf8dy4x
      @user-iv1xf8dy4x Рік тому

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

    • @DarkIllusoire
      @DarkIllusoire Рік тому +1

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

    • @DarkIllusoire
      @DarkIllusoire Рік тому +1

      @@user-iv1xf8dy4x Вот например простой пример класса, которые подсвечивает предмет на который смотрит игрок:
      [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)));
      }
      }

  • @greenbox674
    @greenbox674 Рік тому +1

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

  • @xVitOSx
    @xVitOSx 10 місяців тому

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

    • @-it394
      @-it394  10 місяців тому

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

  • @ram-1919
    @ram-1919 Рік тому +2

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

    • @alexzakh
      @alexzakh Рік тому

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

    • @ram-1919
      @ram-1919 Рік тому

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

  • @user-ex8ed6pu9h
    @user-ex8ed6pu9h Рік тому +2

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

    • @user-ex8ed6pu9h
      @user-ex8ed6pu9h Рік тому

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

  • @CronaxDervish
    @CronaxDervish 7 місяців тому

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

  • @swoolfeek3709
    @swoolfeek3709 Рік тому +1

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

  • @user-xj7gz9fz7x
    @user-xj7gz9fz7x 9 місяців тому +2

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

    • @Arendrast
      @Arendrast 6 місяців тому

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

  • @DELOG244
    @DELOG244 Рік тому

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

    • @-it394
      @-it394  Рік тому

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

    • @DELOG244
      @DELOG244 Рік тому

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

    • @-it394
      @-it394  Рік тому

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

  • @kaishifuin
    @kaishifuin Рік тому

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

    • @-it394
      @-it394  Рік тому

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

  • @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 Спасибо. Понял. Ну вот у меня тож всегда делема с этим. Стоит ли убирать монобех, если можно обойтись без него, но он с монобехом логичнее получается.

  • @SALOway
    @SALOway Рік тому

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

    • @just4funTony
      @just4funTony Рік тому

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

    • @SALOway
      @SALOway Рік тому

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

    • @redfox7193
      @redfox7193 5 місяців тому

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

  • @AlexandrFedotov009
    @AlexandrFedotov009 8 місяців тому +1

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

  • @sweeepeeee
    @sweeepeeee Рік тому

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

    • @-it394
      @-it394  Рік тому

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

    • @sweeepeeee
      @sweeepeeee Рік тому

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

    • @user-go9wr2nm7h
      @user-go9wr2nm7h Рік тому

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

    • @-it394
      @-it394  Рік тому +1

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

  • @worldofgames2383
    @worldofgames2383 Рік тому

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

  • @maxvell-gamedeveloper
    @maxvell-gamedeveloper Рік тому +1

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

    • @-it394
      @-it394  Рік тому

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

    • @maxvell-gamedeveloper
      @maxvell-gamedeveloper Рік тому

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

  • @nycnacubo
    @nycnacubo 8 місяців тому

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

    • @bonbad612
      @bonbad612 7 місяців тому +1

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

    • @nycnacubo
      @nycnacubo 7 місяців тому

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

  • @RimuruDev
    @RimuruDev Рік тому +2

    База

  • @KJPiGames
    @KJPiGames Рік тому

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

  • @lomion46
    @lomion46 Рік тому

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

    • @-it394
      @-it394  Рік тому

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

    • @DarkIllusoire
      @DarkIllusoire Рік тому

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

    • @lomion46
      @lomion46 Рік тому

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

  • @jarag9353
    @jarag9353 Рік тому

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

    • @-it394
      @-it394  Рік тому

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

  • @makxi3795
    @makxi3795 Рік тому +1

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

  • @dasic1334
    @dasic1334 Рік тому +1

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

    • @just4funTony
      @just4funTony Рік тому

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

    • @alexzakh
      @alexzakh Рік тому

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

  • @dev_anim3
    @dev_anim3 Рік тому

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

  • @dev_anim3
    @dev_anim3 Рік тому

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

  • @dmitriypermyakov5402
    @dmitriypermyakov5402 Рік тому

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

  • @tuttikfruttik6210
    @tuttikfruttik6210 Рік тому +1

    8:13 не Example, а Eample =)

    • @nebante
      @nebante Рік тому

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

  • @KadykovDenis
    @KadykovDenis 8 місяців тому

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

  • @belxsi
    @belxsi Рік тому

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

  • @GGamess
    @GGamess Рік тому +3

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

    • @lomion46
      @lomion46 Рік тому +1

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

    • @GGamess
      @GGamess Рік тому

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

    • @-it394
      @-it394  Рік тому

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

    • @DarkIllusoire
      @DarkIllusoire Рік тому

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

    • @GGamess
      @GGamess Рік тому

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

  • @dev_anim3
    @dev_anim3 Рік тому

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

  • @il35215
    @il35215 Рік тому

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

  • @Filimon_enc
    @Filimon_enc 8 місяців тому

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