Статьи

Создай игру Fruit Ninja Inspired с Unity

Конечный продукт
Что вы будете создавать

В этом уроке вы узнаете, как создать мобильную 3D-игру с использованием C # и Unity. Цель игры — разрезать фрукты, появляющиеся на сцене, с помощью сенсорного экрана.

Из этого руководства вы узнаете о следующих аспектах разработки игр Unity:

  • импорт 3D моделей
  • жесты
  • линейные рендеры
  • физические силы
  • 2D спрайты

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

Откройте Unity и выберите « Новый проект» в меню « Файл», чтобы открыть диалоговое окно нового проекта. Сообщите Unity, где вы хотите сохранить проект, и установите   Установите значения по умолчанию для: меню в 3D .

На следующем шаге вам будет представлен пользовательский интерфейс Unity. Настройте проект для мобильной разработки, выбрав « Настройки сборки» в меню « Файл» и выбрав нужную платформу.

Первое, что нам нужно сделать после выбора целевой платформы, это выбрать размер рисунка, который мы будем использовать в игре. Это поможет нам выбрать правильный размер для 3D текстур и 2D GUI, не делая размытые изображения или использовать текстуры, которые слишком велики для целевого устройства. Например, изображение должно иметь более высокое разрешение, если вы ориентируетесь на iPad с дисплеем Retina, чем на Lumia 520.

  • 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 является открытой платформой, существует широкий диапазон устройств, разрешений экрана и плотности пикселей. Некоторые из наиболее распространенных из них перечислены ниже.

  • 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
  • Blackberry Z10 : 720px x 1280px, 355 ppi
  • Nokia Lumia 520 : 400 пикселей на 800 пикселей, 233 пикселей на дюйм
  • Nokia Lumia 1520 : 1080px x 1920px, 367 ppi

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

В зависимости от целевых устройств вам может потребоваться преобразовать иллюстрацию в рекомендуемый размер и плотность пикселей. Вы можете сделать это в вашем любимом графическом редакторе. Я использовал функцию « Настроить размер …» в меню « Инструменты» в приложении предварительного просмотра OS X.

Прежде чем начать, убедитесь, что кнопка 2D на панели « Сцена» не выделена. Вы также можете изменить разрешение, отображаемое на панели « Игра» .

Затем вам будут представлены панели рабочего пространства, которые мы также будем использовать в этом руководстве. Найдите минутку, чтобы взглянуть на основные интерфейсные панели, такие как Сцена , Игра , Иерархия , Проект , Активы и Инспектор . Мы будем часто использовать их в этом уроке.

Вы можете использовать один из трех языков программирования при использовании Unity, C # , UnityScript , разновидности JavaScript и Boo . У каждого языка программирования есть свои плюсы и минусы, и вам решать, какой из них вы предпочитаете. Мои личные предпочтения относятся к языку программирования C #, поэтому я буду использовать этот язык в этом руководстве.

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

Я буду использовать несколько звуков, чтобы улучшить слуховой опыт игры. Звуковые эффекты, используемые в этом руководстве, были получены от PlayOnLoop и Freesound .

Чтобы создать игру, сначала нужно получить несколько 3D моделей. Я рекомендую 3docean для высококачественных моделей и текстур, но если вы тестируете или изучаете, бесплатные модели будут работать так же хорошо. Модели из этого руководства были загружены из SketchUp 3D Warehouse, где вы можете найти самые разнообразные 3D-модели.

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

Откройте 3D-модель в SketchUp Make, выберите « Экспорт»> «3D-модель» в меню « Файл» и выберите Collada (* .dae) . Выберите имя и местоположение и нажмите « Сохранить» . Это создаст файл и папку для 3D-модели. Файл содержит данные для трехмерного объекта, в то время как папка содержит текстуры модели. На следующем шаге мы импортируем модель в Unity.

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

  • выберите Импортировать новый актив в меню Активы
  • перетащите активы в окно проекта
  • добавить элементы в папку ресурсов проекта

