Как сделать симуляцию в unity

Добавил пользователь Morpheus
Обновлено: 05.10.2024

Разработка игр на Unity — отличный способ войти в игрострой и начать свой путь в геймдеве. Первые вопросы, которыми задаётся новичок, это как стать разработчиком игр, на что обращать внимание и где учиться.

Мы с факультетом разработки игр на Unity от GeekBrains собрали 20 советов и трюков, которые помогут освоиться в редакторе.

Не используйте Distance() или magnitude в векторах

Для расчёта расстояния между двумя векторами есть метод Distance() и поле magnitude . Но в процессе вычислений они оба используют операцию извлечения квадратного корня, которая является очень ресурсозатратной. Чтобы этого избежать, используйте поле sqrMagnitude . Оно возвращает квадрат расстояния между векторами. Остаётся лишь сравнить его со значением, также возведённым в квадрат.

Математические операции в полях инспектора

В любых числовых полях инспектора можно вводить не только цифры, но и математические выражения. Например 2 / 3 , 0,5 * 7 .

С версии 2021.2.0 Alpha 10 в инспекторе стало ещё больше доступных выражений:

  • sqrt — извлечение квадратного корня;
  • sin / cos / tan — синус/косинус/тангенс значения соответственно;
  • floor — округление значения вниз;
  • ceil — округление значения вверх;
  • round — округление значения к ближайшему целому числу.

Также математические операции можно выполнять с выделением нескольких объектов. Например выражение -=10 отнимет 10 от соответствующей координаты каждого объекта.

Ещё можно распределить координаты случайно или равноудалённо с помощью функций L(N,M) и R(N,M) соответственно, где N и M — минимальное и максимальное значения координат.

Rich Text в консоли

В обучении разработке игр часто упускают возможности кастомизации Unity, которые достаточно обширны. Например во встроенных компонентах текста UI используется форматирование Rich Text. Оно позволяет сделать текст жирным, курсивом, изменять его цвет, размер и даже присваивать материал.

Пример Rich Text в разработке на Unity

Создание элементов меню редактора

Используя атрибут [MenuItem(“My Menu”)] , можно создавать собственные вкладки меню и элементы в них. Требуется импорт пространства UnityEditor .

Код для создания кнопки меню в Unity

Создание дополнительных опций в контекстном меню компонента

Помимо собственных элементов меню можно создавать дополнительные элементы в контекстном меню компонентов. Для этого используется атрибут [ContextMenu(“Name”)] .

Код для созданий дополнительных опций в Unity

Кастомная опция в контекстном меню при разработке игр в Unity

Сохранение изменений компонента в Play Mode

Если в процессе создания игры на Unity внести какие-либо изменения в компонент с запущенной игрой, то эти изменения не сохранятся. Если вы вносили изменения в пределах одного компонента, то все его значения можно скопировать в контекстном меню компонента (Copy Component), а после того, как вы остановите игру, обратно их вставить через то же контекстное меню (Paste Component Values).

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

HideInInspector и SerializeField

Эти два атрибута помогут настроить отображение нужных полей в инспекторе. Если у вас много публичных полей, которые засоряют инспектор, то вы можете скрыть их атрибутом HideInInspector . Если же вам нужно, чтобы приватное поле, которое по-умолчанию не отображается в инспекторе, всё же можно было редактировать, используйте атрибут SerializeField .

Автоматическое создание глубины в изометрических играх

При создании 2D игры с изометрической проекцией вам может понадобиться имитировать глубину сортировкой слоёв спрайтов. То есть тот объект, который находится на заднем плане, должен быть на слой ниже переднего объекта. Если для неподвижных объектов это легко реализовать, просто настроив их слои в компоненте SpriteRenderer , то для подвижных объектов всё немного сложней.

Однако Unity уже позаботились об этом и дали возможность сортировать объекты по слоям, исходя из их координат. Для начала нужно настроить сортировку. Для этого перейдите в Edit→Project Settings→Graphics→Camera Settings. Свойство Transparency Sort Mode выставьте в Custom Axis , а Transparency Sort Axis в (0; 1; 0) . Теперь все объекты, которые будут находится на одном слою, будут автоматически сортироваться исходя из координаты Y. Те, что выше — на задний план, а те, что ниже — на передний.

