Архитектура простой 2D игры на Unity3D. План, факт и работа над ошибками / Хабр

Запуск игры

Далее рассмотрим диаграмму последовательности, иллюстрирующую действия при запуске игры. Точка начала — загрузка сцены с игрой.

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

Первыми срабатывают события Awake для объектов Player (загрузка всех настроек, аналогично старту приложения) и Snake (метод Init() — инициализиция хвоста “по умолчанию” из двух сегментов). Потом срабатывает событие Start для выбора контроллера (для примера использован FourButtonController), загрузки GUI и инициализации игры. Чуть подробнее об обработке этого события:

  1. Controller selector в событии Start, проверяет настройки игрока и подгружает нужный контроллер управления.
  2. GUInavigator в методе initGame инициирует все необходимые в данной сцене интерфейсы, каждому проставляя признак неактивности. Определение, какой метод вызвать, прроисходит на основе параметра, заданного через редактор. Инициализация и включение активного интерфейса происходят аналогично запуску приложения.
  3. Далее событие Start обрабатывает объект party. Первым делом он проверяет, нет ли сохраненной игры.
    1. Если игра есть, то party вызывает dataProvider для восстановления, который, прочитав данные вызывает метод Restorebackup объекта party.
    2. Он, в свою очередь вызывает аналогичный метод объекта Snake, а тот по цепочке для всех звеньев.
    3. После восстановления данных, управление возвращается объекту party, он включает паузу и ждет действий игрока.

  4. Если же игры не было, то party вызывает фабрику фруктов для создания экземпляра и игра началась. Кстати, на диаграмме показано, что party отвечает и за установку ряда параметров для фрукта — сейчас это уже не так: все необходимые действия инкапсулированы либо в фабрику, либо в экземпляр фрукта.

Игровой цикл: движение змеи

Игровая логика сосредоточена вокруг обработки двух событий: update обрабатывается в змейке методом movehead, здесь происходит движение змеи и управление движением ее сегментов; и ontriggerenter, где происходит обработка столкновений головы змеи с фруктами, стенами и собственным хвостом.

Разберем событие столкновения подробнее:

  1. При возникновении события сначала проверяется, с кем мы столкнулись: если это яблоко, то вызывается метод Eatfruit, а если хвост или стена, то Killme. В обоих случаях информация о столкновении сбрасывается в логи.
  2. Случай яблока:
    1. Змейка выставляет флаг необходимости добавления звена и вызывает метод Eatfruit объекта party.
    2. Party увеличивает рейтинг партии и вызывает свой же метод createfruit, использованный также при запуске игры.
    3. В этом методе сначала удаляется текущий экземпляр фрукта, а затем создается новый через обращение к фабрике.

  3. Случай стены или хвоста:
    1. Змейка передает обработку события объекту party в метод Endgame.
    2. Party выставляет режим паузы и, через навигатор интерфейса, переводит игрока на экран с результатами партии.


Движение же змейки реализовано следующим образом:

  1. В событии update вызывается метод movehead
  2. Здесь проверяется скорость змейки: наступил момент перехода или нет
  3. Если да, то проверяется флаг необходимости добавления звена
    1. Если нужно, то создается звено, аналогичное следующему за головой
    2. Смещаются только голова и одно вновь созданное звено.

  4. Если флага нет, то смещается голова, а за ней по цепочке все звенья, методом adjust.

Изучение интерфейса

Когда ваш проект загрузится, появится экран, заполненный информацией. 

Ваш макет, вероятно, будет выглядеть так:

Если нет, нажмите кнопку «Макет» в правом верхнем углу и выберите 2 на 3 в раскрывающемся меню.

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

Вот как выглядит интерфейс, разбитый на отдельные представления:

Чтобы просмотреть список всех представлений, щелкните параметр «Окно» в строке меню.

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

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

В редакторе найдите вкладку «Игра» и щелкните ее правой кнопкой мыши . В раскрывающемся меню выберите «Добавить вкладку», затем выберите «Профиль».

Представление Profiler позволяет анализировать вашу игру во время ее работы. К сожалению, профилировщик также блокирует просмотр игры, поэтому вы не сможете играть в игру, пока вы ее профилируете — не очень полезно.

