Разработка игры Monkey Ball с помощью Unity...
Введение
В этом уроке вы узнаете, как создать мобильную 3D-игру с использованием C # и Unity. Цель игры - использоватьакселерометр для перемещения мяча и достижение портала.
В этом уроке вы узнаетео следующих аспектах разработки игры на Unity:
- 3D-Примитивы
- управлениеакселерометром
- движение камеры
- физика
- Текстуры графическогоинтерфейса пользователя
1. Создание нового проекта в Unity
Откройте Unity и выберите New Project в менюFile, чтобы открыть новый диалог проекта. Сообщите Unity, где вы хотите сохранить проект,и установите Set up defaults: меню в 3D.
2. Настройки сборки
На следующем этапе вам будет представленпользовательский интерфейс Unity. Задайте проект дляразработки мобильных устройств, выбрав Build Settings в меню File и выбрав свою платформу.
3. Устройства
Первое, что нам нужно сделать после выборацелевой платформы, - это выбрать размер полотна, которое мы будем использоватьв игре. Это поможет нам выбрать подходящий размер для3D-текстур и 2D-графического интерфейса, не создавая иллюстрацию полотна илииспользуя текстуры, которые слишком велики для целевого устройства. Например, изображениедолжно иметь более высокое разрешение, если вы нацелены на iPad с экраном retina, а не на Lumia 520.
iOS
- iPad без Retina: 1024px x 768px
- iPad с Retina: 2048px x 1536px
- 3.5-дюймовый iPhone/iPod Touch без Retina: 320px x 480px
- 3.5-дюймовый iPhone/iPod с Retina: 960 x x 640px
- 4-дюймовый iPhone/iPod Touch: 1136px x 640px
Android
Поскольку Android является открытой платформой,существует широкий спектр устройств, разрешение экрана и плотность пикселей. Ниже перечисленынекоторые из наиболее распространенных.
- ASUS Nexus 7 Tablet: 800px x 1280px, 216 ppi
- Motorola Droid X: 854px x 480px, 228 ppi
- Samsung Galaxy SIII: 720px x 1280px, 306 ppi
Windows Phone & BlackBerry
- BlackBerry Z10: 720px x 1280px, 355 ppi
- Nokia Lumia 520: 400 px x 800px, 233 ppi
- Nokia Lumia 1520: 1080 px x 1920px, 367 ppi
Обратите внимание, что код, который мы напишем в этом уроке, может быть использован в любой из платформ.
4. Экспорт графики
В зависимости от устройств, на которые вы нацеливаетесь, вам может потребоваться преобразовать полотно в рекомендуемый размер и плотность пикселей. Вы можете сделать это в своем любимом редакторе изображений. Я использовал функцию Adjust Sizе в меню Tools в приложении предварительного просмотра OS X.
5.Пользовательский интерфейс Unity
Вы можете изменить разрешение, которое отображается в Gamepanel.
6.Игровой интерфейс
Интерфейс нашей игры будет прост. Вышеприведенный скриншот дает вам представление о полотне, которое мы будем использовать, и о том, как будет выглядеть окончательный интерфейс игры. Вы можете найти обложку и дополнительные ресурсы в исходных файлах учебника на GitHub.
7. Язык программирования
Вы можете использовать один из трех языков программирования при использовании Unity, C#, UnityScript, вариации JavaScript и Boo. Каждый язык программирования имеет свои плюсы и минусы, и вам решать, какой из них вы предпочитаете. Мои личные предпочтения относятся к языку программирования C #, поэтому это язык, который я буду использовать в этом учебнике.
Если вы решите использовать другой язык программирования, ознакомьтесь с примерами ссылок на Unity Script Reference.
8.Звуковые эффекты
Я использую несколько звуков, чтобы улучшить аудиальный опыт игры. Звуковые эффекты, используемые в этом учебнике, были получены на playonloop.com и Freesound.
9.3D-модели
Чтобы создать нашу игру, сначала нам нужно получить наши 3D-модели. Я рекомендую 3docean для высококачественных моделей, текстур и т. д., но если вы тестируете или изучаете, то есть несколько бесплатных моделей. Модели в этом учебнике были загружены из SketchUp 3D Warehouse, где вы можете найти множество разнообразных моделей всех видов.
Теперь, если Unity не распознает формат файла SketchUp, нам нужно преобразовать его в то, что может импортировать Unity. Сначала нам нужно загрузить бесплатную версию SketchUp, которая называется SketchUp Make.
Откройте 3D-модель в SketchUp Make, выберите Export> 3D Model в меню File и выберите Collada (* .dae).
Выберите имя и местоположение, а затем нажмите кнопку "Сохранить". Это создаст файл и папку для 3D-модели. Файл содержит данные для 3D-объекта, в то время как папка содержит текстуры модели. Затем вы можете импортировать модель в Unity, как описано в следующем шаге.
10.Импорт активов
Прежде чем мы начнем кодирование, нам нужно добавить наши активы в проект Unity. Вы можете сделать это одним из нескольких способов:
- выберите Import New Asset в меню Assets
- добавьте элементы в папку с ресурсами в своем проекте
- перетащите и вставьте активы в окно проекта
После завершения этого шага вы должны увидеть активы в папке Assets вашего проекта на панели Project.
11.Создание сцены
Мы готовы создать сцену нашей игры, перетаскивая объекты на панель Hierarchy или Scene. Мы также будем использовать собственные простые объекты Unity для создания уровня, как показано в следующих шагах.
12.Настройка камеры
Давайте сначала расположим нашу главную камеру немного выше, чтобы достичь желаемого вида. Выберите его на панели Hierarchy и отрегулируйте значения Transform в разделе Inspector, чтобы он соответствовал тому, что показано ниже.
Не беспокойтесь, если вы не увидите никаких изменений. Мы еще ничего для камеры не создали. Затем используйте Inspector, чтобы установить цвет фона в RGB: 0, 139, 252.
13.Фон
Уровень нашей платформы будет плавать над фоном, который будет представлять собой море. Он будет создан с использованием примитивов Unity, простой Plane с текстурой, применяемой к нему.
Если Unity может работать с 3D-объектами любого типа, созданного другими программами, иногда проще и/или удобнее использовать примитивы для прототипов.
Чтобы создать море, например, выберите Create Other > Plane в меню GameObject и настройте значения Transform в Inspector, чтобы они соответствовали тем, которые показаны ниже.
В панели Scene должен быть квадрат. Мы будем использовать его, чтобы определить, когда игрок падает с платформы, заканчивая игру.
Стоит упомянуть, что эти примитивные объекты уже прикреплены к ним с помощью Mesh Collider, это значит, что они автоматически обнаружат столкновения или инициируют события, когда они вступают в контакт с RigidBody.
14.Материал текстуры
Чтобы применить текстуру к морской плоскости, нам нужно создать материал. Материал используется для определения того, как выглядит GameObject, и важно добавить текстуру в GameObject.
Выберите Create > Material из меню Assets, чтобы создать, найдите его на панели Assets и используйте Inspector, чтобы выбрать текстуру, которую вы хотите использовать в качестве своего моря. Это настройки, которые я использовал:
В разделе материалов вы увидите сообщение о том, что рекомендуется использовать Mobile/Diffuse в качестве шейдера, потому что белый цвет по умолчанию ничего не делает. Изменение его на Mobile/Diffuse также поможет производительности.
15.Добавление света
Вы, возможно, заметили, что море немного темнее, чем должно быть. Чтобы исправить это, нам нужно добавить свет в нашу сцену. Выберите Create Other из меню GameObject и выберите Directional Light. Это создаст объект, продуцирующий луч света. Измените его значения Transform, как показано на следующем скриншоте, чтобы осветить море.
Это выглядит намного лучше.
16.Создание платформ
Платформы являются частью нашего уровня и используются игроком для перемещения мяча в портал на другой стороне моря.
Создайте Plane, как вы делали для моря, и настройте значение Transform в Inspector, как показано ниже. Это создаст и разместит первую платформу на месте.
Теперь мы можем использовать инструменты Unity Move and Rotation для создания других платформ. Они имеют одинаковый размер, поэтому мы можем использовать их по вертикали или по горизонтали, дублируя их с помощью Command+D в OS X и Control+D в Windows.
17.Текстура платформы
Создайте новый Material, как мы сделали в шаге 14, и примените к нему текстуру. Моя выглядит так:
Отрегулируйте x и y, пока вы не будете довольны результатом.
18.Пограничные цилиндры
Нам необходимо создать границу, чтобы предотвратить слишком легкий проигрыш нашего игрока. Для этого мы будем использовать новый тип примитива -Cylinder.
Выберете Create Other> Cylinder в меню GameObject и отрегулируйте значения Transform в Inspector, как показано ниже.
Это добавит небольшую границу к краю первой платформы. Создайте новый Material и измените его цвет в Inspector на RGB: 255, 69, 0.
Результат должен выглядеть так:
Используйте Command+D (Control+D в Windows) , чтобы дублировать границу и инструмент Scale, чтобы изменить ее размер. Поместите дубликаты на края платформ с помощью инструментов Unity.
19.Портал
Портал - это линия ворот игры. Игрок будет использовать акселерометр для управления мячом, чтобы довести его до этой точки при сборе предметов и избежать падения с платформы. Портал представляет собой трехмерную модель, которую мы импортировали в шаге 10.
Перетяните и вставьте ее на панели Scene или Hierarchy и измените ее значения Transform на следующие:
Это будет позиционировать ее в конце платформ.
20.Портал коллайдера
Так как импортированные по умолчанию 3D-модели не имеют коллайдера, мы должны его подключить. Поскольку нам только нужно проверить, попадает ли мяч в синюю область портала, мы присоединяем коллайдер к нему.
Посмотрите на модель портала в виде Hierarchy, и вы заметите небольшой треугольник слева от его имени. Нажмите треугольник, чтобы развернуть группу портала и выбрать первый элемент. Я добавил суффикс-коллайдер для уточнения.
Нажмите кнопку Add Component в Inspector и выберите Physics > Mesh Collider. Это добавит коллайдер, используя форму области выбранной модели.
21.Источник звука в портале
Чтобы обеспечить обратную связь с игроком, мы сыграем звуковой эффект, когда мяч коснется коллайдера портала. Поскольку мы будем запускать событие с использованием ранее созданного коллайдера, нам нужно добавить источник звука к тому же самому объекту.
Выберите его на панели Hierarchy, нажмите кнопку Add Component на панели Inspector и выберите Audio Source в разделе Audio.
Снимите флажок Play on Awake и нажмите маленькую точку справа, под иконкой шестеренки, чтобы выбрать звук, который вы хотите воспроизвести.
22.Добавление островов.
Острова - не что иное, как декоративные элементы, чтобы сделать уровень менее пустым. Я использовал импортированную 3D-модель и Cylinder для их создания. Я не буду вдаваться в подробности создания островов, поскольку они не являются существенными для игры. С помощью того, что вы узнали до сих пор, вы в состоянии создать их сами.
23.Добавление бананов
В игре Monkey Ball, игрок сможет собирать бананы во время игры. Начните с перетаскивания модели из панели Assets на Scene. Пока не беспокойтесь о ее местоположении, потому что позже мы преобразуем ее в Prefab, так как мы будем его использовать многократно.
24.Банановый Mesh-коллайдер.
Как я упоминал ранее, импортированные модели по умолчанию не имеют коллайдера, поэтому нам нужно прикрепить его к банану. Нажмите кнопку Add Component в Inspector и выберите Physics > Mesh Collider. Это добавит коллайдер, используя форму модели. Обязательно установите флажок Trigger, потому что мы хотим обнаружить столкновения, но мы не хотим, чтобы мяч влиял на банан.
24.Добавление игрока
Настало время для создания нашего игрового персонажа, который будет простым примитивом Sphere. Выберите Create Other > Sphere из меню GameObject, чтобы создать примитив и изменить значения Transform в Inspector, как показано ниже.
Это создаст сферу и разместит ее в начале нашего уровня.
Чтобы сделать сферу полупрозрачной, нам нужно изменить опции ее Shader. Откройте Inspector и измените shader на Transparent/Diffuse.
25.Игрок RigidBody
Чтобы выявить столкновение с игроком, нам нужно прикрепить к нему RigidBody. Чтобы добавить его, выберите Add Component на панели Inspector, а затем Physics > RigidBody. Вы можете оставить настройки по умолчанию. Вы можете оставить настройки по умолчанию.
26.Текстуры GUI
Чтобы отобразить пользовательский интерфейс игры, мы будем использовать в Unity Текстуры GUI. Документация Unity дает четкое объяснение текстур графического интерфейса:
Текстуры GUI отображаются в виде плоских изображений в 2D. Они созданы специально для элементов пользовательского интерфейса, кнопок или украшений. Их позиционирование и масштабирование выполняются только по осям x и y, и они измеряются в координатах экрана, а не во всемирных координатах.
По умолчанию изображения, импортированные в папку Assets, преобразуются в Textures, которые могут применяться к 3D-объектам. Нам нужно изменить их на Текстуры GUI для изображений, которые мы хотим использовать в пользовательском интерфейсе игры.
Выберите изображения, которые вы хотите преобразовать на панели Assets, и откройте Inspector, щелкните выпадающее меню Texture Type и выберите GUI.
Теперь вы можете перетаскивать изображения на сцену. Изображения всегда будут отображаться перед каждым объектом на сцене и будут рассматриваться как 2D-элементы
27. Текст GUI
Внутри каждого элемента GUI, мы отобразим число, отражающее количество бананов, которые игрок собрал, и время, за которое игрок он прошел.
Выберите Create Other > GUI Text в меню GameObject, чтобы создать текстовый объект, поместить его в центр элемента GUI, измените текст на панели Hierarchy на 0. Сделайте то же самое в течение указанного времени справа. Я установил время по умолчанию 30 секунд.
Вы можете использовать собственный шрифт для текста, добавив шрифт в папку Assets, а затем изменив свойство шрифта текста в Inspector.
28.Добавление скриптов
Пришло время для написания кода. Используя пользовательский интерфейс, мы можем начать писать необходимый код, чтобы добавить функциональность в нашу игру. Мы сделаем это с помощью скриптов. Скрипты привязаны к различным игровым объектам. Следуйте следующим шагам, чтобы узнать, как добавить взаимодействие уровню, который мы только что создали.
29.Перемещение сцены
Мы начнем с использования акселерометра устройства. Перемещать игрока с помощью акселерометра в Unity довольно просто. Здесь нечего настраивать и его легко понять.
Выберите сцену, нажмите кнопку Add Component на панели Inspector и выберите New Script. Назовите скрипт MoveScene
и не забудьте изменить язык на C#.Откройте вновь созданный файл и добавьте следующий фрагмент кода.
using UnityEngine;using System.Collections;public class MoveScene : MonoBehaviour{ void Update() { transform.rotation *= Quaternion.Euler(Input.acceleration.y/6, -Input.acceleration.x/3, 0); }}
Мы используем метод Update
для запроса данных с акселерометра в каждом кадре с помощью свойства Input.acceleration
, которое измеряет движение устройства в трехмерном пространстве.. Это позволяет нам получить значения x, y и z и использовать их для управления позицией игрока.
Затем мы применяем полученные значения уровня к свойству transansform.rotation
путем вызова Quaternion.Euler
, который возвращает значения вращения. Обратите внимание, что мы делим значения акселерометра, чтобы избежать слишком быстрого перемещения игрока, так как это затрудняет игровой процесс.
Мы изменяем только значения x и y уровня, потому что нам нужно только наклонять его, а не приближаться к камере или дальше от нее.
30.Последовательность камеры
Следующий скрипт прикреплен к основной камере. Он вычисляет пространство между камерой и игроком и поддерживает его во время движения шара.
using UnityEngine;using System.Collections;public class FollowPlayer : MonoBehaviour{ public GameObject player; private Vector3 playerOffset; // Use this for initialization void Start() { playerOffset = transform.position - player.transform.position; } // Update is called once per frame void Update() { transform.LookAt(player.transform); transform.position = player.transform.position + playerOffset; }}
Сценарий использует две переменные, которые стоит объяснить:
player
: это ссылка на игрока в Scene. Вы можете установить это в Inspector.-
playerOffset
: это расстояние между камерой и игроком. Поскольку мы поддерживаем одинаковое расстояние между камерой и игроком, камера следует за игроком при его движении. Смещение рассчитывается в методеStart
.
Мы в наводим камеру на игрока и установливаем его положение на позицию игрока плюс значение playerOffset
. Поскольку мы делаем это в методе Update
, положение камеры вычисляется и обновляется в каждом кадре. В результате камера следует за игроком. Это простая, но эффективная стратегия создания камеры, которая следует за игроком.
31.Сбор бананов
Следующий сценарий прикрепляется к банану и обрабатывает любые взаимодействия с ним. Мы начинаем с получения ссылок на соответствующий звук и текст, отображающий количество собранных бананов, которые нам понадобятся для воспроизведения звука и увеличения счетчика в левом верхнем углу, когда игрок сталкивается с бананом. После того, как вы указали переменные в скрипте, вам нужно установить эти ссылки в Inspector.
using UnityEngine;using System.Collections;public class PickBanana : MonoBehaviour{ public AudioClip bananaSound; public GUIText bananaText; void OnTriggerEnter(Collider other) { AudioSource.PlayClipAtPoint(bananaSound, transform.position);int score = int.Parse (bananaText.text) + 1;bananaText.text = score.ToString(); Destroy(gameObject); }}
Далее, мы вызываем метод, который обнаруживает, когда мяч сталкивается с бананом. Когда это происходит, мы воспроизводим звук и увеличиваем счетчик.
Чтобы изменить счетчик, мы создаем переменную, используя значение GUI Text, и используем метод int.Parse
для преобразования строки в число и увеличиваем число на 1. Затем мы установим значение в Text GUI, сначала преобразуя число в строку, вызвав метод toString
. Наконец, мы призываем Destroy
для удаления объекта игры банан.
32.Падение с платформы.
Следующий класс используется для определения того, когда игрок падает с платформы в море. Прикрепите сценарий к морскому игровому объекту.
using UnityEngine;using System.Collections;public class Lose : MonoBehaviour{ void OnCollisionEnter() { audio.Play(); Invoke("Reload", 1.59f); } void Reload() { Application.LoadLevel(Application.loadedLevel); }}
Этот простой класс использует метод OnCollisionEnter
для обнаружения того момента, когда мяч сталкивается с морем, а это означает, что игрок упал с платформы. Когда это происходит, мы воспроизводим звук, прикрепленный к морю, и используем метод Invoke
для вызова метода Reload
, который перезапускает игру, перезагружая текущую сцену.
Второй параметр метода Invoke
определяет задержку, с которой вызывается метод Reload
. Это необходимо, поскольку мы сначала хотим, чтобы звук был закончен, прежде чем мы начнем новую игру.
33.Время мониторинга
Следующий класс, Timer
, привязан к времени GUI в верхнем правом углу. Это уменьшает время и заканчивает игру, когда счетчик достигает 0.
using UnityEngine;using System.Collections;public class Timer : MonoBehaviour{ public GUIText timeText; void Start() { InvokeRepeating("ReduceTime", 1, 1); } void ReduceTime() { int currentTime = int.Parse(timeText.text) - 1; timeText.text = currentTime.ToString(); if (currentTime == 0) { audio.Play(); Invoke("Reload", 1.59f);//waits until sound is played to reload Destroy(timeText); } } void Reload() { Application.LoadLevel(Application.loadedLevel); }}
Мы сохраняем ссылку в тексте в переменной timeText
, чтобы упростить изменение пользовательского интерфейса. В методе Start
мы вызываем метод InvokeRepeating
, который неоднократно вызывает метод ReduceTime
.
Чтобы обновить текст в пользовательском интерфейсе, мы создаем переменную для преобразования текста в число, как и ранее, и вычитаем одну секунду, а затем обновляем пользовательский интерфейс с результатом.
Когда счетчик достигнет 0, воспроизводится соответствующий звук, и мы уничтожаем встречный текст. Мы вызываем метод Reload
с задержкой, чтобы перезапустить игру, когда звук закончил проигрываться.
34.Завершение уровня
Последний класс, EndLevel, используется для обнаружения, когда игрок достигает портала. Когда игрок проходит через портал, мы выводим сообщение на экран и уничтожаем мяч. Мы делаем это, чтобы предотвратить попадание мяча в море.
using UnityEngine;using System.Collections;public class EndLevel : MonoBehaviour{ public GameObject complete; public GameObject player; void OnTriggerEnter(Collider other) { audio.Play(); Invoke("Restart", 2); GameObject alert = Instantiate(complete, new Vector3(0.5f, 0.5f, 0), transform.rotation) as GameObject; Destroy(player.rigidbody); } void Restart() { Application.LoadLevel(Application.loadedLevel); }}
Метод Instantiate
используется для создания образца сообщения, которое отображается игроку. Это позволяет нам использовать элемент GUI из проекта Assets вместо того, чтобы он был на сцене. Наконец, мы перезапускаем игру с задержкой в две секунды.
35.Тестирование.
Пришло время протестировать игру. Нажмите Command+P, чтобы начать игру в Unity. Если все работает так, как ожидалось, то вы готовы к последним шагам.
36.Настройки игрока.
Если вы довольны своей игрой, пришло время выбрать Build Settings в меню File и нажать кнопку Player Settings. Это должно привести к Player Settings в панели Inspector, где вы можете установить параметры для вашего приложения.
Эти параметры представляют собой данные, специфические для приложения, которые включают в себя создателя или компанию, разрешение приложения и режим отображения, режим рендеринга (CPU, GPU), совместимость с ОС и т. д. Настройте параметры в соответствии с целью устройств, магазином или рынком, на котором вы планируете опубликовать приложение.
37.Иконки и заставки
Используя графику, созданную ранее, теперь вы можете создать милую иконку и заставку для своей игры. Unity показывает требуемые размеры, которые зависят от платформы, для которой вы создаете.
38.Создание и игра
Если ваш проект настроен правильно, пришло время пересмотреть Build Settings и нажать кнопку Build. Это все, что требуется для создания вашей игры, тестирования и/или распространения.
Заключение
В этом уроке мы научились использовать акселерометр для управления движением игрока, текстурами GUI, примитивами и другими аспектами развития игры в Unity. Я рекомендую вам поэкспериментировать с результатом и настроить игру так, чтобы сделать ее своей. Надеюсь, вам понравился этот урок и вы нашли его полезным.