Такой простой трюк значительно упростит разработку игр на Unity. Ведь без него бы пришлось вручную контролировать координаты различных объектов и менять их слои.

Выполнение кода, не привязанного к объекту

Атрибут метода [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] позволит выполнить код, не привязывая скрипт к какому-либо объекту. В данном случае код вызовется сразу после загрузки сцены.

Структуры и классы

Во время разработки игры старайтесь чаще использовать структуры вместо классов, где это возможно. Это сильно уменьшит нагрузку на игру, ведь структура является типом значения, а класс — ссылочным типом.

Создание подслоёв

Меню слоёв в редакторе Unity

Фокусировка камеры редактора на объекте и следование за ним

Чтобы сфокусироваться камерой редактора на каком-либо объекте, выделите этот объект и нажмите F. Если объект движется и вам нужно, чтобы камера следовала за ним, нажмите F дважды.

Матрица коллизий

В Unity можно определить, какие из объектов будут сталкиваться друг с другом, а какие нет. Делается это через настройку матрицы коллизий. Для этого перейдите в Edit→Project Settings→Physics→Layer Collision Matrix.

Матрица слоёв физики

Если на пересечении двух слоёв убрать галочку, то объекты этих слоёв не будут сталкиваться друг с другом. В данном случае объект слоя Player не будет сталкиваться с другими объектами своего слоя и объектами слоя Walls .

Debug Mode в инспекторе

Во время обучения разработке игр нередко попадаются ошибки. К счастью, стандартный инспектор в Unity имеет режим отладки. В нём отображаются все приватные поля компонентов. Чтобы включить его, вызовите контекстное меню вкладки инспектора или нажмите на троеточие в верхнем правом углу и выберите режим Debug. В некоторых ситуациях этот режим сильно упрощает процесс отладки и разработки игры.

Меню инспектора в редакторе Unity

Пример инспектора с включённым Debug Mode в Unity

Если у компонента есть пользовательский редактор, то он не будет отображаться в в этом режиме — там будут видны только сами поля.

Мониторинг через график

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

Посмотреть график можно, нажав на поле кривой в инспекторе:

Создание графика для отладки игры на Unity

Кеширование объектов

Ещё одна заметка с курсов создания компьютерных игр: старайтесь кешировать все объекты, с которыми вы часто работаете. Например, в скрипте вы часто обращаетесь к какому-либо компоненту через GetComponent . Вместо этого можно создать поле для этого компонента и присвоить его в методе Start . После этого можно будет обращаться напрямую к компоненту через это поле. Такое решение снизит нагрузку, так как операции GetComponent , Find , FindGameObjectsWithTag и т. д. сильно ресурсозатратны.

Создание пресетов для компонентов

Для каждого компонента можно создавать собственные пресеты. Пресет позволяет сохранить текущие настройки компонента и присвоить их другому компоненту того же типа. Пресеты хранятся в виде отдельных файлов.

Кнопка пресетов в компоненте Unity

Меню пресетов, которые помогут облегчить процесс разработки на Unity

Программная пауза

Снова про отладку, которая пригождается и разработчикам игр при обучении, и в дальнейшей работе. Поставить игру на паузу можно не только кнопкой в редакторе, но и через код. Для этого нужно установить поле EditorApplication.isPaused в значение true . Пригодиться это может во время отладки, когда нужно остановить игру прямо после какой-нибудь ошибки, чтобы детальнее её изучить.

Удобный импорт файлов из Photoshop в Unity

Установив пакет 2D PSD Importer, можно упростить процесс переноса изображений во время разработки игры из фотошопа в Unity. Этот пакет принимает файлы с расширением .psb . При импорте такого файла он автоматически создаёт в объекте все дочерние изображения, которые соответствуют слоям из фотошопа. Также он создаёт группу объектов с отсортированными по слоям компонентами SpriteRenderer .

Примечание Чтобы установить пакет, перейдите в Package Manager. В открывшемся окне в поле поиска введите имя нужного пакета. Выберите пакет и нажмите внизу кнопку Install.

Конечно, это далеко не все хитрости. Но уже с ними вы сможете облегчить себе процесс разработки. А узнать ещё больше фишек и профессионально освоить разработку игр на Unity можно на Факультете разработки игр от GeekBrains, где опытные преподаватели научат вас создавать игры с нуля и в том числе разберут особенности различных инструментов. Первые 6 месяцев обучения бесплатно.


Чтобы физическое поведение было правдоподобной, объект в игре нужно правильно ускорить и задействовать столкновения, гравитацию и другие силы. Встроенный в Unity физические движки обеспечивают вас компонентами для обработки симуляции физики. С помощью настройки всего нескольких параметров, можно создать объекты, которые ведут себя пассивно реалистично (т.е., они будут перемещены в результате столкновений и падений, но не начнут двигаться сами по себе). Управляя физикой из скриптов, вы можете придать объекту динамику автомобиля, машины или даже подвижного куска ткани. На этой странице рассматриваются основные компоненты физики в Unity со ссылками для дальнейшего чтения.

Примечание: На самом деле в Unity есть два отдельных физических движка, один для 3D физики и один для 2D физики. Основные понятия идентичны в обоих движках (за исключением дополнительного измерения в 3D), но они реализованы с разными компонентами. Так, например, существует компонент Rigidbody для 3D физики и аналогичный Rigidbody 2D для 2D физики.

See the Knowledge Base Physics section for troubleshooting, tips and tricks.

Павел Попов — Senior Unity Developer в команде NIX. В течение восьми лет он взаимодействует с архитектурой проектов и сетевой составляющей, а также периодически делает инди-игры. Знаком со стеком разработки с нуля, включая наброски картинок. Для ArtCraft Media Павел написал подробный туториал о том, как создать и анимировать 2D персонажа с помощью Unity 2020 LTS и пакетов PackageManager.

Павел Попов — Senior Unity Developer

Почему Unity?

Выбор пал на эту технологию потому, что в ней у меня больше опыта. Средства Unreal Engine, например, лучше всего использовать в 3D-разработке. Godot вполне в силах потягаться с Unity, но там еще есть нюансы с производительностью и стабильностью. Adobe Animate или Toon Boom Animation — для тех, кто рисует покадрово, например, для художников и профессиональных аниматоров.

Мы же нацелены на автоматизацию, и применение этих анимаций в играх или кат-сценах. Так мы сможем управлять широким спектром составляющих картины, не прибегая к прорисовке каждого кадра, а используя сам движок и наработки: освещение, эффекты, симуляции боев и тому подобное.

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

Сейчас мы создадим готового к анимации персонажа средствами Unity из картинки, разбитой на части. Освоив описанные ниже инструменты, ты сможешь оживить любую картинку, привести в нужный вид персонажа и также оживить его. Кроме того, в будущем ты будешь гораздо точнее ставить задачи художникам. Итак, погнали!

Начальная настройка Unity

Поставив 2D PSD Importer, за ним подтянется 2D Animation, который нам понадобится для инверсной кинематики (далее IK). Далее все, что нам нужно — правильно настроенный арт, и здесь есть свои тонкости. Возьмем для наглядности программу Gimp (последующие действия идентичны для Photoshop).