После выполнения этого шага вы должны увидеть активы в папке « Ресурсы » вашего проекта на панели « Проект» .

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

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

Чтобы наши объекты были видны в трехмерном мире, нам нужно добавить свет на сцену. Выберите « Создать другое» в меню GameObject и выберите « Направленный свет» . Это создаст объект, который производит луч света. Измените значения Transform, как показано на следующем снимке экрана, чтобы он освещал сцену.

Свет должен быть виден на сцене, как показано на следующем скриншоте.

Мы будем использовать текстуру Sprite в качестве фона. По умолчанию изображения, импортированные в папку « Ресурсы », преобразуются в экземпляры текстуры, которые можно применять к трехмерным объектам. Нам нужно изменить эти экземпляры текстуры на Sprite экземпляры текстуры для изображения, которое мы хотим использовать в качестве фона.

Выберите изображение, которое вы хотите преобразовать, на панели « Активы» и откройте Инспектора . Выберите Sprite в меню Тип текстуры .

Перетащите фон на панель Иерархия . Он должен автоматически появиться на панели « Сцена» . Настройте значения Transform в Инспекторе, как показано на следующем снимке экрана.

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

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

Это поместит яблоко в верхнем левом углу экрана.

Наряду с моделью яблока, мы будем отображать число, указывающее счет игрока. Это количество фруктов, которые игрок срезал.

Выберите « Создать другой»> «Текст GUI» в меню GameObject, чтобы создать текстовый объект, поместите его справа от модели яблока и измените текст на панели « Инспектор» на 0 .

Вы можете встроить пользовательский шрифт, импортировав его в папку « Ресурсы » и изменив свойство « Шрифт» текста в Инспекторе .

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

Чтобы добавить значок часов, выберите изображение, которое вы хотите использовать, на панели « Ресурсы» и откройте Инспектора . Выберите GUI в меню Texture Type, чтобы преобразовать его в текстуру GUI. Перетащите изображение в сцену и измените его значения преобразования на значения, показанные ниже.

Теперь сцена должна выглядеть следующим образом.

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

Предупреждение — это GUI-текстура, которую мы покажем, когда таймер достигнет 0 . В центре экрана будет отображено сообщение об окончании игры.

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

Теперь давайте реализуем класс Timer . Выберите Time GUI Text , нажмите кнопку « Добавить компонент» на панели « Инспектор» и выберите « Новый скрипт» . Назовите скрипт Timer и не забудьте изменить язык на C #. Откройте только что созданный файл и выполните следующие шаги.

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

1
2
private GUIText timeTF;
public GameObject alertReference

Давайте посмотрим на каждую из переменных.

  • timeTF : ссылка на текстовый графический интерфейс Time
  • alertReference : ссылка на alertReference оповещения

Мы будем использовать эти ссылки для доступа ко времени и оповещения игровых объектов и изменения их значений. Установите предварительный сборник предупреждений в Инспекторе .

С объявленными переменными мы устанавливаем значение timeTF , обращаясь к свойству guiText текущего игрового объекта. Это позволит нам изменить текстовое значение позже.

Мы также вызываем метод InvokeRepeating , который будет вызывать метод ReduceTime каждую секунду.

1
2
3
4
5
void Start()
{
    timeTF = gameObject.guiText;
    InvokeRepeating(«ReduceTime», 1, 1);
}

Метод 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 чтобы преобразовать результат обратно в строку.

Это последняя часть класса 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);
    }
}

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

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

Чтобы обнаружить столкновение с яблоком, нам нужно добавить к нему твердое тело . Чтобы добавить его, выберите « Добавить компонент» на панели « Инспектор» и выберите « Физика»> «Жесткое тело» . Вы можете оставить настройки по умолчанию.

Нам также нужно добавить коробочный коллайдер в яблоко, чтобы обнаруживать столкновения. Этот коллайдер определит область попадания яблока. Нажмите кнопку « Добавить компонент» на панели « Инспектор» , выберите « Физика»> «Box Collider» и измените его значения, как показано на снимке экрана ниже.

