Вступление
В этом уроке вы узнаете, как создать мобильную 3D-игру с использованием C # и Unity. Цель игры — разрезать фрукты, появляющиеся на сцене, с помощью сенсорного экрана.
Из этого руководства вы узнаете о следующих аспектах разработки игр Unity:
- импорт 3D моделей
- жесты
- линейные рендеры
- физические силы
- 2D спрайты
Пользовательский интерфейс игры прост. Снимок экрана ниже дает вам представление о графическом оформлении, которое мы будем использовать, и о том, как будет выглядеть конечный пользовательский интерфейс. Вы можете найти иллюстрацию и дополнительные ресурсы в исходных файлах руководства на GitHub .
1. Настройка проекта
Шаг 1: Создайте новый проект Unity
Откройте Unity и выберите « Новый проект» в меню « Файл», чтобы открыть диалоговое окно нового проекта. Сообщите Unity, где вы хотите сохранить проект, и установите Установите значения по умолчанию для: меню в 3D .
Шаг 2. Настройка параметров сборки
На следующем шаге вам будет представлен пользовательский интерфейс Unity. Настройте проект для мобильной разработки, выбрав « Настройки сборки» в меню « Файл» и выбрав нужную платформу.
Шаг 3: Художественное произведение
Первое, что нам нужно сделать после выбора целевой платформы, это выбрать размер рисунка, который мы будем использовать в игре. Это поможет нам выбрать правильный размер для 3D текстур и 2D GUI, не делая размытые изображения или использовать текстуры, которые слишком велики для целевого устройства. Например, изображение должно иметь более высокое разрешение, если вы ориентируетесь на iPad с дисплеем Retina, чем на Lumia 520.
IOS
- iPad без сетчатки: 1024 x 768 пикселей
- iPad с сетчаткой : 2048px x 1536px
- 3,5 «iPhone / iPod Touch без сетчатки: 320px x 480px
- 3,5 «iPhone / iPod с сетчаткой : 960px x 640px
- 4 «iPhone / iPod Touch: 1136 пикселей x 640 пикселей
Android
Поскольку Android является открытой платформой, существует широкий диапазон устройств, разрешений экрана и плотности пикселей. Некоторые из наиболее распространенных из них перечислены ниже.
- Asus Nexus 7 Tablet: 800px x 1280px, 216 ppi
- Motorola Droid X: 854 x 480 пикселей, 228 ppi
- Samsung Galaxy SIII: 720px x 1280px, 306 ppi
Windows Phone & BlackBerry
- Blackberry Z10 : 720px x 1280px, 355 ppi
- Nokia Lumia 520 : 400 пикселей на 800 пикселей, 233 пикселей на дюйм
- Nokia Lumia 1520 : 1080px x 1920px, 367 ppi
Обратите внимание, что код, который мы напишем в этом руководстве, можно использовать для работы с любой из платформ.
Шаг 4: Экспорт графики
В зависимости от целевых устройств вам может потребоваться преобразовать иллюстрацию в рекомендуемый размер и плотность пикселей. Вы можете сделать это в вашем любимом графическом редакторе. Я использовал функцию « Настроить размер …» в меню « Инструменты» в приложении предварительного просмотра OS X.
Шаг 5: Настройте пользовательский интерфейс Unity
Прежде чем начать, убедитесь, что кнопка 2D на панели « Сцена» не выделена. Вы также можете изменить разрешение, отображаемое на панели « Игра» .
Затем вам будут представлены панели рабочего пространства, которые мы также будем использовать в этом руководстве. Найдите минутку, чтобы взглянуть на основные интерфейсные панели, такие как Сцена , Игра , Иерархия , Проект , Активы и Инспектор . Мы будем часто использовать их в этом уроке.
Шаг 6: Язык программирования
Вы можете использовать один из трех языков программирования при использовании Unity, C # , UnityScript , разновидности JavaScript и Boo . У каждого языка программирования есть свои плюсы и минусы, и вам решать, какой из них вы предпочитаете. Мои личные предпочтения относятся к языку программирования C #, поэтому я буду использовать этот язык в этом руководстве.
Если вы решите использовать другой язык программирования, обязательно посмотрите справочник сценариев Unity для примеров.
2. Ресурсы
Звуковые эффекты
Я буду использовать несколько звуков, чтобы улучшить слуховой опыт игры. Звуковые эффекты, используемые в этом руководстве, были получены от PlayOnLoop и Freesound .
3D модели
Чтобы создать игру, сначала нужно получить несколько 3D моделей. Я рекомендую 3docean для высококачественных моделей и текстур, но если вы тестируете или изучаете, бесплатные модели будут работать так же хорошо. Модели из этого руководства были загружены из SketchUp 3D Warehouse, где вы можете найти самые разнообразные 3D-модели.
Поскольку Unity не распознает формат файла SketchUp, нам нужно преобразовать его во что-то, что Unity может импортировать. Сначала нам нужно скачать бесплатную версию SketchUp, которая называется SketchUp Make .
Откройте 3D-модель в SketchUp Make, выберите « Экспорт»> «3D-модель» в меню « Файл» и выберите Collada (* .dae) . Выберите имя и местоположение и нажмите « Сохранить» . Это создаст файл и папку для 3D-модели. Файл содержит данные для трехмерного объекта, в то время как папка содержит текстуры модели. На следующем шаге мы импортируем модель в Unity.
3. Импорт активов
Прежде чем мы начнем кодировать, нам нужно добавить ресурсы в проект Unity. Вы можете сделать это одним из нескольких способов:
- выберите Импортировать новый актив в меню Активы
- перетащите активы в окно проекта
- добавить элементы в папку ресурсов проекта
После выполнения этого шага вы должны увидеть активы в папке « Ресурсы » вашего проекта на панели « Проект» .
4. Настройка камеры и освещения
Шаг 1: Настройка камеры
На этом шаге мы размещаем основную камеру, чтобы создать нужный нам вид. Выберите основную камеру на панели « Иерархия» и настройте значения « Преобразование» в Инспекторе, чтобы они соответствовали значениям, показанным ниже.
Не волнуйтесь, если вы не видите никаких изменений. Мы еще ничего не создали для камеры, чтобы увидеть.
Шаг 2: Настройка света
Чтобы наши объекты были видны в трехмерном мире, нам нужно добавить свет на сцену. Выберите « Создать другое» в меню GameObject и выберите « Направленный свет» . Это создаст объект, который производит луч света. Измените значения Transform, как показано на следующем снимке экрана, чтобы он освещал сцену.
Свет должен быть виден на сцене, как показано на следующем скриншоте.
5 Добавить фон
Мы будем использовать текстуру Sprite в качестве фона. По умолчанию изображения, импортированные в папку « Ресурсы », преобразуются в экземпляры текстуры, которые можно применять к трехмерным объектам. Нам нужно изменить эти экземпляры текстуры на Sprite экземпляры текстуры для изображения, которое мы хотим использовать в качестве фона.
Выберите изображение, которое вы хотите преобразовать, на панели « Активы» и откройте Инспектора . Выберите Sprite в меню Тип текстуры .
Перетащите фон на панель Иерархия . Он должен автоматически появиться на панели « Сцена» . Настройте значения Transform в Инспекторе, как показано на следующем снимке экрана.
6 Создать графический интерфейс Score
Чтобы отобразить счет игры, мы будем использовать текстовый интерфейс Unity и импортированную 3D-модель.
Шаг 1: Добавление модели Apple
Выберите импортированную трехмерную модель на панели « Ресурсы» и перетащите ее на сцену . Я собираюсь использовать модель яблока. Отрегулируйте значения Transform в Инспекторе, чтобы они соответствовали приведенным ниже.
Это поместит яблоко в верхнем левом углу экрана.
Шаг 2: Добавление текста GUI
Наряду с моделью яблока, мы будем отображать число, указывающее счет игрока. Это количество фруктов, которые игрок срезал.
Выберите « Создать другой»> «Текст GUI» в меню GameObject, чтобы создать текстовый объект, поместите его справа от модели яблока и измените текст на панели « Инспектор» на 0 .
Вы можете встроить пользовательский шрифт, импортировав его в папку « Ресурсы » и изменив свойство « Шрифт» текста в Инспекторе .
7. Создайте графический интерфейс таймера
Мы будем использовать таймер, чтобы указать, когда игра закончится. Он состоит из текстуры GUI, показывающей значок, и текста GUI, отображающего оставшееся время.
Шаг 1: Добавление иконки часов
Чтобы добавить значок часов, выберите изображение, которое вы хотите использовать, на панели « Ресурсы» и откройте Инспектора . Выберите GUI в меню Texture Type, чтобы преобразовать его в текстуру GUI. Перетащите изображение в сцену и измените его значения преобразования на значения, показанные ниже.
Теперь сцена должна выглядеть следующим образом.
Шаг 2: Добавление текста GUI
Повторите шаги для добавления текста оценки, чтобы добавить текст таймера. Не забудьте установить текст в правильное время.
8 Alert Prefab
Предупреждение — это GUI-текстура, которую мы покажем, когда таймер достигнет 0 . В центре экрана будет отображено сообщение об окончании игры.
Чтобы создать оповещение, преобразуйте изображение оповещения в текстуру графического интерфейса с помощью инспектора . Перетащите его с панели « Иерархия» на панель « Ресурсы», чтобы преобразовать его в « Префаб» .
9. Timer
Класс
Теперь давайте реализуем класс Timer
. Выберите Time GUI Text , нажмите кнопку « Добавить компонент» на панели « Инспектор» и выберите « Новый скрипт» . Назовите скрипт Timer и не забудьте изменить язык на C #. Откройте только что созданный файл и выполните следующие шаги.
Шаг 1: объявить переменные
Мы начнем с создания ряда переменных, которые мы будем использовать в классе Timer
.
1
2
|
private GUIText timeTF;
public GameObject alertReference
|
Давайте посмотрим на каждую из переменных.
-
timeTF
: ссылка на текстовый графический интерфейс Time -
alertReference
: ссылка наalertReference
оповещения
Мы будем использовать эти ссылки для доступа ко времени и оповещения игровых объектов и изменения их значений. Установите предварительный сборник предупреждений в Инспекторе .
Шаг 2: Настройка
С объявленными переменными мы устанавливаем значение timeTF
, обращаясь к свойству guiText
текущего игрового объекта. Это позволит нам изменить текстовое значение позже.
Мы также вызываем метод InvokeRepeating
, который будет вызывать метод ReduceTime
каждую секунду.
1
2
3
4
5
|
void Start()
{
timeTF = gameObject.guiText;
InvokeRepeating(«ReduceTime», 1, 1);
}
|
Шаг 3: Реализация ReduceTime
Метод ReduceTime
отвечает за обновление текста таймера и отображение предупреждающего сообщения. Игра заканчивается, когда время достигает 0 . Добавьте следующий блок кода в класс Timer
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
void ReduceTime()
{
if (timeTF.text == «1»)
{
/* Alert */
Time.timeScale = 0;
Instantiate(alertReference, new Vector3(0.5f, 0.5f, 0), transform.rotation);
audio.Play();
GameObject.Find(«AppleGUI»).GetComponent<AudioSource>().Stop();
}
timeTF.text = (int.Parse(timeTF.text) — 1).ToString();
}
|
Мы начинаем с тестирования, если время подходит к концу. Если это true
, мы приостанавливаем игру, изменяя свойство timeScale
на 0 , создаем экземпляр предупреждения и играем в игру поверх звука.
Если время не подходит к концу, мы просто уменьшаем его значение на 1 . Для этого мы используем метод int.Parse
для преобразования строки времени в число, вычитаем 1 и вызываем ToString
чтобы преобразовать результат обратно в строку.
Шаг 4: метод перезагрузки
Это последняя часть класса Timer
. В методе Reload
мы вызываем LoadLevel
для класса Application
и перезагружаем текущий уровень, сбрасывая каждый объект и переменную в исходное состояние.
1
2
3
4
|
void Reload()
{
Application.LoadLevel (Application.loadedLevel);
}
|
Вот как должен выглядеть законченный класс, когда закончите.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
using UnityEngine;
using System.Collections;
public class Timer : MonoBehaviour
{
private GUIText timeTF;
public GameObject alertReference;
void Start()
{
timeTF = gameObject.guiText;
InvokeRepeating(«ReduceTime», 1, 1);
}
void ReduceTime()
{
if (timeTF.text == «1»)
{
/* Alert */
Time.timeScale = 0;
Instantiate(alertReference, new Vector3(0.5f, 0.5f, 0), transform.rotation);
audio.Play();
GameObject.Find(«AppleGUI»).GetComponent<AudioSource>().Stop();
}
timeTF.text = (int.Parse(timeTF.text) — 1).ToString();
}
void Reload()
{
Application.LoadLevel (Application.loadedLevel);
}
}
|
10 Яблочный сборный
Яблоко является одним из важнейших элементов игры и одним из интерактивных объектов на экране. Игрок может использовать сенсорный экран устройства, чтобы разрезать яблоко, увеличив свой счет.
Перетащите яблоко с панели « Ресурсы» на сцену . Не беспокойтесь о его положении, потому что через минуту мы преобразуем его в префаб и удалим его из иерархии .
Шаг 1: Добавьте Rigidbody
Чтобы обнаружить столкновение с яблоком, нам нужно добавить к нему твердое тело . Чтобы добавить его, выберите « Добавить компонент» на панели « Инспектор» и выберите « Физика»> «Жесткое тело» . Вы можете оставить настройки по умолчанию.
Шаг 2: Добавить Box Collider
Нам также нужно добавить коробочный коллайдер в яблоко, чтобы обнаруживать столкновения. Этот коллайдер определит область попадания яблока. Нажмите кнопку « Добавить компонент» на панели « Инспектор» , выберите « Физика»> «Box Collider» и измените его значения, как показано на снимке экрана ниже.
На панели « Сцена» вокруг яблока должно появиться зеленое поле, представляющее только что добавленный коллайдер.
11. Всплеск Prefab
Предварительный сборник заставки будет использоваться в качестве визуального эффекта, когда игрок нарезает фрукты. Он появится на сцене для каждого фрукта, который игрок срезает и постепенно исчезает со временем. Преобразуйте изображение в Sprite, как описано ранее, и добавьте его в сцену .
Добавьте к нему скрипт и перетащите его обратно на панель « Ресурсы», чтобы создать префаб . Откройте только что созданный класс.
12. Splash
Class
Класс Splash
обрабатывает изображения, созданные при нарезке фруктов.
Шаг 1: объявить переменные
Эти переменные используются для вычисления и установки альфа-значения для префаба-заставки. Изменяя его альфа-свойство, мы можем постепенно исчезать из префаба.
1
2
|
private Color randomAlpha;
private float currentAlpha;
|
Шаг 2: Настройка
В этом методе мы вычисляем случайное альфа-значение от 0,3 до 0,5 и сохраняем это значение в переменной randomAlpha
. Затем мы устанавливаем полученную альфу для свойства color
игрового объекта.
В последней строке кода мы вызываем метод, который будет уменьшать это значение каждые 300 миллисекунд, создавая эффект затухания.
1
2
3
4
5
6
|
void Start()
{
randomAlpha = new Color(1, 1, 1, Random.Range(0.3f, 0.5f));
gameObject.renderer.material.color = randomAlpha;
InvokeRepeating(«ReduceAlpha», 0.3f, 0.3f);
}
|
Шаг 3: Уменьшите Альфу и Уничтожьте
Чтобы уменьшить альфа, нам сначала нужно получить текущее значение. Переменная currentAlpha
хранит это значение. Затем мы вычтем 0,1 из этого значения и переназначим новую альфу на игровой объект. Изображение удаляется, когда оно почти не видно.
01
02
03
04
05
06
07
08
09
10
11
12
|
void ReduceAlpha()
{
currentAlpha = gameObject.renderer.material.color.a;
if (gameObject.renderer.material.color.a <= 0.1f)
{
Destroy(gameObject);
} else
{
gameObject.renderer.material.color = new Color(1, 1, 1, currentAlpha — 0.1f);
}
}
|
Вот как выглядит класс Splash
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
using UnityEngine;
using System.Collections;
public class Splash : MonoBehaviour
{
private Color randomAlpha;
private float currentAlpha;
void Start()
{
randomAlpha = new Color(1, 1, 1, Random.Range(0.3f, 0.5f));
gameObject.renderer.material.color = randomAlpha;
InvokeRepeating(«ReduceAlpha», 0.3f, 0.3f);
}
void ReduceAlpha()
{
currentAlpha = gameObject.renderer.material.color.a;
if (gameObject.renderer.material.color.a <= 0.1f)
{
Destroy(gameObject);
} else
{
gameObject.renderer.material.color = new Color(1, 1, 1, currentAlpha — 0.1f);
}
}
}
|
13. Apple
Class
Создав наш готовый сборник, мы можем перейти к классу Apple
. Этот класс будет обрабатывать такие действия, как обнаружение столкновений, обновление счета и удаление яблока со сцены.
Шаг 1: объявить переменные
В классе Apple
объявлены три переменные:
-
splashReference
: ссылка наsplashReference
-заставку -
randomPos
: позиция дляrandomPos
заставки -
scoreReference
: ссылка на текст графического интерфейса пользователя.
1
2
3
4
|
[SerializeField]
private GameObject splashReference;
private Vector3 randomPos = new Vector3(Random.Range(-1, 1), Random.Range(0.3f, 0.7f), Random.Range(-6.5f, -7.5f));
private GUIText scoreReference;
|
Шаг 2: Получить ссылку на счет
Чтобы получить ссылку на текст оценки, мы используем метод Find
. Этот метод ищет активные игровые объекты и возвращает искомый объект, в данном случае текст GUI счета.
1
2
3
4
|
void Start()
{
scoreReference = GameObject.Find(«Score»).guiText;
}
|
С scoreReference
переменной scoreReference
теперь мы можем увеличить ее значение, когда фрукты нарезаны.
Шаг 3: Уничтожь, когда за сценой
В методе Update
мы проверяем, больше ли фрукт виден на экране, открывая его положение y
и удаляя его, если оно true
. Это помогает нам освободить память, уничтожая неиспользуемые игровые объекты.
1
2
3
4
5
6
7
8
|
void Update()
{
/* Remove fruit if out of view */
if (gameObject.transform.position.y < -36)
{
Destroy(gameObject);
}
}
|
Шаг 4. Обработка коллизий
Следующий код использует метод OnCollisionEnter
чтобы определить, когда игрок нарезает фрукт. Когда это происходит, мы играем нарезанный звук и удаляем фрукты. Затем мы создаем новый экземпляр готового заставки и обновляем счет.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
void OnCollisionEnter(Collision other)
{
if(other.gameObject.name == «Line»)
{
Camera.main.GetComponent<AudioSource>().Play();
Destroy(gameObject);
Instantiate(splashReference, randomPos, transform.rotation);
/* Update Score */
scoreReference.text = (int.Parse(scoreReference.text) + 1).ToString();
}
}
|
Вот как выглядит полный класс Apple
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
using UnityEngine;
using System.Collections;
public class Apple : MonoBehaviour
{
[SerializeField]
private GameObject splashReference;
private Vector3 randomPos = new Vector3(Random.Range(-1, 1), Random.Range(0.3f, 0.7f), Random.Range(-6.5f, -7.5f));
private GUIText scoreReference;
void Start()
{
scoreReference = GameObject.Find(«Score»).guiText;
}
void Update()
{
/* Remove fruit if out of view */
if (gameObject.transform.position.y < -36)
{
Destroy(gameObject);
}
}
void OnCollisionEnter(Collision other)
{
if(other.gameObject.name == «Line»)
{
Camera.main.GetComponent<AudioSource>().Play();
Destroy(gameObject);
Instantiate(splashReference, randomPos, transform.rotation);
/* Update Score */
scoreReference.text = (int.Parse(scoreReference.text) + 1).ToString();
}
}
}
|
14. FruitSpawner
Класс
Класс FruitSpawner
создает экземпляры и перемещает фрукты на сцену. Он прикреплен к основной камере.
Шаг 1: объявить переменные
Это переменные, объявленные в этом классе.
1
2
3
|
[SerializeField]
private GameObject appleReference;
private Vector3 throwForce = new Vector3(0, 18, 0);
|
-
appleReference
: ссылка на яблочный сборный -
throwForce
: сила, используемая, чтобы подтолкнуть фрукты вверх
Шаг 2: вызвать Spawn
В следующих строках кода мы вызываем метод InvokeRepeating
чтобы вызывать метод SpawnFruit
каждые шесть секунд. Это будет добавлять новые фрукты на сцену каждые шесть секунд, давая игроку время нарезать их, прежде чем фрукты упадут на дно сцены.
1
2
3
4
|
void Start()
{
InvokeRepeating(«SpawnFruit», 0.5f, 6);
}
|
Шаг 3: метод SpawnFruit
Метод SpawnFruit
создает фрукты и толкает их вверх, чтобы игрок мог их разрезать. Мы используем оператор for
чтобы создать экземпляры фруктов, расположить их случайным образом на сцене и применить физическую силу, используя метод addForce
.
1
2
3
4
5
6
7
8
|
void SpawnFruit()
{
for (byte i = 0; i < 4; i++)
{
GameObject fruit = Instantiate(appleReference, new Vector3(Random.Range(10, 30), Random.Range(-25, -35), -32), Quaternion.identity) as GameObject;
fruit.rigidbody.AddForce(throwForce, ForceMode.Impulse);
}
}
|
Это полный класс FruitSpawner
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
using UnityEngine;
using System.Collections;
public class FruitSpawner : MonoBehaviour
{
[SerializeField]
private GameObject appleReference;
private Vector3 throwForce = new Vector3(0, 18, 0);
void Start()
{
InvokeRepeating(«SpawnFruit», 0.5f, 6);
}
void SpawnFruit()
{
for (byte i = 0; i < 4; i++)
{
GameObject fruit = Instantiate(appleReference, new Vector3(Random.Range(10, 30), Random.Range(-25, -35), -32), Quaternion.identity) as GameObject;
fruit.rigidbody.AddForce(throwForce, ForceMode.Impulse);
}
}
}
|
15. Сенсорное управление
Давайте теперь реализуем сенсорное управление. Игрок сможет использовать сенсорный экран, чтобы разрезать фрукты. Мы визуализируем это, рисуя линию, используя класс LineRenderer
а затем проверяем, сталкивается ли фрукт с жестом смахивания игрока.
Шаг 1: объявить переменные
Мы начнем с создания некоторых переменных.
-
c1, c2
: эти переменные устанавливают цвет линии -
lineGO
: этот игровой объект будет содержать визуализатор линии -
lineRenderer
: экземпляр средства визуализации строк -
i
: значение типа int, используемое для установки размера и индекса строки
1
2
3
4
5
|
public Color c1 = Color.yellow;
public Color c2 = Color.red;
private GameObject lineGO;
private LineRenderer lineRenderer;
private int i = 0;
|
Шаг 2: Настройка
В методе Start
мы устанавливаем необходимые объекты и свойства для линии. Мы начнем с создания нового экземпляра GameObject
содержащего LineRenderer
. Затем мы используем некоторые методы линейного рендерера, чтобы установить, как он будет выглядеть.
01
02
03
04
05
06
07
08
09
10
|
void Start()
{
lineGO = new GameObject(«Line»);
lineGO.AddComponent<LineRenderer>();
lineRenderer = lineGO.GetComponent<LineRenderer>();
lineRenderer.material = new Material(Shader.Find(«Mobile/Particles/Additive»));
lineRenderer.SetColors(c1, c2);
lineRenderer.SetWidth(0.3F, 0);
lineRenderer.SetVertexCount(0);
}
|
Большинство свойств, установленных в этом блоке кода, легко понять, SetColor
меняет цвет линии, а SetWidth
устанавливает ее ширину. Обратите особое внимание на строку SetVertexCount
. Этот метод указывает количество точек линии. Вызывая этот метод с большим количеством точек, мы можем увеличить размер линии. Это станет понятнее на следующем шаге.
Шаг 3: Создать линию
Строка создается в методе Update
. Сначала мы проверяем, касается ли плеер экрана, touchCount
свойство touchCount
класса Input
. Если свойство больше 0 , это означает, что на экране устройства есть хотя бы один палец.
Мы сохраняем ссылку на объект Touch
для более легкого доступа и проверяем, в какой фазе он находится в данный момент. Нам нужно, чтобы он был в фазе Moved
чтобы иметь возможность создать линию.
Если игрок перемещает палец по экрану, мы можем начать создавать отрезок линии в этой позиции. Мы снова SetVertexCount
метод SetVertexCount
чтобы увеличить максимальное количество сегментов линии.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
void Update()
{
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
if(touch.phase == TouchPhase.Moved)
{
lineRenderer.SetVertexCount(i+1);
Vector3 mPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 15);
lineRenderer.SetPosition(i, Camera.main.ScreenToWorldPoint(mPosition));
i++;
}
}
}
|
Шаг 4: Добавить коллайдеры
Когда линия на месте, мы добавляем к ней коллайдер, чтобы помочь нам обнаружить столкновение с любым из фруктов. Следующий фрагмент кода создает и добавляет блок коллайдера в строку, используя метод AddComponent
и устанавливает его позицию в текущую позицию lineRenderer
. Последняя строка кода изменяет размер коллайдера по умолчанию, чтобы соответствовать размеру строки.
1
2
3
|
BoxCollider bc = lineGO.AddComponent<BoxCollider>();
bc.transform.position = lineRenderer.transform.position;
bc.size = new Vector3(0.1f, 0.1f, 0.1f);
|
Шаг 5: Удалить строку
Мы удаляем строку, когда игрок больше не касается экрана. Это предотвращает любые нежелательные столкновения с яблоками.
В следующем фрагменте кода мы проверяем, завершена ли текущая фаза объекта Touch
и устанавливаем для счетчика вершин lineRenderer
значение 0 . Это удалит текущие сегменты линии, но не разрушит объект, что позволит нам использовать его позже. Мы также сбрасываем переменную i
для последующего использования.
1
2
3
4
5
6
7
|
if(touch.phase == TouchPhase.Ended)
{
/* Remove Line */
lineRenderer.SetVertexCount(0);
i = 0;
}
|
Шаг 6: Уничтожить коллайдеры
Как только линия удалена, нам больше не нужны прикрепленные к ней коллайдеры. Сначала мы создаем массив объектов BoxCollider
в которых BoxCollider
коллайдеры BoxCollider
линейного игрового объекта. Затем мы перебираем массив, уничтожая каждый блок-коллайдер.
1
2
3
4
5
6
7
8
|
/* Remove Line Colliders */
BoxCollider[] lineColliders = lineGO.GetComponents<BoxCollider>();
foreach(BoxCollider b in lineColliders)
{
Destroy(b);
}
|
Давайте посмотрим на полную реализацию класса LinesHandler
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
using UnityEngine;
using System.Collections;
public class LinesHandler : MonoBehaviour
{
public Color c1 = Color.yellow;
public Color c2 = Color.red;
private GameObject lineGO;
private LineRenderer lineRenderer;
private int i = 0;
void Start()
{
lineGO = new GameObject(«Line»);
lineGO.AddComponent<LineRenderer>();
lineRenderer = lineGO.GetComponent<LineRenderer>();
lineRenderer.material = new Material(Shader.Find(«Mobile/Particles/Additive»));
lineRenderer.SetColors(c1, c2);
lineRenderer.SetWidth(0.3F, 0);
lineRenderer.SetVertexCount(0);
}
void Update()
{
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
if(touch.phase == TouchPhase.Moved)
{
lineRenderer.SetVertexCount(i+1);
Vector3 mPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 15);
lineRenderer.SetPosition(i, Camera.main.ScreenToWorldPoint(mPosition));
i++;
/* Add Collider */
BoxCollider bc = lineGO.AddComponent<BoxCollider>();
bc.transform.position = lineRenderer.transform.position;
bc.size = new Vector3(0.1f, 0.1f, 0.1f);
}
if(touch.phase == TouchPhase.Ended)
{
/* Remove Line */
lineRenderer.SetVertexCount(0);
i = 0;
/* Remove Line Colliders */
BoxCollider[] lineColliders = lineGO.GetComponents<BoxCollider>();
foreach(BoxCollider b in lineColliders)
{
Destroy(b);
}
}
}
}
}
|
16. Заключительные шаги
Шаг 1: Тестирование
Пришло время протестировать игру. Нажмите Command-P, чтобы играть в игру в Unity. Если все работает, как ожидалось, тогда вы готовы к последним шагам.
Шаг 2: Настройки игрока
Когда вы довольны своей игрой, пора выбрать « Настройки сборки» в меню « Файл» и нажать кнопку « Настройки игрока» . Это должно вызвать настройки проигрывателя на панели инспектора, где вы можете установить параметры для вашего приложения.
Эти настройки представляют собой специфические данные приложения, которые включают создателя или компанию, разрешение приложения и режим отображения, режим рендеринга (CPU, GPU), совместимость с ОС устройства и т. Д. Настройте параметры в соответствии с целевыми устройствами и магазином или рынком, где Вы планируете опубликовать приложение.
Шаг 3: значки и заставки
Используя графику, которую вы создали ранее, теперь вы можете создать красивый значок и заставку для вашей игры. Unity показывает вам необходимые размеры, которые зависят от платформы, для которой вы строите.
Шаг 4: построй и играй
Как только ваш проект будет правильно настроен, пришло время вернуться к настройкам сборки и нажать кнопку « Сборка» . Это все, что нужно для создания вашей игры для тестирования и / или распространения.
Вывод
В этом уроке мы узнали, как использовать сенсорное управление, физические силы, текстуры GUI и другие аспекты разработки игр в Unity. Я призываю вас поэкспериментировать с результатом и настроить игру так, чтобы она была вашей. Я надеюсь, что вам понравился этот урок, и вы нашли его полезным.