Используемые пакеты (Окно PackageManager (Windows->PackageManager). Источник: личный архив автора

Разбиваем персонажа на слои в Gimp (или Photoshop)

Персонаж, разобранный по слоям в Gimp. Источник: личный архив автора

Персонаж, разобранный по слоям в Gimp. Источник: личный архив автора

Если используешь Photoshop, выбери при экспорте формат .psb. Если Gimp, то экспортируем .psd, и потом вручную меняем формат файла на psb в проводнике. Они отличаются большим объемом поддерживаемого разрешение вплоть до 300 000 x 300 000 в отличии от обычного .psd (30 000 x 30 000). Если кидать обычный формат (.psd), Unity его не увидит. Перейдем к самому интересному инструменту с пакета PSD Importer.

Настройка персонажа в Unity

Благодаря PSD Importer пакету мы видим дополнительные возможности — Secondary Textures. Они нужны, чтобы наложить дополнительные карты нормалей или высот, и сделать нашу картинку объемнее.

 Выбираем нашего персонажа (Окно SpriteEdtior по клику на на файл персонажа.psb, youtubeIntro). Источник: личный архив автора

Выбираем нашего персонажа (Окно SpriteEdtior по клику на на файл персонажа.psb, youtubeIntro). Источник: личный архив автора

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

Результат — свет знает, как осветить sprite. Высоты и углубления знаем благодаря NormalMap. Источник: личный архив автора
Результат — свет знает, как осветить sprite. Высоты и углубления знаем благодаря NormalMap. Источник: личный архив автора

Результат — свет знает, как осветить sprite. Высоты и углубления знаем благодаря NormalMap. Источник: личный архив автора

Идем дальше: проверяем, распознались ли все элементы в главном окне корректно, и можем переименовать или изменить pivot по необходимости. Теперь нас интересует Skinning Editor.

Окно Skinning Editor. Источник: личный архив автора

Окно Skinning Editor. Источник: личный архив автора

Полезные ссылки о PSD Importer о SkiningEditor. Рекомендую ознакомиться с примерами, если есть желание создать что то отличное от нашего персонажа, и чтобы понять разные стороны инструмента.

Оранжевым цветом на скриншоте подсвечено, какую панель стоит включить. С ее помощью мы правильно выложим наши кости, и она работает как стандартная иерархия объектов в Unity (Hierarchy — главная панель, переставления родительских объектов в дочерние, — прим. авт.).

Советую сразу именовать новосозданную кость в панели Visibility -> Bone (на скриншоте ниже выделено оранжевым).

Финальный результат настройки костей. Источник: личный архив автора

Финальный результат настройки костей. Источник: личный архив автора

Нажимаем AutoGeometry для построения геометрии под каждый спрайт. Это позволяет в тонкой настройке задать нужный Mesh Deformation. Убрав выделение с какого-либо спрайта, жмем AutoWeight.

Маловероятно, что тулза на 100% распознала все верно. Перейдем в детальные настройки. Первое, что нас интересует — какой спрайт и область привязалась к кости. Для этого открываем Bone Influence.

Bone Influence — настройка привязки костей к изображению и его областям. Источник: личный архив автора

Bone Influence — настройка привязки костей к изображению и его областям. Источник: личный архив автора

В нашем случае будет достаточно того, чтобы одна кость управляла только одним спрайтом и всей его областью.

Примечание: есть более продвинутый режим — это, например, когда надо сделать, чтобы плащ был анимирован. Для этого вручную настроена сетка (вкладка Edit Geometry), и заданы несколько костей с областями с помощью инструмента Weight Brush. Но для первичного разбора нам достаточно правильно задать привязки костей к картинкам.

Когда мы уберем лишние кости, увидим, что вся область подсвечивается цветом этой кости. Если что-то не так, перегенерируйте Weight (AutoWeights -> Generate).

Финальный результат настройки. Источник: личный архив автора

Финальный результат настройки. Источник: личный архив автора

В случае правильной настройки костей к областям изображения (у нас же — ко всему слою картинки), переходим к настройке иерархии. На вкладке visibility мы видим финальный результат. Если у тебя было подобное наименование костей, ты легко можешь это проверить.

Примечание: Рекомендую для ног и рук сделать три кости, или позже добавить их в режиме префаба. Так нам будет проще с помощью LimbSolver 2D (из пакета 2D Animation — компонент инверсной кинематики, — прим. авт.) настроить конечности. Не забываем нажать Apply, перекидываем наш префаб в Unity:

Настроенный персонаж исходное состояние. Источник: личный архив автора

Настроенный персонаж исходное состояние. Источник: личный архив автора

Настройка персонажа для анимации с помощью инверсной кинематики

Перед тем, как мы дополним персонажа элементами управления, нужна предварительная настройка. Создадим родительский объект для нашего героя и проверим, что у него нулевые координаты и стандартный масштаб равный одному:

Создание родительского объекта для персонажа. Источник: личный архив автора

Создание родительского объекта для персонажа. Источник: личный архив автора

Создаем префаб персонажа. У новой системы префабов Unity (начиная с версии 2018 года, — прим. авт.) есть некоторые особенности. Например, объект, который мы создали из ассета, не будет сохранять изменения. Даже если это исходник, как и любая 3D-модель. Поэтому для сохранения своих трудов рекомендую вкладывать подобные объекты в еще один родительский:

Исходный файл персонажа. Источник: личный архив автора

Исходный файл персонажа. Источник: личный архив автора

Далее добавляем четыре Limb Solver — это будут наши конечности. И один ССD, так как у нас между головой и туловищем всего две кости. Здесь мы можем настроить точнее. Если нет желания заморачиваться, можно просто создать пустой объект (в нашем случае — вместо меча), и сдвинуть его, или вовсе учесть в настройках костей шагом ранее.

Примечание: CCD и FABRIK отличаются точностью и количеством проходов по иерархии. Рекомендую ознакомиться с документацией подробнее.

Добавляем Limb Solver. Источник: личный архив автора

Добавляем Limb Solver. Источник: личный архив автора

Теперь именуем наши вновь созданные объекты, и создаем по одному простому GameObject под каждый. Желательно их тоже назвать, чтобы в дальнейшем не теряться. Устанавливаем Target в каждом созданном Solver — четыре Limb и один CCD.

Устанавливаем Target в дочерние объекты. Источник: личный архив автора

Устанавливаем Target в дочерние объекты. Источник: личный архив автора

Теперь устанавливаем Effector-точку для каждого IK Solver:

ArmL Solver Setup. Источник: личный архив автора
ArmL Solver Setup. Источник: личный архив автора
ArmL Solver Setup. Источник: личный архив автора

ArmL Solver Setup. Источник: личный архив автора

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

Результат первичной настройки. Источник: личный архив автора

Результат первичной настройки. Источник: личный архив автора

Здесь мы видим две проблемы. Во-первых, наши суставы смотрят не в ту сторону. Во-вторых, наш управляющий point направляет руки персонажа не туда, куда надо.

Для начала поправим положение рук. Для этого переходим в конечную иерархию в Sword. Наведя курсор между X и значением, появляется альтернативный курсор — <>. Кликаем и понемногу меняем положения так, чтобы наш меч лег в руку. Ту же операцию проводим и для координаты Y при необходимости.

Настройка IK. Источник: личный архив автора

Настройка IK. Источник: личный архив автора

Сделаем так с обеими руками. Если у тебя кости находятся последовательно друг за другом, с этой проблемой ты не столкнешься. Также удостоверимся, что родительский объект не имеет смещения:

Проверка на смещение управляющих точек. Источник: личный архив автора

Проверка на смещение управляющих точек. Источник: личный архив автора

Переходим к суставам. Для этого кликаем на Flip-настройку. Этот инструмент вывернет сустав в нужную сторону. Здесь все зависит от первоначального скелета. В нашей ситуации имеем дело с ногами:

Настройка суставов. Источник: личный архив автора

Настройка суставов. Источник: личный архив автора

Мы получили настроенного персонажа, которым можем управлять с помощью пятью точек. Также нам доступен Root, который не привязан к инверсной кинематике. Сдвигая его, мы можем менять положения тела, а наши IK Solver оставят конечности в той же позиции.

Финальный результат настройки. Источник: личный архив автора

Финальный результат настройки. Источник: личный архив автора

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

В следующей части рассмотрим создание кат-сцены и то, как мы можем скомпозировать управление камерой, эффектами и уже настроенным персонажем в одном таймлайне с помощью Cinemachine Package.

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

Поскольку мой лес фэнтезийный, решил поступить максимально логично и тупо воткнуть туда космический корабль. Почему бы и нет, черт побери? 😉

Как добавить космический корабль на сцену

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

Добавление модели на сцену

И вот мой корабль уже ждет меня на берегу болота. Сейчас это просто моделька – даже без collision shape. А маленьким я его сделал потому, что террейн у меня небольшой. Хочу просто полетать между деревьями, как эльф. Эльф на звездолете!

Как создать коллайдер и добавить массу

Как я уже сказал, корабль – просто моделька. Через нее можно даже пройти. Нужен коллайдер для столкновений и физика – масса корабля.

Первым делом я выделил корабль в иерархии проекта, нажал Add Component в инспекторе и добавил ему свойство Rigidbody. Массу увеличил до 200 единиц, чтобы персонаж при столкновении не мог сдвинуть его с места.

Добавление массы

Создание коллайдера

Ну и вот он, красавец, одиноко лежит на земле в моем лесу.

Корабль

Пришлось передвинуть его в другое место, потому что при первом запуске он жизнерадостно уехал по склону прямиком в мое болотное озерцо 😀.

Как сесть в корабль

Логику происходящего я понимаю лишь примерно.

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

По крайней мере, так я это выдумал на основе того, что видел в играх… Посмотрим, что получится.

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

Камера (здесь я для теста сделал ее дочерней, но затем ее нужно достать наружу)

Камера (здесь я для теста сделал ее дочерней, но затем ее нужно достать наружу)

Перенос постэффектов

Скопировал все компоненты. Теперь все в порядке. Можно продолжать.

Скопировал все компоненты

Не забудьте отключить камеру (галочка в инспекторе)! Дело в том, что 2 активные камеры – это двойная нагрузка на видеокарту. Очевидно, камеру для таких вещей нужно включать / выключать скриптом.

Скрипт посадки на корабль и выхода наружу

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

Опыта в программировании под Unity у меня нет, поэтому совместными силами с Google, YouTube и документацией мы родили простенький скриптик. Я снабдил код подробными комментариями, чтобы было понятно, что происходит.

Этот скриптик по моей задумке вешается на корабль. Сперва регистрируются публичные переменные, которые добавят поля. В эти поля надо поместить объект игрока, объект корабля и камеру корабля. Также добавляется переменная с максимальной дистанцией до корабля, при которой в него можно сесть. Я поставил 10 единиц (пока не знаю каких 😁).

Скрипт вешается на корабль

Вот, по сути, и все. Теперь при приближении к кораблю я могу в него сесть, а затем выпрыгнуть ему на крышу.

Сел в корабль. Каеф ;)

Без видео это, к сожалению, сложно продемонстрировать. Так что придется тебе, дорогой читатель, поверить мне на слово. По крайней мере пока… В конце я обязательно покажу, что получилось 😉.

Как летать на корабле

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

Итак, первое, что я усвоил методом проб и ошибок – не стоит тулить все функции корабля в один скрипт, иначе в итоге он превратится в такую помойку, в которой черт сломает ногу, руку и повесится. Лучше разделить функционал по типу и раскидать на несколько небольших файлов.

В моем случае скриптов получилось аж 5 штук. Вот их список в том порядке, в котором я их делал.

  • EnterToShip (вешается на корабль) – вход в корабль и выход из него.
  • ShipCameraFollow (вешается на камеру корабля) – управление камерой.
  • ShipControl (вешается на корабль) – управление кораблем.
  • ShipEffects (вешается на корабль) – включение / переключение / отключение систем частиц, которые имитируют реактивные струи двигателей.
  • ShipAudio (вешается на корабль) – включение / переключение / отключение аудио-эффектов, которые имитируют гул двигателей.

Как сделать камеру слежения за кораблем

Выбесила она меня страшно, надо сказать. Куда не зайди (я имею в виду YouTube, гайды в сети и так далее), на тебя вываливают какие-то дебри кода с кватернионами, непонятными расчетами и черт знает чем еще. Перепробовав все это я столкнулся с неимоверным количеством глюков.