На панели « Сцена» вокруг яблока должно появиться зеленое поле, представляющее только что добавленный коллайдер.

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

Добавьте к нему скрипт и перетащите его обратно на панель « Ресурсы», чтобы создать префаб . Откройте только что созданный класс.

Класс Splash обрабатывает изображения, созданные при нарезке фруктов.

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

1
2
private Color randomAlpha;
private float currentAlpha;

В этом методе мы вычисляем случайное альфа-значение от 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);
}

Чтобы уменьшить альфа, нам сначала нужно получить текущее значение. Переменная 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);
        }
    }
}

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

В классе 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;

Чтобы получить ссылку на текст оценки, мы используем метод Find . Этот метод ищет активные игровые объекты и возвращает искомый объект, в данном случае текст GUI счета.

1
2
3
4
void Start()
{
    scoreReference = GameObject.Find(«Score»).guiText;
}

С scoreReference переменной scoreReference теперь мы можем увеличить ее значение, когда фрукты нарезаны.

В методе 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);
    }
}

Следующий код использует метод 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();
        }
    }
}

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

Это переменные, объявленные в этом классе.

1
2
3
[SerializeField]
private GameObject appleReference;
private Vector3 throwForce = new Vector3(0, 18, 0);
  • appleReference : ссылка на яблочный сборный
  • throwForce : сила, используемая, чтобы подтолкнуть фрукты вверх

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

1
2
3
4
void Start()
{
    InvokeRepeating(«SpawnFruit», 0.5f, 6);
}

Метод 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);
        }
    }
}

Давайте теперь реализуем сенсорное управление. Игрок сможет использовать сенсорный экран, чтобы разрезать фрукты. Мы визуализируем это, рисуя линию, используя класс LineRenderer а затем проверяем, сталкивается ли фрукт с жестом смахивания игрока.

Мы начнем с создания некоторых переменных.

  • 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;

В методе 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 . Этот метод указывает количество точек линии. Вызывая этот метод с большим количеством точек, мы можем увеличить размер линии. Это станет понятнее на следующем шаге.

Строка создается в методе 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++;
        }
    }
}

Когда линия на месте, мы добавляем к ней коллайдер, чтобы помочь нам обнаружить столкновение с любым из фруктов. Следующий фрагмент кода создает и добавляет блок коллайдера в строку, используя метод 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);

Мы удаляем строку, когда игрок больше не касается экрана. Это предотвращает любые нежелательные столкновения с яблоками.

В следующем фрагменте кода мы проверяем, завершена ли текущая фаза объекта Touch и устанавливаем для счетчика вершин lineRenderer значение 0 . Это удалит текущие сегменты линии, но не разрушит объект, что позволит нам использовать его позже. Мы также сбрасываем переменную i для последующего использования.

1
2
3
4
5
6
7
if(touch.phase == TouchPhase.Ended)
{
    /* Remove Line */
                 
    lineRenderer.SetVertexCount(0);
    i = 0;
}

Как только линия удалена, нам больше не нужны прикрепленные к ней коллайдеры. Сначала мы создаем массив объектов 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);
                }
            }
        }
    }
}

Пришло время протестировать игру. Нажмите Command-P, чтобы играть в игру в Unity. Если все работает, как ожидалось, тогда вы готовы к последним шагам.

Когда вы довольны своей игрой, пора выбрать « Настройки сборки» в меню « Файл» и нажать кнопку « Настройки игрока» . Это должно вызвать настройки проигрывателя на панели инспектора, где вы можете установить параметры для вашего приложения.

Эти настройки представляют собой специфические данные приложения, которые включают создателя или компанию, разрешение приложения и режим отображения, режим рендеринга (CPU, GPU), совместимость с ОС устройства и т. Д. Настройте параметры в соответствии с целевыми устройствами и магазином или рынком, где Вы планируете опубликовать приложение.

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

Как только ваш проект будет правильно настроен, пришло время вернуться к настройкам сборки и нажать кнопку « Сборка» . Это все, что нужно для создания вашей игры для тестирования и / или распространения.

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