Разработка кастомного ECS на Unity: Учимся делать RTS c нуля
В этом видео рассмотрен процесс разработки RTS игр с нуля, где вы узнаете, как создать свой собственный кастомный ECS фреймворк. Мы рассмотрим ключевые аспекты проектирования и реализации, включая эффективное использование компонентов, систем и сущностей.
Узнайте, как создать свой собственный ECS фреймворк для разработки RTS игры с нуля! Здесь я подробно рассказываю о создании кастомного ECS фреймворка, который поможет вам воплотить свои идеи в реальность.
Ссылка на телеграм канал: t.me/unitycodecraft
Таймкоды:
00:00 - вступление
01:25 - разработка RTS
03:20 - почему не DOTS
06:18 - альтернативные ECS фреймворки
07:20 - почему свой ECS
09:17 - из чего состоит ECS
09:46 - реализация ECS
11:24 - реализация системы перемещения
34:08 - перемещение к точке
56:30 - выводы
Пікірлер: 85
Ссылка на проект: drive.google.com/file/d/1bDfphw8BRkzggBhULbBu1vz9PoWgOLcE/view Ссылка на презентацию: docs.google.com/presentation/d/1YXYolr18u1UE8QmOr89dUtr_Wm0p8iiEEYwhKlNmoJ8/edit?pli=1#slide=id.g2535733295c_0_6
Очень классный урок. Автору огромная благодарность. Благодаря Вам я наконец разобрался в принципах работы ECS 👍
Спасибо за видео! Делаю свой Ecs. Остановился на реализации components. Не знал как их максимально оптимизированно хранить в памяти, но ты помог.👍👍👍
Очень крутое и полезное видео! Не останавливайся!
Ы большой молодец 🎉 С удовольствием жду следующее видео
Очень классный контент! Спасибо ❤
С ECS никогда не работал. Но всегда хотел посмотреть, что это. Данное видео дало мне полное понимание данной технологии. Самое главное - понять суть, зачем это и как это работает. Большое спасибо! Теперь полностью готов изучить, например, DOTS. Ну или буду использовать также свое решение, как и собственную DI систему) Очень жду части по мультиплееру!
Комментарий в поддержку канала. Доделаю казуалку. Приду посмотрю может на RTS замахнусь) Спасибо за видео!!!
Спасибо вам большое за ролики, это невероятно круто и очень интересно!🙂 Надеюсь продолжите выпускать их дальше🙌 Подобного полезного контента уж слишком мало на ютубчике :(
мужик, я тебя люблю, наконец-то ЕКС для самых маленьких, спасибо, я так долго этого ждал, чуть на курсы уже не пошел, чтобы хоть кто-то показал объяснил
Это самое простое объяснение ECS, которое я видел, и самая простая реализация. Очень рад, что разъяснили эту тему. Больше всего хочется посмотреть, как будет к этому прикручен мультиплеер и насколько будет быстро работать проект на выходе - интересна как оптимизация рендера/кода, так и скорость отклика в сети, т.к. в RTS важна каждая миллисекунда. Буду следить за проектом!
@kirillsviderski4739
11 ай бұрын
Ну, по опыту, сделать лучше чем отлаженные годами фреймворки - тяжело.Сделать оптимизировано и заложить расширяемость - непросто
@sweettea-hv1ls
9 ай бұрын
Есть технология Unity Netcode For Entities как часть технологии DOTS
@ichbinschlange
8 ай бұрын
@@kirillsviderski4739, "отлаженные годами фреймворки" зачастую являются набором легаси и компромиссов из-за необходимости поддерживать обратную совместимость. Достаточно посмотреть любую либу со сроком жизни 10+ лет. + Все эти замечательные поделки почти никогда не обладают адекватным API, ибо "тяп-ляп и в продакшн, допилим как взлетит", а потом "интерфейсы ломать нельзя". Единственный аргумент против кастомных решений - их долго писать, в подавляющем большинстве случаев лучше жрать что дают, ибо -птичку- время жалко.
если будет идея с патреоном - я подпишусь) такой качественной подачи давно не видел на ютубе про юнити
Спасибо за видео)))
Шиииикарно
Красавчик!
Очень познавательное видео. Я пришел в Unity совсем недавно. Вообще я разраб с огромным опытом на Java. Лайкнул, подписался)
Не так давно разрабы "Diplomacy is not an option" выкатили в стиме новость, точнее большую статью, про технологии и пр. что использовали для своей игры. Кто не знаком - поглядите в стиме)) Это игра, сделанная на юнити с использованием как раз таки ECS (если быть точным, то Entities, Job System и Burst Compiler). И там как раз таки тоже стратежка, где на экране могут быть одновременно даже не сотни, а тысячи и тысячи юнитов)) Имхо яркий такой пример о пользе ECS в разработке. А автору видео респект за то, что дает что-то, чтобы лучше понять, как все это работает. Это поможет не только использовать готовые решения эффективнее, но и может и правда сделать что-то похожее для себя.
Супер Мега кайф 👍🏿👍🏿👍🏿
збс!
Привет! Наткнулся на твой канал по этому видео. Что ж, теперь я твой подписчик :) Тема достаточно нечастая, от того и ценная. UPD: для начинающих советую LeoECS, он лёгкий в использовании и очень производительный.
Я так понял что мне ещё рано это смотреть . Но я чуть что в первых рядах подписчиков был)
Дорогой Игорь. Я не то что новичок, я в программировании понимаю только на пальцах, никогда не обучался (кроме школьной программы). Увидев ваш ролик, захотел повторить за Вами, использовал прикрепленные в комментарии файлы, создал проект. Но у меня персонаж не двигается, не реагирует на команды никак. В Аниматоре на повторе прокручивается Idle. Подскажите, пожалуйста, может что за кадром происходило или я столкнулся с какой-то проблемой? Как заставить перемещаться персонажа
Игорь, подскажи где почитать/посмотреть про рефлексию. Я вообще не понимаю что это такое и то что ты показываешь как в системы рефлексия подтаскивает компонент пулы выглядит для меня как магия.
@CodeCraftUnityEdition
11 ай бұрын
www.tutorialspoint.com/csharp/csharp_reflection.htm
Я сам недавно начал DOD интересоваться. Возможно, лучше вместо того, чтобы просто хранить список ентити и проходиться по нему в апдейтах, хранить это в словаре, где ключ - это битсет из присутствующих у ентити компонентов, а значение - массив этих ентити. Так же каждая система должна будет предоставлять метод, которые будет возвращать битсет (сигнатуру) из компонентов, которые требуются этой системе. В таком случае передавая ентити в систему можно знать наверняка, что эта энтити валидная, и избавиться от кучи ифов. Ну и плюсом это улучшит локалити компонентов для сущностей одинакового типа. Ещё когда удаляешь компонент (ставишь exist = false), можно избавиться от этого поля, вместо свапать неактивный компонент с последним активным, и хранить значение активных элементов. То есть держать массив в отсортированном виде, тогда при аллокации нового элемента не придется проходиться по всему массиву. И бонусом от лишнего була в каждом компоненте избавиться.
@CodeCraftUnityEdition
11 ай бұрын
Круто! Интересно было бы глянуть пример сниппета на github)))
по поводу id в ecsworld - можно в момент удаления (отключения) сущности кэшировать минимальный id удалённой сущности что бы не начинать поиск с 0 при создании новой. Типа: cached_id = min(cached_id, removed_id). ну и кешировать при создании новой (ведь по сути значит уже проверил все предыдущие варианты и незачем их снова проверять)
@CodeCraftUnityEdition
8 ай бұрын
О, хорошая идея, воткну, спасибки :)
Спасибо за интересное видео. Очень познавательно! 11:35 Вместо флага можно использовать Tag: MoveRequired и вешать на энтити, когда нужно переместить юнит. Какой подход в данном случае эффективнее применять флаг в компоненте или тэг?
@CodeCraftUnityEdition
Ай бұрын
Лучше тэг, конечно делать отдельным компонентом. Так фильтры сразу тебе выдают необходимые сущности без лишних if проверок
В дотс порядок вызова систем контролируется с помощью атрибутов и системных групп. Там, на самом деле, очень широкие возможности котроля
спасибо большое за видео, осталось только несколько вопросов :) 1. почему Вы решили в ecs world не удалять энтити из массива и сдвигать его, а помечать индекс пустым и заполнять его после? и то и то решение работает за линейное время, но 1й вариант как будто проще читается из-за того, что это устоявшийся алгоритм. 2. почему Вы не встроили фильтр в ecs world, чтобы не дёргать лишние энтити? у вас же внутри каждой системы свой фильтр, из-за этого выходит дублирование кода постоянное
@CodeCraftUnityEdition
10 ай бұрын
1. Потому, что если сдвигать массив, то нужно двигать и массивы компонентов) 2. По поводу фильтра - резонное замечание. пока что так проще. На производительность это особо не влияет. Дальше посмотрим
на сколько такая реализация ECS совместима с Mirror или unity NetCode который новый
@CodeCraftUnityEdition
10 ай бұрын
Сложно сказать, пока не добрался до этого. В целом я буду делать свою реализацию сетевого взаимодействия)
Блин а возможно ли сдедать систему комбинированную с Behavior tree?? Я делаю стратегию в которой юниты на расстояний 300 метров от камеры имеют единое ИИ, как в стртегиях. А вблизи камеры становятся умными и способными биться логический.
@CodeCraftUnityEdition
8 ай бұрын
Странная система. То есть пока игрок не смотрит, его армия проигрывает :) Вообще возможно. Просто делаешь два режима ИИ через GoF паттерн State и все)
Пересмотрел пару раз видео, возник еще один вопрос, разве ваша система не дублирует дефолтный функционал юнити? В том смысле что можно то что у вас в папке Systems унаследовать от MonoBehavior и повесить на GameObject, Unity будет дергать Update без вашей прослойки интерфейсов, а список компонентов повесить прямо на нужный префаб в виде отдельного скрипта. Тогда Entities будут GameObjects на которых висит скрипт со списком компонентов, a все остальное что у вас в папке ECS вообще не нужно будет, или так не получится?
@CodeCraftUnityEdition
10 ай бұрын
На мой взгляд, лучше не завязывать классы на монобехи, когда можно это сделать без них. Самое главное архитектурное отличие заключается в том, что апдейт через интерфейсы проще контролировать, поскольку игра его вызывает только в активном состоянии
@user-bn7qv3kq3e
10 ай бұрын
@@CodeCraftUnityEdition Если не сложно развейте тему, чем плохи монобехи? Я обратил внимание что разработчики из СНГ их не жалуют, в англоязычных гайдах я такого пренебрежения к ним не замечал, интересно ваше мнение как эксперта. И второй вопрос - почему не рассматриваете мобилки, это ведь большой рынок, какой смысл отказа от него? Из-за жанра RTS? Но я буквально недавно видел клон WarCraft 3 на мобилках, весьма популярно. Сколько я понимаю на мобильном рынке RTS довольно мало, вы могли бы занять нишу. Если не секрет насколько трудозатратно в юнити добиться кроссплатформы для Desktop/Mobile, на примере вашего проекта? Разве не достаточно просто добавить мобильный GUI и может рекламную интеграцию?
@CodeCraftUnityEdition
10 ай бұрын
Я рекомендую использовать монобехи только в тех случаях, когда действительно нужно обрабатывать методы Unity, такие как Update, FixedUpdate, OnTriggerEnter/Exit, OnApplicationPause и так далее. В остальных случаях лучше использовать обычные C# классы, так как их проще поддерживать и переиспользовать, поскольку они выполняют единственную ответственность и занимают меньше ресурсов при размещении экземпляра класса в оперативной памяти. Дополнительно к этому такие классы проще тестировать, так как не требуют доп наследования от MonoBehaviour, не привязываются к жизненному циклу игрового объекта
@CodeCraftUnityEdition
10 ай бұрын
Мобилки, мне честно говоря надоели, я ими занимался с 2019 года. Хочется сделать что-то более глобальное и полноценное. Меня привлекает жанр RTS с детства, и всегда было желание сделать игру именно в этом жанре. На мой взгляд RTS на мобилки - это не очень хорошая история, поскольку среднее время игрока в мобильной игре занимает 3-5 минут, а средняя миссия от 30 минут до 1 часа. Вторая проблема - это маленький экран и сложность сделать удобный интерфейс управления RTS (UI/UX). Таким образом, гораздо разумнее сделать RTS на ПК, понять все особенности разработки таких игр, а потом экспериментировать с мобилками
like
Привет! А что на счет наполнения? Модели?! Есть 3D Artist?
@CodeCraftUnityEdition
11 ай бұрын
Есть 3D ассеты)))
@OnzaRain
11 ай бұрын
@@CodeCraftUnityEdition то есть это чисто образовательное видео- без претензии на выход игры?
@CodeCraftUnityEdition
10 ай бұрын
Да, я хочу сделать сначала код-базу для RTS, а потом уже на нем нормальные игры в Steam делать)))
Для меня вопрос выбор ECS в первую очередь это вопрос трудозатрат. А так причины выбора ECS очень мутные. В прошлом ролике ты утверждал, что хочется свой ECS так как не нравится взаимодействия ООП и не хочется изучать DOTS. Сейчас причины "контроль над проектом" и более "академичские" чтоли.) PS Я не понимаю объёма проекта: 3 месяца, 6 или год ? Хотелось бы конечно увидеть его реализацию, а не только теоретические выкладки)
@CodeCraftUnityEdition
11 ай бұрын
Смотри, ECS я решил взять только для реализации игровых объектов: 1. Увеличить производительность 2. Уменьшить связность кода 3. Увеличить переиспользуемость кода за счет универсальных компонентов и систем Почему я сделал именно свой ECS, а не взял DOTS - это "контроль над проектом", потому что да, если я возьму DOTS, а потом споткнусь об него, то будет грустно переписывать весь проект или вставлять костыли. Поэтому решил сделать свой, чтобы быть уверенным, что это я смогу довести этот проект до конца _____ По поводу сроков проекта, точно год+, так как придется делать очень много по плану работ
@nognomar
8 ай бұрын
@@CodeCraftUnityEdition к несчастью, две из трех целей вы провалили. 1 - производительность в вашей реализации врядли будет сильно отличаться от "дефолтной" юнитевой на монобехах. Вы каждый цикл итерируетесь по всем ентитям в игровом мире и прогоняете их по всем системам проверяя, каждый раз, наличие нужных компонент - это сразу минус локальность кэша, которая по сути является одним из главных бустеров производительности ecs-подхода. 2 - сомнительная переиспользуемость систем, когда та же MoveAnimationSystem жестко привязана к конкретной "анимации" где обязательно есть имя State со значениями 0, 1. По итогу получился крайне странный велосипед, который игнорирует большую часть плюсов ecs-подхода.
Интересноое видео(!); Умоляю поменяйте микрофон))
Если что animation instancing не работает на мобайл тоесть вернее не дает нужный результат может разница в 5фпс, как и многопоточные фреймворки в юнити (, (тестировал на телевонах 2017-2022 годов штук 3) решение для оптимизации графики я находил, рендер скейл… +15-20 фпс, стало возможно рендерит 400к полигонов на 2гб озу мобайл усройстве под 60фпс, еще срп рендеринг из юрп помог очень. Это я так пишу для искателей мобайл оптимизации )
@CodeCraftUnityEdition
10 ай бұрын
Спасибо большое за отзыв, не знал, что на мобилках это так работает 👍
Забавная система, меня немного смутил один момент: вы говорите про Starcraft, при этом тестируете систему на 150 юнитах. Сколько я помню в StarCraft: Brood War 1998 года у игрока был лимит 200 юнитов, при этом в мультиплеере могли играть до 12 игроков (2400 юнитов потенциально), протосс мог похитить рабочего зергов и терранов и получить их лимит отдельно (до 7200 юнитов потенциально на карте) + к тому безлимитное количество зданий. При этом официальные системные требования StarCraft: Brood War: ПК: ЦП 90 МГц, ОЗУ 16 МБ, SVGA совместимая видеокарта В связи этим у меня вопрос: как покажет себя ваша система если активных сущностей в игре будет не 150 а хотя бы 10 000, запустится ли это хотя бы на современных мобилках, про 90МГц и 16МБ озу я не спрашиваю :)
@CodeCraftUnityEdition
10 ай бұрын
Да, согласен, что нужен тест на большее число юнитов) Мобилки не рассматриваю, так как проект на ПК
Можно комментарий, почему юзаешь this, а не _? Сам использую this, но такое чувство что народ не любит этот вариант. Хотя по мне так от _ иногда в глазах рябит.
@CodeCraftUnityEdition
11 ай бұрын
this - это просто код-стайл, к которому я привык. Когда я использую this, я явно указываю, что эта переменная является полем класса, а не локальная. А так на самом деле нет разницы между this, _ или просто писать... IDE все равно подсвечивает 😉
Уважаемый Игорь, видео очень качественное и полезное. НО можно, пожалуйста, объяснить тупому джуну почему многие, и вы в том числе, пишете условия через отрицание. Пример: если нет компоненты то ничего не делает, а иначе делаем. Почему нельзя написать что если есть компонента то делаем и иначе никакого не будет. Надеюсь на ваш ответ
@sinedvesug6992
8 ай бұрын
Проще сделать через отрицание иногда
@CodeCraftUnityEdition
8 ай бұрын
На самом деле, тут дело в код-стайле. Я просто стараюсь избегать вложенных конструкций типа if внутри if внутри if. Проще написать так: public void Move() { if (!this.gameObject.TryGetComponent(out MoveComponent component)) return;' //Логика перемещения... //Другому программисту не нужно читать дальше метод, если условие не выполнено. }
@_shad0vv939
8 ай бұрын
понял. спасибо@@CodeCraftUnityEdition
в документации от Microsoft говорится, что небезопасно хранить в структурах поля ссылочного типа, такие как Transform, GameObject и т.п. Очень сомнительный подход, который неизвестно какими ошибками обернётся при дальнейшей разработке
@CodeCraftUnityEdition
10 ай бұрын
Почему небезопасно? Оно все прекрасно работает! В памяти поля ссылочного типа просто хранят ссылку на экземпляр класса точно также как и классы)
@nightyonetwothree
8 ай бұрын
небезопасно, но можно (тут например обращение ко всем структурам через ref идёт, и если нигде не забыть - то всё будет хорошо)
Так а ECS работает только в DOTS, иначе смысл пропадает группировать таким образом данные в памяти, да это будет быстрее т.к. они с большей вероятностью попадут на кеш процессора, но все еще медленнее без DOTS и в частности Jobs. Это не просто так было придумано в купе с DOTS. В ином случае вы просто тотально декомпозировали логику без существенных плюшек. Позволяете получать доступ к компонентам из любой части архитектуры, нарушая уже другие паттерны проектирования де-факто, при этом идете на эти жертвы без существенной выгоды, как мне кажется, один плюс, что можно бездумно в последствии дописывать слои и быстро их подключать, ну такое. По сути вы жертвуете SOLID, т.к. данный паттерн идет уже вне рамок ООП, вне рамок привычных архитектур, тут по сути сухая работа с данными которые тотально декомпозированы в разных участках проекта и к которым прямой доступ отовсюду. Это оправданно для перформанса, но без DOTS, кажется, что лишено смысла. Могу ошибаться, мое мнение.
@konneuktrevor9295
5 ай бұрын
Вся соль ECS не столько в перформансе (это скорее приятный бонус), сколько в гибкости. SOLID здесь как раз соблюдается, причём даже легче соблюдать, потому что всё декомпозировано. У каждой системы своя микрозадача. Мы можем запросто подменять или расширять игровую логику. Радикальный взгляд на принцип composition over inheritance позволяет давать сущности любые свойства и поведения, что создаёт безграничный потенциал для комбинирования. ECS очень гибок и удобен.
очень интересно но ничего не понянто
Попытка оправдать велосипед?
@CodeCraftUnityEdition
11 ай бұрын
Не понял вопрос, честно) Просто мне удобнее разрабатывать игру на своем велике, потому что знаешь, как он работает на low level и всегда всегда можешь подкрутить любую деталь)))
@xanaramus
11 ай бұрын
@@CodeCraftUnityEditionА почему тогда используете движок и с#? Если можно писать на своем языке и движке? Тогда контроль еще больше
@nickicool
11 ай бұрын
@@xanaramus из огня в воду? А может пусть он еще и свой C# напишет и свой движек? Ну хочет писать свой велик - пусть пишет. И народ лучше поймет что такое ECS/
@xanaramus
11 ай бұрын
@@nickicool Большинство программистов работает в команде. А большинство программистов в этих командах знакомы с коммерчески проверенными инструментами. И никакого толку от вашего самописного чуда, только в ваших пет-проектах, и то много вопросов. Вместо того чтобы сосредоточиться на проблемах которые точно нужно решить, вы решаете уже решенные задачи. А научится использовать ecs можно и без велосипедов, поэтому все ваши доводы сомнительны.
@nickicool
11 ай бұрын
@@xanaramus Еще раз - человек хочет на своем личном проекте писать велосипед. Кто ему в праве это воспрещать? Он кому то чем то обязан? Если бы это был командный проект, видимо, выбор был бы иной.
нудно, слишком много воды. непонятно в каком порядке смотреть видео