Скрипт камеры слежения

В итоге выкинул все, сел и просто стал думать.

Итак, у меня есть корабль. И у меня есть камера. Камера должна всегда находиться позади корабля, но следовать за ним с небольшой задержкой. Повернуть камеру на объект легче легкого с помощью Transform.LookAt(). Движение за объектом и задержку вроде бы тоже нетрудно сделать с помощью Vector3.Lerp(). Но как заставить камеру всегда находиться позади объекта?

Оказалось, очень легко. Нужно просто задать камере смещение относительно самого корабля. И я сделал это в 3 строчки кода.

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

Реализация управления

Управление получилось несколько топорным, если сравнивать с настоящими играми. Но в целом летать можно, и это даже по кайфу.

Скрипт контроллера корабля

Код я немного причесал и обильно прокомментировал. Хотя уверен, что круглые новички все равно ничего не поймут. В общем, логика работы следующая.

Чтобы скрипт нормально работал, в Rigidbody корабля в Инспекторе нужно настроить Mass (массу), Drag (сопротивление среды движению) и Angular Drag (сопротивление вращению). От массы корабля напрямую зависит сила импульса, которую нужно применить в AddForce(), чтобы он полетел. Высокие сопротивления помогут удерживать корабль стабильным. В противном случае после придания ускорения его уже будет крайне сложно остановить, и его будет мотать по всей округе. То же самое с вращением – если не хотите превратить корабль в спинер, то Angular Drag ставьте большой.

