Страницы

воскресенье, 15 декабря 2019 г.

Процедурное создание уровней в Unity. Часть 3. Создание окружения из файла рисунка

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

Давайте посмотрим, как это можно сделать:

  • Создайте простое изображение jpeg, используя графический редактор по вашему выбору, например Adobe Photoshop, Microsoft paint или Gimp.
  • При создании изображения можно использовать инструмент кисть. Убедитесь, что ее размер равен 1 для рисования по пикселям.

Для нашего приложения мы оставим пустые пространства белыми, а стену будет изображать пиксель другого цвета, на ваш выбор.
Рис 9. Создание контура для уровня


Вот такой немного кривой лабиринт у меня получился.

  • Мой контур очень простой; он использует белые пиксели для пустых областей и цветные пиксели для стен.
  • Это изображение размером 500 на 500 пикселей, имитирующее область шириной 500 метров и длиной 500 метров. Вы можете сохранить это изображение в любом формате по вашему выбору; в моем случае, я сохранил его в формате .png (outline.png).

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

  • Импортируйте текстуру в Unity (т. е. перетащите изображение в окно проекта или используйте опцию Assets | Import New Asset).
  • Рисунок должен быть сохранен в папке Assets. Его не нужно сохранять в папку Resources!!!

Рис. 10. Импорт рисунка с контуром лабиринта

Выберите импортированную текстуру в окне проекта. Используя окно Инспектора, сделайте следующие настройки:
Рис. 11. Настройки текстуры
В разделе Advanced нужно поставить галочку  Read/Write enabled и убрать Generate Mip Maps. Нажмите справа внизу кнопку Apply, чтобы применить изменения.

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

Создайте новый C# скрипт и назовите его GenerateFromImage (или как хотите). Добавьте следующий код в начало скрипта перед методом Start:
Color[,] colorOfPixel;
public GameObject wall;
public Texture2D outlineImage;
Мы объявили двухмерный массив типа Color, в котором будут храниться значения цвета всех пикселей нашей текстуры. Объект wall будет использован для создания стен из префаба. Так же, как и в прошлых примерах, нужно будет перетащить префаб из окна проекта в инспектор на переменную wall скрипта. Объект outlineImage типа Texture2D – это наш рисунок контура лабиринта. На место этой переменной надо будет перетащить импортированную текстуру.

Добавьте в Start следующий код:
colorOfPixel = new Color[outlineImage.width, outlineImage.height];
for (int x = 0; x < outlineImage.width; x++)
{
   for (int y = 0; y < outlineImage.height; y++)
   {
      colorOfPixel[x, y] = outlineImage.GetPixel(x, y);//check tramsparency
      if (colorOfPixel[x, y] != Color.white)
      {
        GameObject t = (GameObject)(Instantiate(wall, new Vector3
                  ((outlineImage.width / 2 ) - x, 2f, (outlineImage.height / 2 ) - y),
                  Quaternion.identity));
      }
  }
}

  • Инициализируем двухмерный массив colorOfPixel . Его размерность равна сторонам импортированного рисунка.
  • Используя двойной вложенный цикл, считываем картинку по одному пикселю.
  • С помощью метода GetPixel узнаем значение цвета каждого пикселя и сохраняем его в элемент массива с соответствующими координатами.
  • Если цвет пикселя не белый, то создаем экземпляр стены с нужными координатами.

Сохраните скрипт и убедитесь, что нет ошибок. Перейдите из редактора кода в Unity и деактивируйте скрипт GenerateMaze, созданный нами в прошлых примерах и добавленный к пустому объекту generateMaze. Добавьте к пустому объекту наш новый скрипт GenerateFromImage.
Рис. 12. Деактивация и добавление скриптов

Сейчас нам нужно заполнить пустые переменные в скрипте. Перетащите на соответствующие места префаб wall и текстуру outline.
Рис.13. Заполнение переменных
Поскольку размер рисунка 500*500, мы должны скорректировать размер объекта ground. Измените свойство scale на (700, 1, 700) или рассчитайте сами, если ваш рисунок другого размера.
Позицию камеры можно изменить на (0, 611, 0).
Теперь запустите сцену и посмотрите на наш лабиринт.
Рис. 14. Сцена с лабиринтом
Я поменял материал у объекта wall, поэтому он другого цвета.
Можно изменить рисунок, добавив какие-то детали, например, двери,  окна и блоки другого цвета, а затем модифицировать скрипт, считывая эти пиксели. Чтобы побегать по созданному лабиринту, нужно импортировать ассет персонажа, а затем добавить префаб персонажа на сцену.

Содержание
Часть 2. Создание окружения из текстового файла
Часть 4. Использование XML-файлов для создания контента