Нажмите и удерживайте на вкладку Профили и перетащите его на вкладке Сцена выше.

Как видите, виды можно перемещать, закреплять и упорядочивать. Они также могут существовать вне редактора в виде плавающих окон.

Чтобы сохранить макет, выберите «Окно Макеты Сохранить макет…» и назовите его «Отладка».

Всякий раз, когда вам нужно получить доступ к этому конкретному макету, вы можете нажать кнопку «Макет» и выбрать «Отладка».

При нажатии вы увидите список всех ваших макетов.

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

Курсовая работа найти игра в программе unity 3d

  • Обзор подходов к разработке музейных приложений с элементами дополненной реальности, формирование требований к ним. Выбор методов разработки приложения, разработка пользовательского интерфейса. Принципы тестирования. Реализация раздела «Распознавание».

    дипломная работа, добавлен 03.07.2021

  • Анализ целевой аудитории. Функциональные характеристики пользовательского приложения. Разработка алгоритмов и интерфейса программного продукта, функций рабочей области. Написание скриптов на языке C#. Тестирование программы методом чёрного ящика.

    дипломная работа, добавлен 09.11.2021

  • Общее описание разрабатываемого приложения, его актуальность и сферы практического применения. Выбор среды разработки и языка программирования, 3D-движка. Архитектура приложения, интерфейса и его главных элементов, взаимодействие с пользователем.

    дипломная работа, добавлен 10.07.2021

  • Анализ моделируемого приложения и постановка задачи. Диаграмма прецедентов, деятельности объектов и состояния классов. Разработка приложения-игры, выбор языка программирования и среды для разработки проекта, интерфейс приложения и ресурсы проекта.

    курсовая работа, добавлен 14.10.2021

  • Изучение информационной базы клиента «Управление торговлей». Выбор и изучение платформы для построения сайта. Выбор технологии и среды разработки. Разработка основных алгоритмов решения задач и хранения данных. Проектирование интерфейса пользователя.

    дипломная работа, добавлен 20.05.2021

  • Рассмотрение игр, схожих по жанру и модели распространения с разрабатываемым приложением. Выбор среды разработки и сторонних библиотек. Проектирование интерфейса и подготовка графических материалов приложения. Особенности введения в игру микротрансакций.

    дипломная работа, добавлен 18.11.2021

  • Изучение существующих подходов к использованию компьютерных игр в образовательном процессе. Разработка и реализация проекта игрового обучающего приложения на мобильной платформе. Выбор платформы и средств реализации игрового обучающего приложения.

    дипломная работа, добавлен 12.08.2021

  • Анализ программных продуктов для реализации обучающего курса по программе AutoCAD для строительных специальностей. Системные требования, необходимые для работы приложения. Создание интерфейса приложения. Написание, запись и монтаж сценария видеоуроков.

    дипломная работа, добавлен 19.06.2021

  • Создание, изучение и разработка приложение на Android. Среда разработки приложения DelphiXE5. Установка и настройка среды программирования. Этапы разработки приложения. Инструменты для упрощения конструирования графического интерфейса пользователя.

    курсовая работа, добавлен 19.04.2021

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

    дипломная работа, добавлен 22.03.2021

  • Обзор созданных классов

    На диаграмме ниже представлены все классы, созданные при разработке игры. На диаграмме скрыта часть методов, не несущих смысловой нагрузки или настолько тривиальных, что не стоят упоминания. Также часто под именем переменной (например, textures) скрывается целый блок переменных (в данном случае — разнообразных текстур).

    Все имеющиеся классы разделены по четырем пакетам:

    • Gamelogic — здесь представлены классы для игровых объектов, существующих на ирговом поле. По сути, этот паявляется ядром игры.
    • Gui — здесь представлены классы, отвечающие за построение статического пользовательского интерфейса: главное меню, настройки, рекорды и кнопки поверх игрового поля, кроме кнопок непосредственного управления змейкой.
    • Controllers — это изюминка нашего приложения: пакет с разнообразными способами управления змейкой. Каждый класс полностью содержит в себе все необходимое для выбранного стиля управления: от интерфейсных кнопок до логики расчета поворота.
    • Providers — этот пакет содержит вспомогательные классы, обеспечивающие такие функции, как чтение и сохранение данных, возможности поделиться рекордом, логирование, аналитику и т.п.

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

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

    Второй по важности класс Snake содержит логику движения змеи, включая управление зависимыми объектами класса Snakechain. Именно этому классу передают команды контроллеры управления.

    Для создания экземпляров фруктов (FruitInstance) используется фабрика, т.к. в будущем планируется увеличивать количество разных типов фруктов.

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

    Пакет с контроллерами содержит управляющие классы. Они добавляются к змейке и взаимодействуют напрямую с объектом Snake, используя паттерн command, а змейка выполняет поступившие команды в той же последовательности, но раздельно по своим шагам. Это было сделано для корректной обработки быстрых последовательных команд, например для разворота на 180 градусов вдоль своего хвоста.

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

    Организация активов

    Новички в Unity могут представить, что вы разрабатываете свою игру от начала до конца в Unity, включая написание кода, создание 3D-моделей и текстур и т. д.

    На самом деле, лучше думать о Unity как об инструменте интеграции. Обычно вы пишете код или создаете 3D-модели или текстуры в отдельной программе и используете Unity, чтобы связать все вместе.

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

    Представление, в котором вы импортируете и упорядочиваете активы, называется обозревателем проекта. Он имитирует организацию вашей файловой системы.

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

    В Диспетчере проектов выберите папку Assets и нажмите кнопку Create. В раскрывающемся меню выберите «Папка» и назовите ее «Модели». Это будет дом для всех ваших моделей. У вас может возникнуть соблазн создать папки и манипулировать файлами в файловой системе вместо обозревателя проекта. Не делайте этого!

    Unity создает метаданные для каждого актива. Создание, изменение или удаление ресурсов в файловой системе может нарушить эти метаданные и вашу игру.

    Создайте следующие папки: Animations, Materials, Prefabs, Presets, Scripts и Textures.

    Ваш обозреватель проекта должен выглядеть так:

    Лично я считаю, что большие значки папок отвлекают. Если у вас также есть предпочтение, вы можете увеличить или уменьшить размер с помощью ползунка в нижней части Диспетчера проектов.

    Примечание. Все снимки экрана в этом руководстве с этого момента будут отображать самые маленькие настройки.

    Наконец, вы можете изменить название актива. Например, ваша текущая сцена называется SampleScene. Выберите папку Scenes, а затем выберите файл SampleScene. Имя будет выделено. Один раз щелкните по нему еще раз, и вы напишете новое имя. Измените его на Main.

    Вы можете сделать это с любой папкой или активом в Диспетчере проектов.

    Этап 1. концепция

    Первый, концептуальный, вариант архитектуры создавался нами ещё до выбора unity. Он приведен на картинке ниже. В этом варианте мы выделили слои будущего приложения:

    Архитектура простой 2D игры на Unity3D. План, факт и работа над ошибками / Хабр

    Исторически последним был выделен слой инициализации, хотя в приложении он должен был запускаться первым. Дело в том, что мы сначала заложили инициализацию объектов в сами объекты, но потом решили выделить ее централизованно.Слои интерфейса, логики и контроллеров представляют собой почти классической паттерн MVC.

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

    Хорошие идеи:

    Промахи:

    Следующим этапом стал выбор платформы, хотя, строго говоря, выбор делался между unity и разработкой на чистой java. Беглый обзор других существующих движков не вызвал энтузиазма в их изучении. Мы пришли к достаточно ожидаемому выводу: написать змейку проще вообще без платформы, к тому же это выглядело интереснее — кто ж не любит делать свои велосипеды?

    Однако, мы выбрали unity, с целью ознакомления с платформой, близкой к статусу стандарта де-факто в области гейм-дева. Да, мы получили солидный оверхед из-за того, что unity — трёхмерный движок (на момент начала разработки у unity еще не было нативной поддержки 2D), а делали мы двумерную игру, но полученный опыт того стоил.

    Этап 2. проект

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

    Эта архитектура состояла из нескольких связанных диаграмм, которые я ниже называю терминами uml, хотя, конечно, стандарту они следуют, мягко говоря, не полностью.

    Сущность-связь (понятно, что это скорее относится к разряду требований к системе, чем к её архитектуре, но в контексте статьи я не могу её не упомянуть:

    Нотация ERD, думаю, всем знакома. На ней представлены все объекты игровой логики и логические связи между ними. Каждый такой объект порождает один класс, обеспечивающий работу этого объекта.

    Диаграммы компонентов и кооперации. Для их восприятия предварительно опишу ряд договоренностей:

    Общая архитектура — носит общий концептуальный характер, являясь, по сути, продолжением диаграммы этапа 1. На ней отображены:

    Детализирующие диаграммы содержат:

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

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

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

    Отдельно выделены компоненты для логирования и расшаривания рекордов.

    Игровой мир состоит из объектов, взятых с ERD. Ключевую роль играют партия и змейка.

    Партия хранит ссылки на змейку и текущий экземпляр фрукта, обеспечивает инициализацию игровых объектов и их взаимодействие.Змейка обрабатывает основные игровые события: собственное движение, поедание фрукта и столкновения со стенами или хвостом.Экземпляр фрукта отвечает за контроль собственного времени жизни.

    Хорошие идеи:

    Промахи:

    Этап-3.1: под капотом

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

    Этапу-4: визуальный дизайн

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

    На первом шаге мы формируем базовое понимание облика будущей игры, а так как по задумке наша игра создается в изометрическом стиле, первое что нам необходимо проделать, это настроить камеру. Тут мы подходим к одной из ключевой особенности Unity. Дело в том, что можно долго экспериментировать с параметрами настройки камеры, подбирая нужные значения… Но проще просто выставить понравившийся ракурс с помощью панели View, а затем активировать GameObject -> Align With View, после чего ваша камера тотчас же примет необходимые значения. Вот такой вот shortcut от создателей Unity.

    Итак, сцена готова, но как придать персонажу движение? Для начала, произведем некоторые манипуляции с объектом Sphere, добавив в него такие компоненты как Rigidbody и только что созданный скрипт sphereBehavior. Не забудьте отключить галочку Use Gravity, так как на данном этапе он нам не понадобится.

    Если вкратце, то компонент Rigidbody позволяет объекту ощутить на себе все прелести физического мира, таких как масса, гравитация, сила тяжести, ускорение и.т.д. Вот почему для нас он так важен! А теперь, чтобы заставить тело двигаться в нужном нам направлении, нам всего лишь нужно слегка изменить параметр velocity, но делать это мы будем при помощи кода. Давайте заставим сферу двигаться по оси Х, для этого внесём изменения в скрипт sphereBehavior:

    using UnityEngine;
    using System.Collections;
    
    public class sphereBehavior : MonoBehaviour {
    
       private Rigidbody rb; // Объявление новой переменной Rigidbody
       private float speed = 5f; // Скорость движения объекта
       
       void Start() {
          rb = GetComponent<Rigidbody> (); // Получение доступа к Rigidbody
       }
       void Update() {
          rb.velocity = new Vector3 (speed, 0f,0f);
       }
    
    }

    В Unity, тела описывают своё положение и направление, посредством специальных векторов, хранящих значения по осям x, y и z. Изменяя эти значения, мы добиваемся необходимого нам направления или положения конкретного тела. Строка

    rb.velocity = new Vector3(speed, 0f,0f)

    задает новое направление телу по оси X, тем самым придавая нашей сфере нужное нам направление.

    Если вы сделали всё в точности, как и я, то ваша сфера отправится в бесконечное путешествие по оси X, со скоростью speed.

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

    using UnityEngine;
    using System.Collections;
    
    public class sphereBehavior : MonoBehaviour {
    
       private Rigidbody rb; // Объявление новой переменной Rigidbody
       private bool isMovingRight = true; // переменная, отражающая условное направление объекта
       private float speed = 5f; // Скорость движения объекта
    
       void Start() {
          rb = GetComponent<Rigidbody> (); // Получение доступа к Rigidbody
       }
    
       void changeDirection() {
          if (isMovingRight) {
             isMovingRight = false;
          } else {
             isMovingRight = true;
          }
       }
    
       void Update() {
    
          if(Input.GetMouseButtonDown(0)) {
             changeDirection();
          }
    
          if (isMovingRight) {
             rb.velocity = new Vector3 (speed, 0f, 0f);
          } else {
             rb.velocity = new Vector3 (0f, 0f, speed);
          }
    
       }
    
    }

    Условимся, что когда сфера движется по оси X, то это движение называется движением «вправо», а по оси Z – «влево». Таким образом мы легко можем описать направление нашего тела специальной булевой переменной isMovingRight.

    if(Input.GetMouseButtonDown(0)) {
       changeDirection();
    }

    Этот кусочек кода отслеживает нажатие левой клавиши мыши, и если данная клавиша все же была нажата, запускает функцию

    changeDirection()

    , с простой логикой: если на момент нажатия левой клавиши мыши, переменная isMovingRight имела значение true, то теперь она стала false и наоборот. Напомню, что булевая переменная позволяет нам ответить на один простой вопрос: истинно ли утверждение о том, что тело движется по оси X, или нет?

    Альтернативно, функцию changeDirection() можно записать в одну строку:

    void changeDirection() {
          isMovingRight = !isMovingRight;
    }

    И последнее, что необходимо сделать, это переписать метод направления движения с учетом переменной isMovingRight:

    if (isMovingRight) {
       rb.velocity = new Vector3 (speed, 0f, 0f);
    } else {
       rb.velocity = new Vector3 (0f, 0f, speed);
    }

    Если isMovingRight имеет значение true (если сфера действительно движется вправо), тогда значение velocity принимает новый вектор направления rb.velocity = new Vector3 (speed, 0f, 0f); Если isMovingRight имеет значение false, значит тело более не движется вправо, а значит пришло время изменить вектор направления на rb.velocity = new Vector3 (0f, 0f, speed);

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

    Круто? Конечно нет! Ведь сфера движется, а мы стоим на месте. Давайте доработаем игру так, чтобы мы могли двигаться вместе со сферой и не упускали её из виду. Для этого нам нужно создать скрипт cameraFollow и прикрепить его к объекту Main Camera:

    А вот код скрипта cameraFollow:

    using UnityEngine;
    using System.Collections;
    
    public class cameraFollow : MonoBehaviour {
    
    public GameObject player;
    public Vector3 offset;
    
       void Start () {
          offset = transform.position - player.transform.position;
       }
    	
       void Update () {
          transform.position = player.transform.position   offset;
       }
    
    }

    Как же осуществить слежение за объектом? Для начала нам нужно рассчитать разницу смещения между объектами Camera и Sphere. Для этого достаточно вычесть от позиции камеры, координаты сферы, а полученную разницу сохранить в переменной offset. Но прежде, необходимо получить доступ к координатам сферы.

    Для этого нам необходима переменная player, представляющая собой простой GameObject. Так как наша сфера находится в постоянном движении, мы должны синхронизировать координаты камеры с координатами сферы, приплюсовав полученное ранее смещение. Осталось только указать в поле player наш объект слежения, и можно смело любоваться результатом.

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

    Если в вашем списке нет тэга Ground, то его необходимо создать во вкладке Add Tag…

    Следующее, что нам предстоит совершить, это создать в корне проекта специальную папку с названием Prefabs, и перетащить в нее наш Cube, прямо из инспектора. Если после этого, имя объекта Cube стало синего цвета, значит вы все сделали правильно.

    Префабы – это особый тип объектов, позволяющий хранить GameObject, а также все его значения и свойства в одном месте. Префабы позволяют создавать бесконечное множество объекта, а любое его изменение немедленно отражаются на всех его копиях. Иными словами, теперь мы можем вызывать участок пути Cube, прямо из папки Prefabs, столько раз, сколько необходимо.

    Теперь давайте создадим пустой GameObject, (щелчок правой кнопки мыши по Hierarchy) переименуем его в RoadContainer и прикрепим к нему только что созданный скрипт roadBehavior:

    А вот и сам код roadBehavior:

    using UnityEngine;
    using System.Collections;
    
    public class roadBehavior : MonoBehaviour {
    
       public GameObject road; // Префаб участка пути
       private Vector3 lastpos = new Vector3 (0f,0f,0f); // Координаты установленного префаба
    
       void Start() {
    
          for(int i=0; i<10; i  ) {
             GameObject _platform = Instantiate (road) as GameObject;
             _platform.transform.position = lastpos   new Vector3 (1f,0f,0f);
             lastpos = _platform.transform.position;
          }
    
       }
    
    }

    Что же тут на самом деле происходит? Как видите, у нас есть переменная, которая позже, вручную будет привязана к нашему префабу Cube, и есть объект Vector3, хранящий координаты последнего установленного префаба (сейчас значения равны нулю).

    for(int i=0; i<10; i  ) {
       GameObject _platform = Instantiate (road) as GameObject;
       _platform.transform.position = lastpos   new Vector3 (1f,0f,0f);
       lastpos = _platform.transform.position;
    }

    Этот участок кода выполняет следующее: до тех пор, пока i < 10, мы будем брать префаб, устанавливать его позицию с учетом последней позиции lastpos позиция с учетом смещения по X, сохранять последнюю позицию. То есть в результате, мы получим 10 префабов Cube установленных в точности друг за другом. Перед проверкой, не забываем назначить переменной road наш объект Cube из папки Prefabs:

    Ок, но что делать дальше? А дальше нам нужно продолжить установку блоков в произвольном порядке. Для этого нам понадобится генератор псевдослучайных чисел random. Подправим скрипт roadBehavior с учетом нововведений:

    using UnityEngine;
    using System.Collections;
    
    public class roadBehavior : MonoBehaviour {
    
       public GameObject road; // Префаб участка пути
       private Vector3 lastpos = new Vector3 (0f,0f,0f); // Координаты установленного префаба
    
       void Start() {
    
          for(int i=0; i<10; i  ) {
             GameObject _platform = Instantiate (road) as GameObject;
             _platform.transform.position = lastpos   new Vector3 (1f,0f,0f);
             lastpos = _platform.transform.position;
          }
    
          InvokeRepeating ("SpawnPlatform", 1f, 0.2f);
    
       }
    
       void SpawnPlatform() {
    
          int random = Random.Range (0, 2);
          if (random == 0) { // Установить префаб по оси X
             GameObject _platform = Instantiate (road) as GameObject;
             _platform.transform.position = lastpos   new Vector3 (1f,0f,0f);
             lastpos = _platform.transform.position;
          } else { // Установить префаб по оси Z
             GameObject _platform = Instantiate (road) as GameObject;
             _platform.transform.position = lastpos   new Vector3 (0f,0f,1f);
             lastpos = _platform.transform.position;
          }
    
       }
    
    }

    Строчка

    InvokeRepeating («SpawnPlatform», 1f, 0.2f)

    предназначена для активации функции

    SpawnPlatform()

    спустя 1 секунду после начала игры, и повторного её вызова каждые 0.2 секунды. Что касается самой функции, то тут, как говорится все проще пареной репы! Каждые 0.2 секунды, система загадывает случайное число между цифрами от 0 до 1. Если система загадала 0 – мы устанавливаем новый префаб по оси X, а если 1 – то по оси Z. Вот и вся магия!

    И наконец, давайте заставим сферу падать каждый раз, когда она сходит с дистанции. Для этого создадим новый скрипт playerFalls и прикрепим его к нашему объекту Sphere:

    А вот и сам код скрипта playerFalls:

    using UnityEngine;
    using System.Collections;
    
    public class playerFalls : MonoBehaviour {
    
       private Rigidbody rb;
    
       void Start() {
    
          rb = GetComponent<Rigidbody> ();
    
       }
    
       void Update() {
    
          RaycastHit hit;
          if(Physics.Raycast (transform.position, Vector3.down, out hit, 5f) && hit.transform.gameObject.tag == "Ground") {
             rb.useGravity = false;
          } else {
             rb.useGravity = true;
          }
    
       }
    
    }

    Raycast – специальный луч на подобии лазера, который излучается по направлению к сцене. В случае, если луч отражается от объекта, он возвращает информацию об объекте, с которым столкнулся. И это очень круто, потому что именно так, посредством такого луча, направленного из центра сферы вниз, мы будем проверять, находимся ли мы на платформе Cube или нет (проверяем, имеет ли объект тэг «Ground»).

    Рефераты:  Реферат: Пожарная безопасность -
    Оцените статью
    Реферат Зона
    Добавить комментарий