Как сделать настройки в unity 2d
Трудно представить современную игру без анимаций. Сегодня я расскажу о том как работаю с 2д анимациями на Юнити через фреймворк Actors. Описанный мною подход реализуется легко на любых движках и языках. Ну а проект на юнити можно скачать отсюда.
Проблема
Зачем свое решение писать если в Unity уже есть Mecanim? Я много работаю с 2д анимациями и могу ответственно сказать, что использовать меканим для 2д это как стрелять из пушки по воробьям. Много ассетов,много абстракций, много оверхеда, много гибкости и мало смысла.
Дело вкуса и предпочтений но для того чтобы настроить простейшие связи анимаций нужно
- Добавить animator на объект
- Сделать animator controller ( особенно жесть если анимация всего 1 или 2 ).
- Понять, что лучше для этих целей использовать component animation. Который Legacy. Который в общем-то не дает нам ничего кроме массива анимаций и проигрывания. Да еще и с лишними вызовами методов со стороны движка хрен знает чего и для чего.
Допускается что мы будем использовать и Animator Controller и Component Animation и работать уже с двумя логическими единицами - Нужно создать anim clip и загрузить туда свою 2д анимацию. Кто этим никогда серьезно не занимался не прелставляет какой это гемор. Спасает разве что PowerSprite Animator от Powerhoof.
- Настроить animator controller закончив это дело настоящим итальянским болоньезе,с кучей второстепенных скриптов и невнятной логики.
- Goto 1. и так пока весь проект незавалится кучей бесмысленных ассетов с animator и anim clip.
БОЛОНЬЕЗ НЯМ
Я не говорю, что mecanim плох, я говорю вот об этом:
Описываем задачу
Чертить тонны схем и из какого места должны вылазить методы не моё , но прежде чем погрузиться в код надо хотя бы примерно представлять что мы будем делать.
- Мы создаем систему которая будет работать БЕЗ юнити аниматора и анимклипов.
- Нам нужно иметь возможность загружать несколько анимаций для объекта.
- Нам нужен функционал позволяющий проигрывать цепочку анимаций. Хотя бы цепочку из двух анимаций.
- Было бы неплохо при вызове анимации получить назад время на проигрывание выбранной анимации.
- Нам нужно иметь возможность работать с анимациями через скрипты если это потребуется.
- Простое api чтобы назначать и сбрасывать анимации у сущностей.
- Работает из Actors разумеется.
Что мне нравится в системах анимаций так это то, что их можно сделать какими угодно сложными или простыми.
В конечном итоге у нас должно получиться что-то такое:
sequence
sequences
Нам нужны ID для анимаций. Я предпочитаю использовать константы, но это так же легко делается через enum.
ComponentAnimator
Это компонент для екс. В общем-то это то что мы будем вешать на наши сущности.
Здесь нам интересен AnimatorGuide. Именно он позволит тонко работать с анимациями и добавлять к ним "события" и "скрипты".
AnimatorGuide
AnimatorGuide это аналог Mecanim в коде. С помощью animator guide можно легко настроить логику для базовых анимаций. Например все юниты проигрывают idle если скорость = 0 или меняют анимацию на бег если скорость выше 0.
AnimatorGuide по умолчанию не делает ничего. Напишем AnimatorGuidePawn который прикажет всем сущностям у которых он есть стоять на месте. Каждый раз когда мы создаем новую сущность она начнет проигрывать idle. Если мы в коде игры ( например в АИ скриптах ) перезапишем анимацию, то cAnimator.overriding не даст работать методу handle в AnimatorGuide. Так же нам не придется создавать по копии класса AnimatorGuidePawn для каждого юнита. Можно будет просто повесить один и тот же AnimatorGuidePawn через Instance.
ProcessorAnimator
Создаем процессор ( или еще их называют системами ) который будет обрабатывать все сущности с нашими компонентами ComponentAnimator и ComponentRenderer. ComponentRenderer просто хранит ссылку на SpriteRenderer.
game.locals.time_between_frames хранит время через которое нам надо обновлять кадры. В целях простоты мы не делаем локального времени для каждой отдельной секвенции, однако добавить это очень просто.
Осталось прикрутить API и сделать загрузку анимаций.
Метод ниже позволяет проиграть анимацию у сущности. Мы выбираем тип анимации, сколько раз она должна проиграться и c какого кадра. Мы так же считаем время нужное на проигрывание анимации и кешируем его в компоненте/возвращаем обратно.
anim.loop и anim.random_frame просто удобные константы чтобы указать что нам нужно сыграть анимацию бесконечно раз или нам нужен случайный кадр. Эти контанты добавляем к структуре anim```
Последний метод который нам понадобится это animationReset Мы просто сбрасываем кадры до нуля и говорим, что больше не перезаписываем анимацию чтобы наш animator guide мог решить сам какую анимацию нужно запустить.
Загрузка анимаций
Делаем все из кода. Просто и быстро. Box.Load это обертка Resources.Load в фреймворке с возможностью кеширования. Последняя секвенция интересная. Мы в ней пишем, что после проигрывания анимации Grab нужно проиграть анимацию Walk
($"
Результат
У нас на руках простое, легкорасширяемое решение по анимациям. Зарисуем же чтонибудь на экране. В самом начале поста я показывал как у нас это будет выглядить в скриптах игры.
Интереснее всего этот отыгрыш. После четырёх отыгрышей anim.grab отыграется anim.walk так как мы ее указали в настройках анимации для этого юнита.
Проект на unity можно скачать здесь.
Это не самая совершенная система, но ее не сложно дополнить нужными фишками. Но хочется особенно подчеркнуть : keep it simple, code fast.
А как справляетесь с анимациями вы? Делитесь мыслями и идеями в комментариях, будет интересно почитать :)
🎮 Игры
Unity - отличный инструмент для создания прототипов всего, от игр до интерактивных визуализаций. В этой статье мы рассмотрим все, что вам нужно знать, чтобы начать использовать Unity.
Вступление
Эта статья предназначена для всех, кто никогда раньше не использовал Unity, но имеет некоторый опыт программирования или веб-дизайна / разработки. К концу этой статьи у вас должен быть хороший общий обзор движка, а также всех необходимых функций и кода для начала создания базовой игры.
Почему Unity?
Если вы хотите делать игры
Когда дело доходит до разработки инди-игр, вариантов действительно очень мало. Если вы хотите создавать игры, есть три основных варианта: Unreal, Unity или GameMaker.
Unity, вероятно, наименее упрямая из трех платформ. Он дает вам очень сырой продукт из коробки, но он очень гибкий, хорошо документированный и расширяемый для создания практически любого жанра игры, о котором вы только можете подумать.
В Unity есть множество очень успешных игр, таких как Escape from Tarkov (FPS), Monument Valley (Puzzler) и This War of Mine (Стратегия / Выживание).
На самом деле движок, на котором вы создаете свою первую игру, вероятно, не критичен, поэтому мой совет — просто выберите один и используйте его.
Если вы хотите прототипировать пользовательский опыт
Поскольку Unity — это всего лишь движок с кучей физики, анимации и 3D-рендеринга в реальном времени, это также отличное место для создания полноценных интерактивных прототипов для исследований UX.
Unity полностью поддерживает VR и AR и, следовательно, может стать отличным инструментом для изучения архитектуры, автоматизации и моделирования с помощью клиентов.
Окно редактора Unity
Окно редактора разделено на несколько разделов. Мы расскажем об этом очень кратко, так как будем постоянно к нему обращаться на протяжении всей статьи. Если вы уже знакомы с этим, пропустите мимо!
Просмотр сцены: позволяет размещать и перемещать игровые объекты в сцене.
Просмотр игры: предварительный просмотр того, как игрок будет видеть сцену с камеры.
Инспектор: предоставьте подробную информацию о выбранном GameObject в сцене.
Assets / Project: здесь хранятся все префабы, текстуры, модели, скрипты и т. Д.
Иерархия: позволяет вложение и структурирование игровых объектов внутри сцены.
Теперь мы готовы начать!
Объекты Unity Game
Что такое GameObjects
Если у вас есть опыт веб-дизайна, вы можете думать о GameObjects как о элементах
! Чрезвычайно скучные контейнеры, но они легко расширяемы для создания сложной функциональности или визуальных эффектов.
Буквально все, от эффектов частиц, камер, игроков, элементов пользовательского интерфейса… (список продолжается) — это GameObject.
Создание иерархии
для создания разнообразных и желаемых макетов или абстракций, вы можете сделать то же самое с игровыми объектами.Логика вложения игровых объектов во многом такая же, как и при веб-разработке, я приведу несколько примеров …
Беспорядок и эффективность
Веб-аналогия: у вас есть много похожих элементов, которые могут динамически генерироваться на лету в ответ на взаимодействие с пользователем, и вы хотите, чтобы они оставались аккуратными.
Позиционирование
Unity Translation: вы создали группу дронов-помощников, которые летают вокруг игрока. На самом деле вы бы не стали писать код, чтобы они гонялись за игроком, поэтому вместо этого вы создаете их как дочерние элементы игрового объекта player.
Встроенные компоненты Unity
Компонентная модель актера
Unity работает на основе модели компонентов акторов, проще говоря, GameObjects — это актеры, а компоненты — ваши скрипты.
Если вы писали какие-либо веб-приложения раньше, вы будете знакомы с идеей создания небольших повторно используемых компонентов, таких как кнопки, элементы форм, гибкие макеты, которые имеют различные директивы и настраиваемые свойства. Затем собираем эти маленькие компоненты в большие веб-страницы.
Большим преимуществом этого подхода является возможность повторного использования и четко определенные каналы связи между элементами. Точно так же при разработке игр мы хотим минимизировать риск непреднамеренных побочных эффектов. Небольшие ошибки имеют тенденцию выходить из-под контроля, если вы не будете осторожны, и их чрезвычайно сложно отладить. Таким образом, создание небольших, надежных и повторно используемых компонентов имеет решающее значение.
Ключевые встроенные компоненты
Думаю, пришло время привести несколько примеров встроенных компонентов, предоставляемых движком Unity Games.
- MeshFilter: позволяет назначать материалы для 3D-сетки GameObject.
- MeshRender: позволяет назначать материалы 3D-сетке.
- [Коробка | Mesh] Collider: позволяет обнаруживать GameObject во время столкновений.
- Rigidbody: позволяет реалистичному физическому моделированию воздействовать на GameObjects с 3D-сетками и запускать события обнаружения на коллайдерах боксов.
- Свет: освещает части вашей сцены.
- Камера: определяет область просмотра игрока, которая будет прикреплена к GameObject.
- Различные компоненты холста пользовательского интерфейса для отображения графического интерфейса пользователя
Их еще много, но это основные, с которыми вам нужно познакомиться. Один совет заключается в том, что вы можете получить доступ ко всем документам по ним через руководство по Unity и справочник по сценариям в автономном режиме, где бы вы ни находились:
Создание пользовательских компонентов
Структура моноповедения
Ключевые функции
Все компоненты наследуются от класса MonoBehaviour. Он включает в себя несколько стандартных методов, главное:
- void Start (), который вызывается всякий раз, когда объект, содержащий скрипт, создается в сцене. Это полезно в любое время, когда мы хотим выполнить некоторый код инициализации, например. установить экипировку игрока после того, как он появится в матче.
- void Update (), который вызывается каждый кадр. Это то место, где будет выполняться основная часть кода, включающего пользовательский ввод, обновляющего различные свойства, такие как движение игрока в сцене.
Переменные инспектора
Часто мы хотим сделать компоненты максимально гибкими. Например, все оружие может иметь разный урон, скорострельность, has_sight и т. Д. Хотя все оружие, по сути, одно и то же, мы можем захотеть иметь возможность быстро создавать различные вариации с помощью редактора единства.
Другой пример, когда мы можем захотеть это сделать, — это создание компонента пользовательского интерфейса, который отслеживает движения мыши пользователя и помещает курсор в область просмотра. Здесь мы можем захотеть контролировать чувствительность курсора к движениям (если пользователь использовал джойстик или геймпад, а не компьютерную мышь). Таким образом, имеет смысл сделать эти переменные легко изменяемыми как в режиме редактирования, так и поэкспериментировать с ними во время выполнения.
Переменные в окне инспектора можно изменить в любой момент во время выполнения или в режиме редактирования. Примечание. Изменения, внесенные во время выполнения, не будут постоянными.
Мы можем сделать это легко, просто объявив их как общедоступные переменные в теле компонента.
Обратите внимание, как мы можем сделать переменные с разными уровнями доступа, частными, общедоступными или общедоступными, но не отображаемыми в окне инспектора.
Принятие пользовательского ввода
Конечно, мы хотим, чтобы наша игра реагировала на ввод пользователя. Наиболее распространенные способы сделать это — использовать следующие методы в функции Update () компонента (или в любом другом месте, которое вам нравится):
Управление игровыми объектами
Трансформации
Все GameObjects имеют свойство transform, которое позволяет выполнять различные полезные манипуляции с текущим игровым объектом.
Вышеупомянутые методы довольно понятны , просто обратите внимание, что мы используем gameObject в нижнем регистре для ссылки на GameObject, которому принадлежит этот конкретный экземпляр компонента.
В общем, рекомендуется использовать локальное [Положение, Вращение], а не глобальное положение / поворот объекта. Обычно это упрощает перемещение объектов разумным образом, поскольку ось локального пространства будет ориентирована и центрирована на родительском объекте, а не на мировом начале координат и направлениях x, y, z.
Преимущества локального пространства станут немного более очевидными с диаграммой!
Если вам нужно преобразовать между локальным и мировым пространством (что часто бывает), вы можете использовать следующее:
Создание новых игровых объектов
Поскольку GameObjects — это в основном все в вашей сцене, вы можете иметь возможность генерировать их на лету. Например, если у вашего игрока есть какая-то пусковая установка для снарядов, вы можете захотеть создавать снаряды на лету, у которых есть собственная инкапсулированная логика для полета, нанесения урона и т. Д.
Сначала нам нужно ввести понятие префаба . Мы можем создать их, просто перетащив любой GameObject в иерархии сцены в папку с ресурсами.
По сути, это хранит шаблон объекта, который только что был в нашей сцене, со всеми теми же конфигурациями.
Пример пользовательского объекта-кирпича, который используется для динамического создания кубиков Lego в сцене, к нему прикреплен набор компонентов с различными значениями по умолчанию.
Когда у нас есть эти сборные компоненты, мы можем назначить их переменным инспектора (как мы говорили ранее) для любого компонента в сцене, чтобы мы могли создавать новые GameObject, как указано в сборке, в любое время.
Доступ к другим игровым объектам и компонентам
После этого вы можете получить доступ к любому из общедоступных методов / переменных компонента, чтобы управлять GameObject. Это простой момент, однако на самом деле получить ссылку на GameObject можно несколькими способами …
Доступ через переменную инспектора
Это самый простой способ. Просто создайте общедоступную переменную для GameObject, как мы продемонстрировали ранее с префабами, и вручную перетащите ее на компонент через инспектор. Затем перейдите к переменной, как указано выше.
Доступ через теги
Мы можем пометить GameObjects или prefabs через инспектор, а затем использовать функции поиска игровых объектов, чтобы найти ссылки на них.
Доступ через преобразование
Доступ через SendMessage
Raycasting
Есть два сценария, в которых это может пригодиться (вероятно, их гораздо больше):
Обнаружение столкновений
Ранее мы упоминали компоненты Collider и Rigidbody, которые можно добавить к объекту. Правило для столкновений состоит в том, что один объект в столкновении должен иметь твердое тело, а другой — коллайдер (или оба имеют оба компонента). Обратите внимание, что при использовании raycasting лучи будут взаимодействовать только с объектами, к которым прикреплены компоненты коллайдера.
После настройки в любом настраиваемом компоненте, прикрепленном к объекту, мы можем использовать методы OnCollisionEnter, OnCollisionStay и OnCollisionExit для реагирования на коллизии. Получив информацию о столкновении, мы можем получить ответственность за GameObject и использовать то, что мы узнали ранее, для взаимодействия с прикрепленными к нему компонентами.
Следует отметить, что твердые тела обеспечивают физику, такую как гравитация, для объектов, поэтому, если вы хотите отключить это, вам нужно будет включить is_kinematic .
Расширенные возможности
Мы не будем вдаваться в подробности сейчас, но, возможно, в следующей статье — просто чтобы вы знали, что они существуют.
Создание графического интерфейса
Unity имеет полноценный движок пользовательского интерфейса для создания графического интерфейса для вашей игры. В целом эти компоненты работают примерно так же, как и остальная часть двигателя.
Расширение редактора Unity
Unity позволяет вам добавлять пользовательские кнопки к вашим инспекторам, чтобы вы могли влиять на мир в режиме редактирования. Например, чтобы помочь в построении мира, вы можете разработать собственное окно инструментов для строительства модульных домов.
Анимация
Unity имеет систему анимации на основе графиков, которая позволяет вам смешивать и управлять анимацией для различных объектов, таких как игроки, реализующие систему анимации на основе кости.
Материалы и PBR
Unity использует физический движок рендеринга, который обеспечивает освещение в реальном времени и реалистичные материалы. Реальность такова, что вам нужно либо сначала изучить 3D-моделирование, либо использовать модели, созданные и оптимизированные кем-то другим, прежде чем вы доберетесь до этого, чтобы создавать вещи, которые действительно хорошо выглядят.
Совет новичкам по Unity
Если вы планируете написать свою первую игру, не стоит недооценивать сложность и время, необходимое для написания даже самых тривиальных игр. Помните, что над большинством игр, которые выходят в Steam, команды работают над ними в течение многих лет!
Выберите простую концепцию и разбейте ее на небольшие достижимые этапы. Настоятельно рекомендуется разделить вашу игру на как можно более маленькие независимые компоненты, так как у вас гораздо меньше шансов столкнуться с ошибками, если вы сохраните компоненты простыми, а не монолитными блоками кода.
Прежде чем вы начнете писать какой-либо код для любой части вашей игры, поищите, что кто-то сделал раньше, чтобы решить ту же проблему — скорее всего, у них будет гораздо более удобное решение.
Хорошие ресурсы для разработки игр в Unity
Сообщество разработчиков игр — одно из лучших среди всех, и в индустрии есть множество высококвалифицированных профессионалов, которые размещают контент бесплатно или почти бесплатно. В этой области требуются 3D-моделисты, концептуальные художники, геймдизайнеры, программисты и так далее. Я связал несколько отличных общих ресурсов, с которыми я столкнулся, для каждого из этих полей ниже:
Игровой движок Unity стал невероятно популярным за последние несколько лет. Мы подготовили статью и видео, в ходе которых расскажем про базовые принципы построения игр на Unity.
Установка программ
Перед началом разработки необходимо скачать игровой движок Unity, а также текстовый редактор для написания кода. В качестве текстового редактора можно использовать любую программу, но зачастую используется программа Visual Sttudio.
Ссылки на программы:
Начало разработки
Разработка игры
Разработка каждой игры уникальна и нет единого общего шаблона. Каждый раз вам будет необходимо придумывать все новые и новые алгоритмы проектирования вашей игры. В ходе урока мы создавали 2D гонку и описали весь процесс создания игры в большом видео уроке. Посмотреть урок можно ниже:
Ссылки из урока:
Также вы можете скачать весь проект целиком по этой ссылке или же просто скачать основное изображения дороги что было использовано в уроке:
Больше интересных новостей
Гид по CMS MODX для новичков!
Чем отличаются языки программирования, сценариев и разметки?
Реальная история программиста, который никогда не изучал Си
Как удалить информацию о себе из Google
Это вторая часть туториала о 2Д игре платформере. Вам понадобятся некоторые игровые рессурсы для этого туториала. Скачайте .zip архив здесь. Также вы можете скачать первую часть туториала здесь. Запустите юнити проект с первой частью туториала и загрузите сцену scenePlatformer.
Как сделать стену:
Как собирать и подсчитывать монеты:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CoinController : MonoBehaviour
//звук сбора монеты
public AudioClip CoinSound;
//переменная количества собранных монет
public int coin;
//запустится если collider2D попал в триггер
void OnTriggerEnter2D ( Collider2D other) //проверка, имеет ли попавший объект тэг Coin
if (other.tag == "Coin" ) //увеличить счетчик монет
coin = coin + 1 ;
//проиграть звук поднятия монеты на позиции крысы
AudioSource .PlayClipAtPoint (CoinSound, transform.position);
//удалить монету из сцены
Destroy (other.gameObject);
>
>
>
Добавьте этот скрипт к крысе. Импортируйте звук CoinSound в проект. Выберите крысу в иерархии и поместите CoinSound в поле Coin Sound (чейчас мы используем 3Д позиционирование звука и он будет относительно тихим, так как восприятие звука находится на камере. Мы потом переделаем Audio Listener для более правильного звука).
Теперь сделаем простой интерфейс для отображения количества монет. Добавьте новый UI - Text. Будет созданно три новых объекта: Canvas, Text, EventSystem.
Выделите Canvas в иерархии. Измените UI Scale Mode на Scale With Screen Size и Screen Match Mode на Expand. С этими параметрами будет неплохое скалирование размера интерфейса на разных экранах.
Сцена и интерфейс теперь находятся в одном экране. Сделайте двойной клик на Canvas в иерархии. Камера сфокусируется на белом прямоугольнике. Этот прямоугольние представляет как будет выглядеть экран в игре.
Выберите Text в иерархии. Сделайте его больше и перетащите на то место, где он должен отображаться. Измените привязку на право-вверх. Измените Text на 0. Alignment на середину. Включите Best Fit (заполнение пространства). Измените Max Size на что-то около 100. Настройте Color по желанию.
Нам нужен скрипт для управления текстом. Откройте снова скрипт CoinController.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//эта библиотека нужна для работы с интерфейсом
using UnityEngine.UI;
public class CoinController : MonoBehaviour
//ссылка на объект с текстом
public GameObject TextObject;
//ссылка на текстовый компонент
Text textComponent;
//звук поднятия монеты
public AudioClip CoinSound;
//переменная подсчета монет
public int coin;
//запустится один раз при запуске скрипта
void Start () //делаем линк на текстовый компонент, который находится на текстовом объекте
textComponent = TextObject.GetComponent Text > ();
>
//запустится если collider2D попал в триггер
void OnTriggerEnter2D ( Collider2D other) //проверка, имеет-ли объект тэг Coin
if (other.tag == "Coin" ) //увеличить переменную подсчета монет
coin = coin + 1 ;
//записать в текст результат счета монет, преобразованный в текстовую переменную
textComponent.text = coin.ToString();
//проиграть звук поднятия монеты на позиции крысы
AudioSource .PlayClipAtPoint (CoinSound, transform.position);
//удалить монету из сцены
Destroy (other.gameObject);
>
>
>
Сфокусируйте камеру назад в сцену (сделайте двойной клик по крысе в иерархии). Выберите Rat в иерархии. У скрипта CoinController пояаилось новое поле Text Object. Поместите объект Text в это поле. Интерфейс теперь должен отображать значение переменной сбора монет. Запустите игру и проверьте это.
Как сделать яму:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//это библиотека для работы со сценами
using UnityEngine.SceneManagement;
public class DeadEndController : MonoBehaviour
//запустится если 2D collider попал в триггер
void OnTriggerEnter2D ( Collider2D other) //проверка, имеет ли объект тэг Player
if (other.tag == "Player" ) //ппосмотреть название текущей сцены и загрузить её (reload)
SceneManager .LoadScene ( SceneManager .GetActiveScene().name);
>
>
>
Выберите DeadEnd в иерархии и добавьте этот скрипт. Создайте префаб DeadEnd (перетащите DeadEnd из иерархии в Assets.)
Как сделать простого врага:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//библиотека для управления сценами
using UnityEngine.SceneManagement;
public class MushroomController : MonoBehaviour
//как далеко гриб может отойти от начальной точки
public float distanceToRun;
//скорость движения
public float speed;
//направление взгляда гриба
public bool isLookingLeft = true ;
//стартовая позиция
Vector3 startPos;
//линк на компонент Rigidbody2D
Rigidbody2D rb;
//выполнится 1 раз при старте игры
void Start () //делаем линк на Rigidbody2D компонент
rb = GetComponent Rigidbody2D > ();
//запоминаем стартовую точку гриба
startPos = transform.position;
//будем сравнивать квадрат вектора расстояния с квадратом расстояния
//так как извлечение корня медленный процесс
distanceToRun = distanceToRun * distanceToRun;
>
//выполняется на каждом фиксированном интервале
void FixedUpdate () //проверить, смотрит-ли гриб влево
if (isLookingLeft) //посчитать вектор направления от стартовой точки к грибу
Vector2 dist = transform.position - startPos;
//проверить, что гриб слева от стартовой точки
//и расстояние между грибом и стартовой точкой больше разрешенного удаления
if (transform.position.x distanceToRun) //вызвать функцию поворота гриба
TurnTheMushroom ();
//начать движение направо
rb.velocity = new Vector2 (speed, rb.velocity.y);
//если проверка была негативной
> else //продолжить движение влево
rb.velocity = new Vector2 (-speed, rb.velocity.y);
>
>
//проверить, что гриб смотрит вправо
if (!isLookingLeft) //посчитать вектор направления от стартовой точки к грибу
Vector2 dist = transform.position - startPos;
//проверить, что гриб справа от стартовой точки
///и расстояние между грибом и стартовой точкой больше разрешенного удаления
if (transform.position.x > startPos.x && dist.sqrMagnitude > distanceToRun) //вызвать функцию поворота гриба
TurnTheMushroom ();
//начать движение налево
rb.velocity = new Vector2 (-speed, rb.velocity.y);
//если проверка была негативной
> else //продолжить движение направо
rb.velocity = new Vector2 (speed, rb.velocity.y);
>
>
>
//функция поворота гриба
void TurnTheMushroom ()
//инвертировать (изменить на противоположный) указатель направления взгляда
isLookingLeft = !isLookingLeft;
//повернуть гриб
transform.localScale = new Vector3 (transform.localScale.x * -1 , transform.localScale.y, transform.localScale.z);
>
//запустится, если коллайдер коснулся другого коллайдера
void OnCollisionEnter2D ( Collision2D other) //проверить, что у коллайдера тэг Player
if (other.collider.gameObject.tag == "Player" ) //посмотреть имя загруженной сцены и загрузить такую сцену (reload)
SceneManager .LoadScene ( SceneManager .GetActiveScene().name);
>
>
//запустится, если другой коллайдер попал в триггер
void OnTriggerEnter2D ( Collider2D other) //проверить, что у коллайдера тэг Player
if (other.tag == "Player" ) //удалить гриб
Destroy (gameObject);
>
>
>
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ExplosionsDestroyer : MonoBehaviour
//как долго взрыв будет в сцене
public float timeToDestroy;
//выполнится один раз при старте скрипта
void Start () //удалить взрыв из сцены
Destroy (gameObject, timeToDestroy);
>
>
Выберите Explosion в иерархии. Добавьте этот скрипт к Explosion. Измените Time To Destroy на 1. Создайте префаб Explosion. После создания префаба удалите взрыв из сцены (правый клик на Explosion в иерархии и нажать Delete).
Теперь добавим взрыв и его звук к скрипту гриба. Откройте скрипт MushroomController.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//библиотека для управления сценами
using UnityEngine.SceneManagement;
public class MushroomController : MonoBehaviour
//префаб взрыва
public GameObject Explosion;
//звук взрыва
public AudioClip Boom;
//как далеко гриб может отойти от начальной точки
public float distanceToRun;
//скорость движения гриба
public float speed;
//направление взгляда гриба
public bool isLookingLeft = true ;
//стартовая позиция гриба
Vector3 startPos;
//линк на компонент Rigidbody2D
Rigidbody2D rb;
//выполнится один раз при старте гриба
void Start () //делаем линк на компонент Rigidbody2D
rb = GetComponent Rigidbody2D > ();
//запоминаем стартовую позицию гриба
startPos = transform.position;
//будем сравнивать квадрат вектора расстояния с квадратом расстояния
//так как извлечение корня медленный процесс
distanceToRun = distanceToRun * distanceToRun;
>
//выполняется на каждом фиксированном интервале
void FixedUpdate () //проверить, что гриб смотрит налево
if (isLookingLeft) //посчитать вектор направления от стартовой точки к грибу
Vector2 dist = transform.position - startPos;
//проверить, что гриб слева от стартовой точки
//и расстояние между грибом и стартовой точкой больше разрешенного удаления
if (transform.position.x distanceToRun) //вызвать функцию поворота
TurnTheMushroom ();
//начать движение направо
rb.velocity = new Vector2 (speed, rb.velocity.y);
//если проверка была отрицательной
> else //продолжить движение налево
rb.velocity = new Vector2 (-speed, rb.velocity.y);
>
>
//проверить, что гриб смотрит направо
if (!isLookingLeft) //посчитать вектор направления от стартовой точки к грибу
Vector2 dist = transform.position - startPos;
//проверить, что гриб справа от стартовой точки
//и расстояние между грибом и стартовой точкой больше разрешенного удаления
if (transform.position.x > startPos.x && dist.sqrMagnitude > distanceToRun) //вызвать функцию поворота
TurnTheMushroom ();
//начать движение налево
rb.velocity = new Vector2 (-speed, rb.velocity.y);
//если проверка была отрицательной
> else //продолжить движение направо
rb.velocity = new Vector2 (speed, rb.velocity.y);
>
>
>
//функция поворота гриба
void TurnTheMushroom ()
//изменить указатель направления взгляда на противоположный
isLookingLeft = !isLookingLeft;
//повернуть гриб
transform.localScale = new Vector3 (transform.localScale.x * -1 , transform.localScale.y, transform.localScale.z);
>
///запустится, если коллайдер коснулся другого коллайдера
void OnCollisionEnter2D ( Collision2D other) //проверить, что у коллайдера тэг Player
if (other.collider.gameObject.tag == "Player" ) //посмотреть имя загруженной сцены и загрузить такую сцену (reload)
SceneManager .LoadScene ( SceneManager .GetActiveScene().name);
>
>
//запустится, если другой коллайдер попал в триггер
void OnTriggerEnter2D ( Collider2D other) //проверить, что у коллайдера тэг Player
if (other.tag == "Player" ) //спавн взрыва
Instantiate (Explosion, transform.position, Quaternion .identity);
//проиграть звук взрыва
AudioSource .PlayClipAtPoint (Boom, transform.position);
//удалить гриб
Destroy (gameObject);
>
>
>
Импортируйте звуковой файл Boom в Assets. Выберите Enemy в иерархии. У Mushroom Controller появилось два новых поля в скрипте. Поместите префаб Explosion в Explosion поле. Поместите аудиофайл Boom в поле Boom. Сделайт префаб Enemy. проверьте сцену.
Восприятие звука:
По стандарту, Audio Listener (компонент отвественный за восприятие звука) прикреплен к Main Camera. Audio Listener можно представить как виртуальные уши. Смотрите Unity Documentation для подробностей. Надо передвинуть этот компонент к крысе. Выберите Main Camera (дочерний объект крысы) ит отключите Audio Listener в Inspector (нам нужен только один такой компонент в сцене).
Выьерите Rat в иерархии и добавьте Audio Listener к ней.
Проверьте сцену.
Как сделать движущуюся платформу:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlatformMoving : MonoBehaviour
//скорость движения платформы
public float speed;
//позиция, где платформа должна повернуть назад
public Transform endPoint;
//позиция начала движения
Vector3 startPoint;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;
//скорость платформы в текущий момент
float currentSpeed;
//выполнится при запуске скрипта
void Start () //запомнит стартовую точку платформы
startPoint = transform.position;
//сделать ссыдку на Rigidbody2D
rb = GetComponent Rigidbody2D > ();
//начальное направление движения
currentSpeed = speed;
>
Создайте новый пустой объект (empty).
Назовите его endPoint. Добавьте к нему иконку для лучшего вида. Поместите endPoint над Platform (испольуйте инструмент движения).
Выберите Platform в иерархии. Добавьте скрипт PlatformMoving. Измените Speed на 1. Поместите endPoint в поле End Point.
Запустите игру и проверьте (можете переключить на сцену, пока игра запущена).
Поместите wall в сцену справа от платформы. Выьерите эту стену в иерархии и добавьте Box Collider 2D.
Поместите следующий Dead End префаб в сцену под двигающейся платформой. Нажмите на Edit Collider и настройте размер.
Как добавить физические объекты:
Импортируйте картинку Box из скачанного архива. Поместите спрайт Box в сцену (на движущуюся платформу). Выьерите Box в иерархии. Измените Tag и Layer на Ground. Смените Z-позицию на 0. Добавьте Rigidbody 2D. Измените Interpolate на Interpolate. Добавьте Box Collider 2D.
Теперь сможете взаимодействовать с этим объектом.
Конец уровня:
Добавьте Ground префаб в сцену, где платформа перестаёт двигаться наверх (смотрите скриншот). Добавьте последнбб стену (поместите спрайт wall в сцену и добавьте Box Collider 2D ).
Импортируйте картинку Exit в Assets. Добавьте спрайт Exit в сцену возле последней стены. Крыса не должна допрыгивать до Exit, если она просто прыгает с пола. Boxпонадобится как подставка. Выберите Exit в иерархии. Добавьте Box Collider 2D. Включите Is Trigger. Добавьте Dead End Controller. У нас сейчас нет следуюшего уровня, поэтому просто перезагрузим сцену.
Как сделать движущийся фон с эффектом параллакс:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Parallax : MonoBehaviour
//ссылочная переменная на игрока
GameObject player;
//позиция игрока в предыдущем кадре
//и разница в позиции между кадрами
Vector3 lastPos, offset;
//скорость движения фона
public float speed;
//выполнится один раз при запуске скрипта
void Start () //делаем линк на игрока
player = GameObject .FindWithTag ( "Player" );
//запоминаем его позицию
lastPos = player.transform.position;
>
//выполняется каждый кадр
void Update () //посчитать разницу в позициях между кадрами
offset = player.transform.position - lastPos;
//пересчитать разницу в зависимости от скорости и передвинуть фон по полученному вектору
//Time.deltaTime корректировка для разного фпс
transform.Translate (offset * speed * Time .deltaTime);
//перезаписать позицию в текущем кадре
lastPos = player.transform.position;
>
>
Импортируйте BackGround в Assets. Поместите BackGround в сцену. Измените X и Y Scale на 4. Передвиньте на позицию крысы (смотрите скриншот). Измените Order in Layer на -100. Добавьте Parallaxскрипт. Измените Speed на 60 (потестите разные настройки).
Как добавить фоновую музыку:
Теперь простое. Импортируйте звуковой файл Music. Выберите Rat в иерархии. Перетащите Music на Rat ы иерархии (или добавьте Audio Source и поместите Music в поле AudioClip field). Включите Loop.
Проверьте сцену.
Читайте также: