У Unity всё плохо / Хабр
На просторах интернета, и в частности хабра, очень трудно встретить статьи с критикой игрового движка Unity. Я решил это исправить, и приготовил вам текст о переходе на DOTS, насилию над C#, знаменитых UI пакетах, MonoBehaviour, универсальности и о многом другом.
Статья не требует от вас знаний о создании игр на Unity, я ее писал с учетом того, что ее будет читать обычный программист, который сравнивает плюсы и минусы разных движков, чтоб выбрать подходящий для своего проекта. В конце концов, может вам будет просто интересно узнать, что же это за движок такой, для которого курсы рекламируются на каждом шагу.
DOTS
Кадр из презентации DOTS. На картинке изображен спальный район Москвы через 20 лет.В данный момент Unity активно переходит на новый стек технологий под названием DOTS. Транзит сопровождается лозунгом «Производительность по умолчанию» и идеей того, что С# может быть таким же быстрым как C++ у UnrealEngine и других движков. Главные фронтмены данного действа это Entities, Jobs и Burst.
Теория
Если вы уже знаете, что из себя представляет пакет DOTS, тогда можете смело переходить к пункту Имплементация.
Entities представляет из себя реализацию популярного в игровой индустрии паттерна ECS. ECS это паттерн, где код делится на сущности к которым добавляются компоненты с данными, состоянием компонентов у сущностей управляют системы, которые эффективно перебирают сущности с нужными им компонентами и изменяют данные компонентов по надобности.
К примеру, у вас игра — шутер, в которой снаряд это сущность с компонентом Bullet в котором хранятся данные о расположении снаряда. Есть система движения снарядов, которая перебирает все сущности с компонентом Bullet и двигает их вперед, а есть система рендера снарядов, которая перебирает все сущности со снарядом Bullet и рендерит их.
Реализаций ECS есть великое множество, но в основном, используют следующие способы оптимизации перебора сущностей:
Хранение компонентов эффективно в памяти в соответствии с архетипом существа к которому они привязаны. Архетип это уникальное сочетание компонентов у существа. В случае Unity, компоненты хранятся в чанках по 16кб в соответствии с архетипом. Выходит, что чанки с компонентами хранятся друг за другом в памяти.
Распараллеливание обработки существ системой. Тут всё очевидно, двигать 50 тысяч снарядов в каком-то шутере быстрее в 32х потоках одновременно. От программиста не требуется особых телодвижений для управления многопоточностью, потенциально ECS может эффективно управлять потоками самостоятельно. В Unity роль управления потоками делегирована фреймворку Jobs.
Такой паттерн хорошо подходит сложным играм, в которых есть очень много сущностей которые надо очень часто перебирать (к примеру ММО). Вдобавок, ECS управляет зависимостями, позволяя игре становиться все больше и больше без последствий.Но есть и обратная сторона медали, ECS плохо подходит играм, в которых мало сущностей и их не надо часто перебирать (например 99% мобильного рынка).
Jobs это реализация безопасной мультипоточности путем создания экземпляра «работы». Работу можно запланировать, получить ее обработчик и выполнить ее. Также работу можно запланировать после другой работы, или вместе с другими работами. Таким образом создаются целые цепи последовательных задач. Сами задачи выполняются сразу в нескольких потоках. Например, вам надо умножить все числа массива А с вместительностью в 100 элементов и положить их в массив B. Это можно сделать в десяти потоках, в каждом из них задача будет обрабатывать по 10 элементов.
Burst это компилятор, который транслирует IL байткод в оптимизированный нативный код с помощью LLVM. В основном, используется для компиляции работ с Jobs.
Имплементация
Теперь, когда вы понимаете что из себя представляет новый стек технологий теоретически, можно поговорить об имплементации. А она, как всегда, не выдержала столкновения с реальностью.
Начнем с того, как же команда Unity хочет сделать C# таким же быстрым, как C++, а именно:
Создали новый компилятор для Работ с векторизацией и intrinsics (разве что без блекджека).
Создали нессылочные альтернативы массиву, списку, очереди и т.д которые дружат с Burst’ом. Особенность в том, что эти контейнеры надо аллоцировать и после их жизненного цикла освобождать, иначе утечка. Причем, аллоцировать надо не абы как, а с правильными лейблами (Persistent/Temp/TempJob).
Ввели в использование указатели на списки и указатели на функции. Также вам может понадобиться использовать Malloc, MemMove, MemCpy и подобные
brand-newфункции.
Я думаю, вы уже поняли к чему я клоню. Они решили, что лучший способ сделать сишарп таким же быстрым как и плюсы, это сделать из сишарпа плюсы! *занавес, бурные овации, публика в шоке*
Ладно указатели, ладно Dispose у контейнеров, но когда вы начали писать новый компилятор для языка, можно же было что-то заподозрить! Пытаться уже третий год реализовать стек технологий на языке, который не подходит вашему стеку, и при этом переделывать* язык, это же сумасшествие!
Ещё один пример несовместимости DOTS и C# это Jobs с Работой IJobChunk и производными. Для того, чтобы проитерировать 3 компонента c помощью IJobChunk, вам надо 43 строки кода. Ситуацию могли бы спасти макросы, но они в C# предательски отсутствуют!
Следующая проблема нового стека Unity это недостаток многих функций, которые, иногда, могут вам пригодиться в создании игры, например:
Звук. Версия пакета для звука 0.1.0-preview17 и за 3 года он так и не обновлялся.
Интерфейс. Тут всё проще, пакета для интерфейса с поддержкой Entities просто нет.
2д. Существует com.unity.2d.entities, но он создан для Project Tiny и работает в общем-то только с ним, о Project Tiny тоже позже.
Анимации. Пакет тоже существует, версия 0.9.0-preview.6, в теории использование возможно, на практике не очень.
Всё элементы движка, которые не требуют очевидного отдельного пакета. Свет, камера, партиклы и т.д, всеми ими нельзя управлять через Entities, что угодно делайте. Можете создавать псевдо-сущность с компонентом, к примеру, камеры, и отдельной системой в главном потоке синхронизировать поля между MonoBehaviour камерой и вашей псевдо-камерой, можете другие костыли городить. За 3 года решения от Unity так и нет.
*под переделыванием языка я подразумеваю минимизирование использования ссылочных объектов и, как следствие, кучи путем создания кастомных аллокаторов, компиляторов которые не поддерживают кучу и т.п.
Проблемы
Предположим, что отсутствующие пакеты можно дописать, а текущую имплементацию можно ещё починить (в конце концов, можно переписать Roslyn!). Но проблемы самой DOTS как концепции, быстро решить не выйдет.
DOTS по умолчанию сложен. ECS требует полного понимания, как он работает, программисту надо знать на что влияет Read/Write доступ к компонентам, что такое Sync point и как сократить их количество, зачем нужен ECB, WriteGroup, гибридные компоненты и многое, многое другое. Также есть Jobs со своими контейнерами на указателях и такой же морокой с Read/Write доступом, Burst с миллиардом приспособлений для оптимизиации и примерами в документации из ассемблера.
Такая сложность явно не идёт на руку движку, одна из основных преимуществ которого простота. Unity занял свое место на рынке как «движок для дизайнеров, а не программистов», на нём делают Cuphead, Ori, Hollow Knight и другие игры которые не Factorio по сложности исполнения и требуемой оптимизации. У Unity занят рынок мобильных игр, маленьких кросс-платформенных инди игр, игр уровня «мы с парнями другие движки не знали, пришлось на этом пилить» (таким образом получаются Rust и Tarkov), в общем, идиллия. ААА игры не будут делать на Unity даже с полностью реализованным DOTS, ведь для них уже пишут отдельные движки на основе опенсоурса (UE) или вообще с нуля, а сложные инди игры делают энтузиасты на своих микро-движках, фреймворках или на том же UE.
В общем, плюсы от перехода на DOTS неочевидны, а минусы из-за нехватки ресурсов компании на поддержку и развития старых решений из уже уходящей эры MonoBehaviour присутствуют.
Project Tiny
В дополнение к выше написанному, хочу упомянуть Project Tiny. Это этакий набор мини-фреймворков для DOTS, которые должны помочь в разработке «Instant games» или, если выражаться русским языком, сделанные за 2 недели Егором из 9Б гипер казуальные игры типа тривряд. Также для Project Tiny команда Unity написала новую среду выполнения DOTS Runtime, вот вам документация (кстати в гугл доках, такого я не видел). Опять пересказывать то, что они пытаются переделать C#, смысла я не вижу, просто обозначу, что факт существования данного набора пакетов подтверждает то, что они хотят именно переделать движок с новым стеком DOTS, что в свою очередь, делает проблемы, описанные выше, ещё более значимыми.
Unity, но без DOTS
Скриншот редактора Unity. Если вы думаете, что автор не умеет удобно расставлять окна — вы правы.Под данным заголовком я хочу описать проблемы как старого архитектурного решения Unity, так и самого Unity как движка.
MonoBehaviour
Начнем с основного старого архитектурного решения — MonoBehaviour. Mono потому что на C#, раньше ещё был, к примеру, JSBehaviour, но все языки кроме C# в Unity бесславно умерли, так и остался один единственный MonoBehaviour.
Если кратко излагаться, MonoBehaviour представляет из себя базовый класс для скриптов в Unity, унаследованные от него классы можно добавить на любой объект в сцене как компоненты, а публичные поля таких классов красивенько отображаются в редакторе. Код пишется в методах со спец. именем, которые ядро движка на С++ вызывает самостоятельно, такие методы называются Messages, их у MonoBehaviour целая куча, от обычных Start
и Update
до OnCollisionEnter
и OnApplicationQuit
.
Такое решение довольно простое в понимании и не требует вообще никаких навыков у программиста, у вас все под рукой. Для больших проектов это, естественно, никуда не годится. Тут нет какой-то внятной архитектуры, у вас логика приложения находится сразу же в структуре с данными (компоненте). MonoBehaviour почти не предоставляет никаких абстракций, не дает инструмента для управления зависимостями, методы для поиска объектов с MonoBehvaiour на сцене де факто антипаттерн из-за производительности, методы для вызова Message-методов у других MonoBehaviour ещё больше антипаттерн из-за ещё худшей производительности.
В принципе создание чего-то сложнее тривряд с активным использованием MonoBehaviour не рекомендуется, а поскольку модульность в старом Unity отсутствует как понятие, просто убрать пакет с MonoBehaviour и написать что-то свое вы, конечно, не можете. Так и живут разработчики под Unity с гайдлайнами по оптимизации, в которых рекомендуют не использовать половину функций движка.
Команда Unity давным давно забила на попытки хоть как-то развить эту систему и пофиксить проблемы с производительностью.
Editor и UI
Разработчики Unity не умеют в UI. За 16 лет они не смогли создать пакет для адекватного интерфейса с xml/css/js и имплементировать редактор своего движка на нем. Для игр они сделали какой-то хлам с Canvas-ом и перетаскиванием панелей по иерархии сцены, а для редактора они предоставили что-то невообразимо ужасное с IMGUI на C# и рефлексией.
Спустя 16 лет они поняли, что шутки про использование штатного пакета для интерфейса Unity на форумах больше не смешные, и решили сделать новый пакет для интерфейса — UIElements (UIToolkit), с xml и css, но без js. Новый пакет для интерфейса непригоден для работы из-за отсутствия функционала у стилей. В нем нет анимаций, нет масок, нет полей для настроек выставления фона (только background-color и background-image), нет настроек шрифта и теней. Можете сравнить набор свойств у обычного CSS, и USS Unity.
Можно было бы сказать, что реализовать полный набор функций CSS движка довольно сложно, но вот Valve создали свой фреймворк Panorama с JS’ом, анимациями, масками, фоном, партиклами, сценами и многим другим. Благодаря ему, у игр Valve одни из самых лучших интерфейсов в индустрии. Понятно, что сравнивать Valve с Unity не совсем корректно, но это пример успешной реализации xml/css/js интерфейса в движке.
Декларируемая универсальность
Уже не совсем техническая, но огромная проблема Unity прошлого, настоящего и будущего. Unity старается быть универсальным, но игровой движок по природе своей не может быть универсальным. Нельзя сделать движок, который одинаково подходил бы сандбокс игре с процедурной генерацией мира, кооперативному FPS шутеру и мобильному кликеру. У разных игр разные требования к архитектуре движка, и если ваш движок это не каркас для плагинов как vim, то сделать его одинаково подходящим для всех не выйдет.
В случае с Unity это выливается в то, что ни одно отдельно взятое общее решение движка просто не подходит вашей конкретной проблеме. Как итог, вы постепенно отказываетесь от предоставленных движком решений и пишете свои, от чего попросту теряете время.
Этой проблеме, по сравнению с остальными, выделено не так много места в статье, но она фундаментальна. Именно эта проблема, скорее всего, потратит тонну вашего времени и похоронит проект, или уже похоронила. Если разработчики Unity сразу бы решили, для каких игр они делают свой движок, этой статьи бы не было.
Другое
Руководствуясь больше долгом о написании всех недочетов Unity, чем здравым смыслом, хочу отметить ещё немного мелких проблем которые не заслуживают отдельного параграфа, но заслуживают упоминание:
Стилистика кода у биндингов Unity с префиксами
m_
, чрезмерным использованием internal и бесполезными комментариями наподобие «x — Left coordinate, y — Top coordinate». Пример.Существование авто-сериалайзера Unity который работает хуже чем любой другой из существующих в мире, я думаю что сериалайзер на конвейерах в Factorio работал бы лучше, и как минимум, поддерживал бы сериализацию словаря.
Перезагрузка всех ресурсов с надписью «Hold on» после каждой правки кода. Команда Unity клянется что ничего не могут с этим сделать, но это нетерпимо.
В Unity до сих пор нет поддержки C# 9, я просто напомню, что последняя версия уже C# 10.Поддержку #9 давно добавили.Асинхронные юнит тесты обещали, но конечно, не сделали. Приходиться создавать костыли.
Конец
Статья вышла немного больше, чем я думал и наверняка я где-то допустил ошибку, так что прошу в комментарии. А если вы тот самый человек из начала статьи, который ищет движок для своего проекта, можете ознакомиться со следующим списком:
Для небольших игр с простой 3д или 2д графикой
Unity. Не смотря на все минусы перечисленные выше, скорее всего для простых игр он вам подойдет.
Godot. Сам не пробовал, по ощущениям Unity v2, но опенсоурс и не будет требовать от вас деньги и ставить свой логотип в начале.
GameMaker: Studio. Создан для 2д игр, на нем сделали Undertale. Без подписки минимум за 10$ делать ничего не хочет.
Microsoft XNA. Не движок, но фреймворк для создания игр на C#, больше не поддерживается (но есть форки). На нем создают довольно много разных инди игр и по сей день, одна из самых популярных это Stardew Valley.
Для средних или больших игр с 3д графикой
UnrealEngine. Больше мне советовать нечего, скорее всего он вам подойдет. Писать код на C++ это сжигание тонны времени, но блюпринты могут вас спасти.
Другое
Amethyst. Движок на Rust, пока без своего редактора, естественно опенсоурс.Разработка движка прекращена.Bevy. Конкурент предыдущего движка, можете попробовать оба.
Твоя первая игра на Godot Engine / Хабр
1.
ПредисловиеЗдравствуй, в данной статье я хочу в максимально сжатой форме познакомить тебя с основами создания простых 2d платформеров на движке Godot. Иногда мы будем останавливаться на некоторых важных моментах, а иногда пропускать ненужную тебе на начальном уровне информацию.
2.Стартуем!
Думаю установить сам движок не составит труда. После установки открываем его и нажимаем на кнопку «новый проект».
Создание проекта.В выплывшем окошке введи название проекта и выбери его расположение в файловой системе. В пункте «отрисовщик» выбираем «OpenGL ES 3.0», у нас нет нужды использовать более старую версию opengl, т.к ее обычно применяют при создании браузерных игр.
3.Знакомство с интерфейсом
2D сцена в Godot Engine.Итак, мы создали твой первый проект! Отличное начало, на сегодня хватит. Ладно, а если серьезно, то изучать интерфейс программы, особенно на первых парах, очень важно. Перед тобой открылась интересная картина с пустой 3d сценой, но она нам сегодня не понадобится, поэтому переходим во вкладку 2d. Кнопка находится сверху посередине. Стало немного проще, не правда ли? Ну, а теперь перейдем к самому интерфейсу программы (его кстати можно настроить под себя, перетащив какие-то элементы левой кнопкой мыши, но пока лучше оставить все как есть).
4.Работа с файлами через Godot
Не очень удобно каждый раз лазить в проводник, чтобы достать какие-то файлы, согласен? Для этого в Godot существует отдельное окошко, оно находится в левом нижнем углу редактора.
Проводник в Godot Engine.Пока что там пусто, но это потому, что мы еще ничего не добавили. Так давай сделаем это! Ссылку на архив я прикрепил в конце поста, скачивай его и наслаждайся халявными спрайтами для игры (сразу говорю, они не мои). Если конечно у тебя заготовлена своя графика, то милости прошу.Итак, выделяем все нужные нам файлы и переносим их в окошечко. Вжух и они скопировались в движок! Но на этом магия не заканчивается! Здесь можно делать все то, что ты делаешь в обычном проводнике! Одним словом, полная свобода действий.
Но давай пока оставим эту часть экрана в покое и перейдем к более серьезным вещам.
5.Работа со сценами
Создание новых сцен.Посмотри в верхний левый угол редактора. Здесь есть вкладка, которая называется «Сцена». Давай добавим твою первую сцену! Делается это просто, тебе нужно либо нажать на плюсик, либо ввести сочетание клавиш «ctrl + A». Перед тобой выплыло меню, в поиске которого нужно ввести заветное слово «Node». Мы давай это будет наша основная сцена, назовем ее «World», но название в принципе неважно. Чтобы переименовать сцену нужно лишь дважды щелкнуть на нее левой кнопкой мыши. Теперь давай добавим на сцену игрока!
Многие просто добавляют объект «Sprite», но это большая ошибка! Так делать нельзя! Запомни это раз и навсегда! Мы с тобой, как продвинутые пользователи добавим не «Sprite», а «KinematicBody2D».
Теперь древо твоего проекта выглядит так:
Добавляем игрока.Как ты наверное успел заметить, напротив нашего «KinematicBode2D» висит какой-то желты значок. Что он тут забыл? Дело в том, что наш объект пока что не имеет форму, вот Godot и ругается. Но прежде чем добавить форму нашему игроку, давай добавим его спрайт( И не забудь заменить название «KinrmaticBode2D» на «Player» ). Для этого нажми один раз правой кнопкой мыши на нашего «Player» и сочетанием клавиш «ctrl + A» добавь объект «Sprite». Потом опять нажми на Игрока и добавь объект «CollisionShape2D». У тебя должна быть примерно такая картина:
Добавляем в спрайт и границы игрока.Если все так, едем дальше. Теперь зададим картинку спрайта нашего персонажа. Выбираем объект «Sprite», а потом перетаскиваем из моего архива картинку «Player.png»( или твою картинку) в раздел «Texture». Если картинка импортировалась с сжатым качеством, просто нажми на нее, и в Godot в верхнем левом углу перейди в вкладку «Импорт», там в разделе «Flags» убери галочку с пункта «Filter» и нажми «Переимпортировать». Если не помогло, то просто перезапусти Godot.
Итак, мы добавили спрайт игрока, но выглядит это немного странно.
Добавляем текстуру спрайта игрока.Что же делать? Без паники, все поправимо в пару кликов. В левой части панели «Инспектор» выбираем параметр «Hframes», и подгоняем его по размерам ( у меня это 25). Ну что, поменялась картинка?
Устанавливаем границы спрайта.Супер, едем дальше! Ты еще не забыл про CollisionShape2D? Выделяй его и в пункте «Shape» выбирай «Новый RectangleShape2D». Теперь изменяй его под размер персонажа. У меня получилось так:
CollisionShape2d.6.Отдельные сцены в Godot
Это все конечно классно,но хорошим тоном в Godot является создание отдельных сцен для объектов. Поэтому нам нужно сделать так, чтобы объект «Player» был отдельной сценой. Но не создавать же нам все заново? Нет, для этого в движке предусмотрена отдельная функция.Нажмите на «Player» правой кнопкой мыши и выберете «Сохранить ветку,как ветку».
Создание сцены из ветки.Теперь «Player» это отдельная сцена, отлично!Чтобы перейти на сцену игрока достаточно нажать на иконку:
Перейдем на сцену игрока и приступим к очень интересному занятию — программированию.
7. Скрипт игрока, GDscript
Для того чтобы добавить скрипт какому-либо объекту нужно просто выбрать этот объект и нажать на иконку свитка:
Создать скрипт.После этого выплывет такая табличка:
Скрипт для игрока.Нажимаем «Создать» и у нас открывается встроенный редактор кода в Godot.Теперь начинается более сложная часть туториала, поэтому слушай внимательнее.Пока что наш персонаж просто стоит на сцене и ничего не делает, это слишком скучно. Ну так давай сделаем управление персонажем!Что нам для этого понадобится? Нам нужен скрипт, который будет обрабатывать нажатия клавиш с клавиатуры, двигать персонажа, проигрывать анимацию. Но давай пойдем по порядку и начнем с самого простого — управления.
Простое управление.Пишем вот такой код, не волнуйся сейчас все объясню. Первая строчка объявляет Godot, что мы используем объект «KinematicBody2D». Ее создал сам движок. На 3 и 4 строчке мы задаем две константы, отвечающие за ускорение и максимальную скорость. Они нужны для плавного перемещения персонажа по сцене. На 6 строчке объявляем переменную для вектора перемещения. После этого на 8 строчке создаем функцию «physicsprocess», это системная функция движка. Она нужна, чтобы привязать к персонажу физику. В нашем случае — это физика перемещения и сила гравитации. 9 строчка отвечает за управление по оси X. Метод Input помогает нам считывать те самые кнопки для управления (стрелка влево и стрелка вправо). После на 11 строчке мы проверяем была ли нажата какая-то кнопка. Потом мы перемещаемся влево или вправо.
Как ты заметил, мы прибавляем к координате игрока произведение направления по координате на ускорение и на какую-то delta. Вопрос, что такое delta? Delta показывает сколько времени (в секундах, тип float) прошло с момента отрисовки прошлого кадра.Зачем это сделано? Если мы не будем привязывать передвижение игрока ко времени, то оно автоматически привязывается к частоте процессора. На крутых компьютерах или телефонах разница незаметна, но запустив приложение на старом пк или телефоне, ты все поймешь. Поэтому всегда привязывай передвижение к delta!
Потом в строке 13 мы используем какой-то clamp. Опять неразбериха! Все просто, clamp, как можно догадаться из названия, «сжимает» значение переменной. Сделано это для оптимизации и плавности движения.Ну и в последней строке мы просто запускаем передвижение нашего игрока. Не так уж все и сложно!
8. Первый запуск.
Вот сделали мы все это с тобой, а где результат? Ну так давай поскорее запустим с тобой первую демку! Все очень просто, нажми клавишу F5, после этого выплывет окно, которое скажет тебе, что основания сцена не выбрана. В нашем случае основная сцена — World.tscn. Выбираем ее и снова жмем F5. Должно появиться что-то такое:
Окно демки.В верхнем левом углу можно заметить маленькую часть нашего персонажа. Давай приведем все в порядок. Для этого сначала закрое окошко демки и перейдем в настройки проекта. Чтобы это сделать, в левой верхней части нажми на «Проект», а в выплывшем окне нажми «Настройки проекта». Здесь переходим в вкладку «Window» и ставим разрешение на 320×180. Почему такое маленькое? Все просто, мы с тобой задали разрешение экрана в самой сцене, для платформера такие размеры идеальны. А для экрана самой демки нужно задать нормальное разрешение. Это можно сделать в пунктах «Test Width» и «Test Height». Я задам его в формате 1280×720. Спустимся пониже и в пункте «Mode» ставим «2d», а в «Aspect» ставим «keep». Для красоты предлагаю обратно перейти на сцену и передвинуть персонажа в середину экрана. Делается это легко, просто зажми персонажа левой кнопкой мыши и начни перетаскивать. Теперь все приготовления закончены,можно запускать демку.
Красота, правда? Попробуй передвигать персонажа стрелками на клавиатуре. Получилось? Да, но персонаж будто скользит по экрану и не может остановиться. Не волнуйся, скоро мы это исправим. Однако сейчас наш персонаж как бы висит в воздухе, это не есть хорошо. Давай сделаем землю для нашего игрока!
9.Tilemaps
Что такое «Tilemap»? Тайлы — это плитки, вместе образующие сетку тайлов. Чаще всего они принимают форму квадратов. Как же их добавить в наш платформер? Очень просто, для начала выбери объект «World»(нашу основную сцену), нажми клавиши «ctrl + A» и выбери «TileMap».
Теперь в этом окошке выбири «Tile Set» и нажми «Новый TileSet».Снова нажми на «TileSet», должно получиться ка-то так:
Добавляем анимацию.Давай добавим спрайт для нашего tilemap, для этого нажми на плюс снизу и выбери «tile.png».
Следующий шаг будет довольно сложным, поэтому слушай внимательно. Итак, во вкладке «Регион» полостью выделяем нашу картинку, в вкладке «snap options» ставим step по x и y на 16. Такие же действия повторяем во вкладках столкновение, перекрытие, навигация, битовая маска. А последней мы остановимся поподробней.
В ней мы нажимаем на квадратик и выделяем весь тайл. Тоже самое проделываем и в других вкладках. Вот как в итоге должно получиться.
Задаем границы тайла.Отлично, сохраняем все и переходим обратно на сцену. Еще раз кликаем на Tilemap и в раздеел «Cell» меняем size на 16×16.Теперь можно делать уровень!
Создаем простой уровень.Вот как у меня получилось. Супер, но на нашего игрока до сих пор не действует гравитация, давай это исправим. Для этого перейдем в скрипт player и введем там такой код.
Константы для прыжка и гравитации.Здесь к существующим переменным мы добавляем friction, gravity, jumpforce, airresistance. Названия говорят сами за себя, поэтому объяснять за что они отвечают я не буду.
Реализация прыжка и гравитации.Следом идет сама сила гравитации. Мы прибавляем к motion.y силу тяжести, умноженную на delta. Это действие заставляет нашего игрока падать вниз, если под ним ничего нет. После этого скрипт обрабатывает нажатия на кнопки, характерные для прыжка (стрелочка вверх). И заставляет игрока падать вниз, когда он уже прыгнул.
Вот собственно и все, давай запустим демку!Все работает. Но нет никаких анимаций,и передвижение из-за этого выглядит очень топорно.
Как выглядит при запуске.10.Анимации
Простые анимации в Godot сделать очень легко. Для этого перейдем на сцену player и добавим туда «AnimationPlayer». Жмем на кнопку «анимация», далее жмем «новый» и вводим название анимации. Сделаю анимацию для бега и назову ее «Run».Чтобы добавить новый кадр для анимации нужно перейти в «sprite».
Добавляем кадры в анимацию.Напротив пункта «frame» есть ключик,если нажать на него, то кадр из спрайта добавиться в анимацию. Постепенно увеличиваем frame от 0 до 8 и ключиком добавляем кадр в анимацию. Вот как в итоге это должно выглядеть:
Создаем анимацию из кадров.Тоже самое повторяем для других анимаций, просто меняя номер кадра. В итоге у тебя будет несколько анимаций — для прыжка, ходьбы, и анимация idle. Теперь все это нужно добавить в код.Переходим в код player и вносим некоторые изменения:
Добавляем переменные для анимации.Добавляем две переменные sprite и player. Но ты заметил, они какие-то странные. Почему в начале стоит слово onready, что за странное значение этой переменной? Сейчас все объясню. Переменные типа onready нужны для взаимодействий с другими объектами на сцене. В данном случае мы подключаем их для воспроизведения анимации и получения спрайта игрока.
Анимация при ходьбе.На 16-ой строчке мы проигрываем анимацию ходьбы. Однако здесь еще появилась какая-то странная 22 строчка, что она делает? Она зеркально отражает анимацию игрока в зависимости от того, куда он идет. А на 24 строке мы говорим, что если игрок стоит, то проигрывать нужно анимацию idle.
Анимация прыжка.На 35 строчке мы проигрываем анимацию прыжка, если игрок не на земле. Вот собственно и все изменения в коде.
Заключение
Если ты все правильно делал, то у тебя должен получиться простой платформер. Что делать дальше? Да все что угодно! Улучшай свои навыки в использовании движка, создавай свои собственные игры изучай новые фишки. На этом я вынужден с тобой проститься, надеюсь ты хорошо провел время и научился чему-то новому.
Вот все материалы для этого туториала:
Официальная торговая площадка двигателей. Магазин двигателей, новых и бывших в употреблении
Показан в телешоу Two Guys Garage на канале Discovery
Engines. com является официальной торговой площадкой для производителей двигателей.
двигательНаши двигатели полностью протестированы и готовы к работе. Поддерживается нашей эксклюзивной программой защиты покупателей и поставляется напрямую с завода.
2 977,00 $ 3 495,00 $
ПРОИЗВОДИТЕЛЬНОСТЬ
КОМПЛЕКТЫ ТРАНСМИССИИ
ЧАСТИ ДВИГАТЕЛЯ
ДЛИННЫЕ БЛОКИ
КУПИТЬ И СРАВНИТЬ
САМЫЕ ПРОВЕРЕННЫЕ БРЕНДЫ
СПЕЦИАЛИЗИРОВАННАЯ ГРУППА ПОДДЕРЖКИ
Мы знаем двигатели и готовы помочь!
EASY CORE RETURNS
Наша служба технического обслуживания силовых агрегатов делает замену сердечника быстрой и легкой.
GLOBAL SHIPPING
Мы работаем с производителями двигателей со всего мира.
Engines.com на Гараж двух парней
Гараж двух парней на канале Discovery с Уилли Би и Кевином Бердом, обзор Engines. com
ПОСМОТРЕТЬ ВИДЕО >ЛУЧШИЕ ПРОДУКТЫ ЭТОЙ НЕДЕЛИ
Распродажа75,99 $
Распродажа113,96 $
Распродажа74,99 $
Распродажа173,24 $
Распродажа64,24 $
Распродажа148,36 $
Распродажа72,47 $
Распродажа1 962,18 $
САМОЕ СВЕЖЕЕ СОДЕРЖИМОЕ ДВИГАТЕЛЯ
Официальный сайт Engines.com
POV: Ваш масляный поддон плачет, позвоните нам 😭😬#jeep #jeeplife #jeeps #corvette #ls #ls3 #lsswap
Исследуйте официальный рынок двигателестроения по адресу https://engines .com/ Присоединяйтесь к сообществу и подписывайтесь:…
Официальный сайт Engines.com
Непревзойденная производительность! Наши нагнетатели обеспечивают неустанную мощность и исключительную приемистость
Исследуйте официальный рынок двигателестроения по адресу https://engines. com/ Присоединяйтесь к сообществу и следите за новостями:…
Официальный сайт Engines.com
LS Engines Unleashed: 5 лучших спальных мест, от которых у вас перехватит дыхание!
Исследуйте официальный рынок двигателестроения по адресу https://engines.com/ Присоединяйтесь к сообществу и подписывайтесь на:…
Официальный сайт Engines.com
Reman Cadillac Engine Показан на телевидении. Официальная торговая площадка двигателестроения, Engines.com
Посетите официальный рынок двигателестроения по адресу https://engines.com/ Полный выбор восстановленных, высокопроизводительных,…
INSTAGRAM #enginesdotcom
Вы успешно подписались!
Ящик с двигателями: проектные автомобили | Запчасти Chevy Performance
Вы просматриваете сайт Chevrolet.com (США). Закройте это окно, чтобы остаться здесь, или выберите другую страну, чтобы увидеть транспортные средства и услуги, характерные для вашего местоположения.
КанадаДругое
Продолжать
- Части производительности
- Двигатели
- Компоненты двигателя
- Трансмиссии
- Компоненты трансмиссии
- Подключение и круиз
- Электрификация
- Каталог
- Части производительности
- Двигатели
- Компоненты двигателя
- Трансмиссии
- Компоненты трансмиссии
- Подключение и круиз
- Электрификация
- Каталог
Полвека назад компания Chevrolet Performance впервые представила наш высокопроизводительный двигатель в ящиках, и мы никогда не прекращали работать над тем, чтобы предлагать энтузиастам новые и более мощные решения для их проектов. У вас есть мечта в вашем гараже. Мы хотим помочь вам воплотить его в жизнь.
Соединение и круиз
LT4 ПОДКЛЮЧЕНИЕ И КРУИЗ
650 л.
с. при 6400 об/минКРУТЯЩИЙ МОМЕНТ 650 Нм
ZZ572/620 ДЕЛЮКС ПОДКЛЮЧЕНИЕ И КРУИЗ
621 л.с. при 5400 об/мин
КРУТЯЩИЙ МОМЕНТ 645 Нм
LS376/515 ПОДКЛЮЧЕНИЕ И КРУИЗ
533 л.с. при 6600 об/мин
477 Нм
LS376/525 ПОДКЛЮЧЕНИЕ И КРУИЗ
525 л.с. при 6300 об/мин
486 Нм
ZZ502/502 ДЕЛЮКС ПОДКЛЮЧЕНИЕ И КРУИЗ
508 л.с. при 5200 об/мин
580 Нм
LS376/480 ПОДКЛЮЧЕНИЕ И КРУИЗ
495 л.с. при 6200 об/мин
473 фунт-фут крутящий момент
ZZ427/480 ПОДКЛЮЧЕНИЕ И КРУИЗ
480 л.с. при 6000 об/мин
490 Нм
ZZ454/440 ПОДКЛЮЧЕНИЕ И КРУИЗ
469 л.с. при 5500 об/мин
КРУТЯЩИЙ МОМЕНТ 519 Нм
LT1 ПОДКЛЮЧЕНИЕ И КРУИЗ
460 л.
с. при 6000 об/минКРУТЯЩИЙ МОМЕНТ 465 Нм
454 HO СОЕДИНЕНИЕ И КРУИЗ
438 л.с. при 5300 об/мин,
крутящий момент 500 фунт-фут
SP383 ДЕЛЮКС ПОДКЛЮЧЕНИЕ И КРУИЗ
435 л.с. при 5600 об/мин
445 Нм
LS3 ПОДКЛЮЧЕНИЕ И КРУИЗ
430 л.с. при 5900 об/мин
425 Нм
HT502 ПОДКЛЮЧЕНИЕ И КРУИЗ
406 л.с. при 4200 об/мин
КРУТЯЩИЙ МОМЕНТ 541 Нм
ZZ6 ПОДКЛЮЧЕНИЕ ПОД КЛЮЧ И КРУИЗ
405 л.с. при 5600 об/мин
КРУТЯЩИЙ МОМЕНТ 406 Нм
ПОДКЛЮЧЕНИЕ БАЗЫ ZZ6 И КРУИЗ
404 л.с. при 5600 об/мин
406 Нм
SP350/385 ПОДКЛЮЧЕНИЕ ПОД КЛЮЧ И КРУИЗ
385 л.с. при 5600 об/мин
405 Нм
SP350/385 БАЗОВОЕ СОЕДИНЕНИЕ И КРУИЗ
385 л.
с. при 5600 об/мин405 Нм
350 HO ПОДКЛЮЧЕНИЕ И КРУИЗ
333 л.с. при 5100 об/мин
КРУТЯЩИЙ МОМЕНТ 381 Нм
HT383 ПОДКЛЮЧЕНИЕ И КРУИЗ
323 л.с. при 4200 об/мин
444 Нм
RAM JET 350 ПОДКЛЮЧЕНИЕ И КРУИЗ
350 л.с. при 5000 об/мин
КРУТЯЩИЙ МОМЕНТ 403 Нм
LT
СРАВНИТЬ ДВИГАТЕЛИ LT
LT4
650 л.с. при 6400 об/мин
КРУТЯЩИЙ МОМЕНТ 650 Нм
LT1
460 л.с. при 6000 об/мин
КРУТЯЩИЙ МОМЕНТ 465 Нм
L8T
401 л.с. при 5200 об/мин
464 фунт-фут
ЛС
СРАВНИТЬ ДВИГАТЕЛИ LS
СРАВНИТЬ ДВИГАТЕЛИ LSX
ЛС9
638 л.с. при 6500 об/мин
КРУТЯЩИЙ МОМЕНТ 604 Нм
LSX454
627 л.
с. при 6300 об/мин586 Нм
LSA
556 л.с. при 6100 об/мин
КРУТЯЩИЙ МОМЕНТ 551 Нм
ЛС376/515
533 л.с. при 6600 об/мин
477 Нм
ЛС376/525
525 л.с. при 6300 об/мин
486 Нм
ЛС376/480
495 л.с. при 6200 об/мин
473 фунт-фут крутящий момент
LSX376-B8
476 л.с. при 5900 об/мин
475 Нм
LSX376-B15
476 л.с. при 6000 об/мин
444 Нм
ЛС427/570
570 л.с. при 6200 об/мин
КРУТЯЩИЙ МОМЕНТ 540 Нм
ЛС364/450
452 л.с. при 5600 об/мин
441 Нм
ЛС3
430 л.с. при 5900 об/мин
425 Нм
Новые длинные блоки LS
Э-ШТАНГА
LT4 E-ROD
640 л.
с. при 6400 об/мин630 Нм
LT1 E-СТОЙКА
455 л.с. при 6000 об/мин
455 Нм
LS3 E-СТЕРЖЕНЬ
430 л.с. при 5900 об/мин
425 Нм
Малый блок
СРАВНИТЕ МАЛЕНЬКИЕ ДВИГАТЕЛИ
SP383 ЭФИ ПОД КЛЮЧ
450 л.с. при 5800 об/мин
436 Нм
SP383 ЭФИ ДЕЛЮКС
450 л.с. при 5800 об/мин
436 Нм
SP383 ДЕЛЮКС
435 л.с. при 5600 об/мин
445 Нм
ZZ6 EFI ПОД КЛЮЧ
420 л.с. при 5800 об/мин
408 Нм
ZZ6 ЭФИ ДЕЛЮКС
420 л.с. при 5800 об/мин
КРУТЯЩИЙ МОМЕНТ 408 ФУНТ-ФУТОВ
ZZ6 ПОД КЛЮЧ
405 л.с. при 5600 об/мин
КРУТЯЩИЙ МОМЕНТ 406 Нм
ZZ6 БАЗА
404 л.
с. при 5600 об/мин406 Нм
SP350/385 БАЗА
385 л.с. при 5600 об/мин
405 Нм
SP350/385 ПОД КЛЮЧ
385 л.с. при 5600 об/мин
405 Нм
SP350/357 БАЗА
357 л.с. при 5500 об/мин
407 Нм
SP350/357 ДЕЛЮКС
357 л.с. при 5500 об/мин
407 Нм
SP350/357 ПОД КЛЮЧ
357 л.с. при 5500 об/мин
407 Нм
350 HO ПОД КЛЮЧ
333 л.с. при 5100 об/мин
КРУТЯЩИЙ МОМЕНТ 381 Нм
HT383E
323 л.с. при 4200 об/мин
444 КРУТЯЩИЙ МОМЕНТ
HT383
323 л.с. при 4200 об/мин
444 Нм
Большой блок
СРАВНЕНИЕ ДВИГАТЕЛЕЙ BIG-BLOCK
ZZ632/1000 ДЕЛЮКС
1004 л.
с. при 6600 об/минКРУТЯЩИЙ МОМЕНТ 876 Нм
ZZ572/720R ДЕЛЮКС
727 л.с. при 6300 об/мин
680 ФУНТ-ФУТ КРУТЯЩИЙ МОМЕНТ
ZZ572/620 ДЕЛЮКС
621 л.с. при 5400 об/мин
КРУТЯЩИЙ МОМЕНТ 645 Нм
ZZ502/502 ДЕЛЮКС
508 л.с. при 5200 об/мин
580 Нм
ZZ502/502 БАЗА
508 л.с. при 5200 об/мин
580 Нм
ZZ427/480
480 л.с. при 6000 об/мин
490 Нм
ZZ454/440
469 л.с. при 5500 об/мин
КРУТЯЩИЙ МОМЕНТ 519 Нм
502 ХО
461 л.с. при 5100 об/мин
558 Нм
454 ХО
438 л.с. при 5300 об/мин,
крутящий момент 500 фунт-фут
HT502
406 л.
с. при 4200 об/минКРУТЯЩИЙ МОМЕНТ 541 Нм
Двигатели в герметичных ящиках
CT525
533 л.с. при 6600 об/мин
477 Нм
СТ400
404 л.с. при 5600 об/мин
406 Нм
СТ350
350 л.с. при 5400 об/мин
КРУТЯЩИЙ МОМЕНТ 396 Нм
DR525 (показан с автомобильным масляным поддоном F)
525 л.с. при 6200 об/мин
494 фунт-фут крутящий момент
Посмотреть все
ZZ632/1000 ДЕЛЮКС
1004 л.с. при 6600 об/мин
КРУТЯЩИЙ МОМЕНТ 876 Нм
ZZ572/720R ДЕЛЮКС
727 л.с. при 6300 об/мин
680 Нм
LT4
650 л.с. при 6400 об/мин
650 ФУНТ-ФУТ КРУТЯЩИЙ МОМЕНТ
LT4 ПОДКЛЮЧЕНИЕ И КРУИЗ
650 л.
с. при 6400 об/минКРУТЯЩИЙ МОМЕНТ 650 Нм
LT4 E-ROD
640 л.с. при 6400 об/мин
630 Нм
ЛС9
638 л.с. при 6500 об/мин
КРУТЯЩИЙ МОМЕНТ 604 Нм
LSX454
627 л.с. при 6300 об/мин
586 Нм
ZZ572/620 ДЕЛЮКС
621 л.с. при 5400 об/мин
КРУТЯЩИЙ МОМЕНТ 645 Нм
ZZ572/620 ДЕЛЮКС ПОДКЛЮЧЕНИЕ И КРУИЗ
621 л.с. при 5400 об/мин
КРУТЯЩИЙ МОМЕНТ 645 Нм
ЛС427/570
570 л.с. при 6200 об/мин
КРУТЯЩИЙ МОМЕНТ 540 Нм
ЛС376/515
533 л.с. при 6600 об/мин
477 Нм
LS376/515 ПОДКЛЮЧЕНИЕ И КРУИЗ
533 л.с. при 6600 об/мин
477 Нм
CT525
533 л.
с. при 6600 об/мин477 Нм
ЛС376/525
525 л.с. при 6300 об/мин
486 Нм
LS376/525 ПОДКЛЮЧЕНИЕ И КРУИЗ
525 л.с. при 6300 об/мин
486 Нм
DR525 (показан с автомобильным масляным поддоном F)
525 л.с. при 6200 об/мин
494 фунт-фут крутящий момент
ZZ502/502 БАЗА
508 л.с. при 5200 об/мин
580 Нм
ZZ502/502 ДЕЛЮКС
508 л.с. при 5200 об/мин
580 Нм
ZZ502/502 ДЕЛЮКС ПОДКЛЮЧЕНИЕ И КРУИЗ
508 л.с. при 5200 об/мин
580 Нм
ЛС376/480
495 л.с. при 6200 об/мин
473 фунт-фут крутящий момент
LS376/480 ПОДКЛЮЧЕНИЕ И КРУИЗ
495 л.с. при 6200 об/мин
473 фунт-фут крутящий момент
ZZ427/480
480 л.
с. при 6000 об/минКРУТЯЩИЙ МОМЕНТ 490 ФУНТ-ФУТОВ
ZZ427/480 ПОДКЛЮЧЕНИЕ И КРУИЗ
480 л.с. при 6000 об/мин
490 Нм
LSX376-B8
476 л.с. при 5900 об/мин
475 Нм
LSX376-B15
476 л.с. при 6000 об/мин
444 КРУТЯЩИЙ МОМЕНТ
ZZ454/440
469 л.с. при 5500 об/мин
КРУТЯЩИЙ МОМЕНТ 519 Нм
ZZ454/440 ПОДКЛЮЧЕНИЕ И КРУИЗ
469 л.с. при 5500 об/мин
КРУТЯЩИЙ МОМЕНТ 519 Нм
502 ХО
461 л.с. при 5100 об/мин
558 Нм
LT1
460 л.с. при 6000 об/мин
КРУТЯЩИЙ МОМЕНТ 465 Нм
LT1 ПОДКЛЮЧЕНИЕ И КРУИЗ
460 л.с. при 6000 об/мин
КРУТЯЩИЙ МОМЕНТ 465 Нм
LT1 E-СТОЙКА
455 л.
с. при 6000 об/мин455 Нм
ЛС364/450
452 л.с. при 5600 об/мин
441 Нм
SP383 EFI ПОД КЛЮЧ
450 л.с. при 5800 об/мин
436 Нм
SP383 ЭФИ ДЕЛЮКС
450 л.с. при 5800 об/мин
436 Нм
454 ХО
438 л.с. при 5300 об/мин,
крутящий момент 500 фунт-фут
454 HO ПОДКЛЮЧЕНИЕ И КРУИЗ
438 л.с. при 5300 об/мин,
крутящий момент 500 фунт-фут
SP383 ДЕЛЮКС
435 л.с. при 5600 об/мин
445 Нм
SP383 ДЕЛЮКС ПОДКЛЮЧЕНИЕ И КРУИЗ
435 л.с. при 5600 об/мин
445 Нм
ЛС3
430 л.с. при 5900 об/мин
425 Нм
LS3 E-СТЕРЖЕНЬ
430 л.
с. @5900 ОБ/МИН425 ФУНТ-ФУТ КРУТЯЩИЙ МОМЕНТ
LS3 ПОДКЛЮЧЕНИЕ И КРУИЗ
430 л.с. при 5900 об/мин
425 Нм
ZZ6 EFI ПОД КЛЮЧ
420 л.с. при 5800 об/мин
408 Нм
ZZ6 ЭФИ ДЕЛЮКС
420 л.с. при 5800 об/мин
408 Нм
HT502
406 л.с. при 4200 об/мин
КРУТЯЩИЙ МОМЕНТ 541 Нм
HT502 ПОДКЛЮЧЕНИЕ И КРУИЗ
406 л.с. при 4200 об/мин
КРУТЯЩИЙ МОМЕНТ 541 Нм
ZZ6 ПОД КЛЮЧ
405 л.с. при 5600 об/мин
КРУТЯЩИЙ МОМЕНТ 406 Нм
ZZ6 ПОДКЛЮЧЕНИЕ ПОД КЛЮЧ И КРУИЗ
405 л.с. при 5600 об/мин
КРУТЯЩИЙ МОМЕНТ 406 Нм
ZZ6 БАЗА
404 л.с. при 5600 об/мин
406 Нм
ПОДКЛЮЧЕНИЕ БАЗЫ ZZ6 И КРУИЗ
404 л.
с. при 5600 об/мин406 Нм
СТ400
404 л.с. при 5600 об/мин
406 Нм
SP350/385 ПОД КЛЮЧ
385 л.с. при 5600 об/мин
405 Нм
SP350/385 ПОДКЛЮЧЕНИЕ ПОД КЛЮЧ И КРУИЗ
385 л.с. при 5600 об/мин
405 Нм
SP350/385 БАЗА
385 л.с. при 5600 об/мин
405 Нм
SP350/385 БАЗОВОЕ СОЕДИНЕНИЕ И КРУИЗ
385 л.с. при 5600 об/мин
405 Нм
SP350/357 ПОД КЛЮЧ
357 л.с. при 5500 об/мин
КРУТЯЩИЙ МОМЕНТ 407 ФУНТ-ФУТОВ
SP350/357 БАЗА
357 л.с. при 5500 об/мин
КРУТЯЩИЙ МОМЕНТ 407 ФУНТ-ФУТОВ
SP350/357 ДЕЛЮКС
357 л.с. при 5500 об/мин
КРУТЯЩИЙ МОМЕНТ 407 ФУНТ-ФУТОВ
СТ350
350 л.
с. при 5400 об/минКРУТЯЩИЙ МОМЕНТ 396 ФУНТ-ФУТОВ
350 HO ПОД КЛЮЧ
333 л.с. при 5100 об/мин
КРУТЯЩИЙ МОМЕНТ 381 ФУНТ-ФУТ
350 HO ПОДКЛЮЧЕНИЕ И КРУИЗ
333 л.с. при 5100 об/мин
КРУТЯЩИЙ МОМЕНТ 381 Нм
HT383
323 л.с. при 4200 об/мин
444 Нм
HT383E
323 л.с. при 4200 об/мин
444 ФУНТ-ФУТ КРУТЯЩИЙ МОМЕНТ
HT383 ПОДКЛЮЧЕНИЕ И КРУИЗ
323 л.с. при 4200 об/мин
444 Нм
Новые длинные блоки LS
L8T
401 л.с. при 5200 об/мин
464 фунт-фут
350/265 База
265 л.с. при 4300 об/мин
КРУТЯЩИЙ МОМЕНТ 351 Нм
Принесите нам свой талант
Никто не разбирается в автомобилях так, как Дейл Эрнхардт-младший — так кто лучше может поделиться советом с начинающими автотехниками?
Посмотреть истории техников
БЛОК
Посетите TheBLOCK. com, чтобы заглянуть за кулисы мира Chevrolet Performance с точки зрения энтузиаста.
Узнать больше
Свяжитесь с Chevrolet Performance
Хотите узнать последние новости о Chevrolet Performance и многое другое? Свяжитесь с нами по электронной почте и в социальных сетях сегодня.
Зарегистрироваться
Принесите нам свой талант
Никто не разбирается в автомобилях так, как Дейл Эрнхардт-младший — так кто лучше может поделиться советом с начинающими автотехниками?
Посмотреть истории техников
БЛОК
Посетите TheBLOCK. com, чтобы заглянуть за кулисы мира Chevrolet Performance с точки зрения энтузиаста.
Узнать больше
Свяжитесь с Chevrolet Performance
Хотите узнать последние новости о Chevrolet Performance и многое другое? Свяжитесь с нами по электронной почте и в социальных сетях сегодня.
Зарегистрироваться
ПОСЕТИТЕ НАШИ БРЕНДЫ ДЛЯ ВАШИХ ПОТРЕБНОСТЕЙ OE
Если в настоящем документе специально не указано иное, автомобили, оснащенные деталями Chevrolet Performance, влияющими на выбросы, могут не соответствовать законам и нормам США, Канады, штатов и провинций, касающихся выбросов автотранспортных средств.