Визуальные эффекты для корабля

По сути, корабль был уже готов. Можно было летать и выполнять фигуры высшего пилотажа. Но все это происходило в тишине и скукоте. Решил добавить визуальные эффекты.

(Эффекты частиц вам придется создать самим )

  1. Сделал одну систему частиц, имитирующую реактивную струю из двигателя. Даже добавил в нее источник света, чтобы был эффект освещенности. Сделал ее дочерним объектом корабля, назвал Engine1Fire.
  2. Скопировал ее для второго двигателя, назвал Engine2Fire.
  3. С помощью скрипта запрограммировал 4 фазы: двигатели выключены (игрок вне корабля), двигатели на минимум (режим бездействия), двигатели в полете (W), двигатели форсаж (W + Shift).
  4. Чтобы эффект различался по степени яркости, изначальные частицы сделал прозрачными, а выполнении условий фазы просто добавлял их количество.

Получился довольно прикольный эффект. Вначале струя тусклая, при полете ярче, а при ускорении – совсем яркая.

Код, опять же, причесал, как мог.

Звуковые эффекты для космического корабля

Еще одно место, где меня, зеленого неофита, ждали боль и страдания.

Скрипт звуковых эффектов для корабля

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

Во-вторых, у меня долго не получалось сделать звук объемным. То есть не просто рев моторов в фоне, а чтобы он исходил из корабля. В итоге скачал ассет Resonance Audio (инструкция по установке) – не работает. Долго не мог понять, что не так. В конце концов, дошло: нужно отключать Audio Listener на камере корабля, когда она неактивна. Вырубил, управление прописал в скрипт.

В-третьих, нужно было сделать зацикленный звук рева двигателей. К счастью, тут все оказалось так сложно. Первым делом надо скачать полностью бесплатную программку Audacity. Затем найти в интернете бесплатный файлик с ревом двигателей.

  1. Открываем файл с шумами в проге, обрезаем более-менее стабильно звучащий кусочек.
  2. Копируем его, копию ставим в начало файла.
  3. Оригинал разворачиваем задом наперед (Эффекты → Реверс).
  4. Присобачиваем к копии.
  5. Обязательно заходим в Эффекты → Обрезка тишины и, ничего не меняя, применяем на трек. Это удалить паузу (миллисекунды тишины) в начале трека.
  6. Готово. Экспортируем в OGG и закидываем в Unity.

Создание зацикленного бесшовного звука двигателей

В целом, я думаю, получилось, нормально. Иногда проскакивают косяки со звучанием вертикального взлета, но я это исправлю… Когда-то 😀.

Видео с моим кораблем

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

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

Надеюсь, приведенный здесь код будет кому-то полезен. Увидимся в следующих постах 😉.

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