Розробник дитячого мобільного пазла Fold the Adventure Олексій Галкін написав для ЦП колонку про те, на що слід звернути увагу при розробці мобільної гри на платформі Unity: як вибрати правильні Ассет з Asset Store, в якому сервісі зберігати дані про прогрес користувачів і де взяти звуки для гри.
Щоб зробити хорошу гру, потрібна хороша ідея. Але навіть маючи ідею, створити на її основі гідну гру зовсім непросто. Крім банальної удачі, існує величезна безліч речей, з якими доводиться мати справу. Нескінченне число рішень необхідно прийняти в дуже скромне час. Адже час - це гроші, а бюджет проекту має тенденцію зникати до того, як зроблено хоч щось гідне демонстрації (не кажучи вже про випуск).
Ця історія про те, як наша невелика інді-команда створювала гру Fold the Adventure ( «Склади пригода») на основі оригінальної ідеї. Оскільки гра випущена, ми можемо перевести дух і окинути поглядом три місяці, витрачені на розробку. Незважаючи на наявність багаторічного досвіду в ігровій індустрії, створення Fold the Adventure змусило нас добряче попотіти зважаючи непередбачуваних поворотів подій і дуже обмежених ресурсів. Ласкаво просимо в наше пригода!
Вибір движка: Unity
Сказати по правді, движок нам вибирати не довелося. Ми відразу взяли Unity і не пошкодували про це. Нашої першорядним завданням було створення порівняно невеликої гри і запуск її на максимальній кількості платформ. При цьому хотілося уникнути метушні з програмуванням на Objective C і Java. З Unity нам це вдалося. І хоча все було не так просто і гладко, як передбачалося, движком ми залишилися задоволені.
Ось деякі з рекомендацій, які ми виробили після досить тривалого використання Unity (необмеженого створенням Fold the Adventure):
Ассет: створювати або купувати
Якщо у вас невелика команда при сильно обмежених часу і бюджеті, то створити велику кількість якісних ігрових Ассет з нуля практично неможливо. Доводиться втихомирювати грандіозні амбіції і мінімізувати кількість необхідного. Але навіть за умови мінімізації, потрібно залишити щось, на що гравцеві було б приємно подивитися.
Якщо Ассет для гри можуть бути зроблені силами команди - однією проблемою менше (Швидка всього). Але є ще фаза прототипирования, а для неї також потрібні Ассет, які з великою часткою ймовірності будуть викинуті. Тому практично кожній команді потрібні Ассет, які вона не може або не хоче робити. Питання в тому, де їх взяти.
Першим і найбільш очевидним відповіддю для нас, як для Unity розробників, був Unity Assets Store. Який би привабливою не здавалася ця можливість, вона тягне за собою і ряд складнощів:
- Ассет в Unity Assets Store доступні всім без винятку. Однак ніхто не хоче, щоб їх гра була схожа на інші. По крайней мере, ми цього дуже не хотіли.
- Практично неможливо купити один пак Ассет, який би задовольнив всі потреби проекту, і виникає проблема стилістичної сумісності. Для Fold the Adventure ми купили кілька паків, з яких використовували менше половини.
- Незважаючи на те, що загальна кількість Ассет в Unity Assets Store досить велике, знайти серед них щось підходяще для конкретних потреб буває досить непросто. При цьому якість часто залишає бажати кращого. Ми витратили годинник на пошуки, при цьому не завжди маючи можливість оцінити якість пака без його покупки.
Другим варіантом був аутсорсинг Ассет. Безумовно, цей шлях забирає більше часу і грошей, ніж просто покупка чогось з Unity Assets Store. Однак, при вдалому розкладі, одержувані Ассет унікальні і якісніші.
Існувала також можливість покупки Ассет з джерел крім Unity Assets Store. Однак тут виникала проблема сумісності з Unity, і ми вирішили утриматися від таких експериментів.
Ось кілька простих правил, до яких ми прийшли в ході пошуку і покупки Ассет в Unity Assets Store
Музика та звуки заслуговують на окрему увагу. Вони рідко створюються інді-командою самостійно (якщо у вас є композитор, то вам або дуже пощастило, або ви вже не інді). На щастя, існує велика кількість сервісів, що поставляють royalty-free музику і звуки, включаючи Unity Assets Store. І це зовсім недорого.
Недостатньо просто купити музику і звуки. Необхідно зробити так, щоб вони правильно звучали в грі і не дратували слух. Якщо ви впевнені в своїх силах, то можна спробувати зробити це самостійно. Ми ж звернулися за допомогою до студії, яка спеціалізується на озвучці. Отриманий результат був значно краще того, що ми могли зробити самі, і коштував своїх грошей.
Де зберігати дані: Parse
Навіть якщо ви, як і ми, створюєте однопользовательськую гру, вам все одно буде потрібно місце для зберігання даних про поточний прогрес гравця, статистиці його дій, зроблених покупках та іншої інформації. Найпростішим рішенням буде використовувати для цього клас Unity PlayerPrefs. Однак він зберігає дані локально і, цілком очевидно, не підходить для таких делікатних речей, як внутрішньоігрові покупки.
Однією з причин, по яким ми вибрали Parsе, була його інтеграція з Facebook (перша версія Fold the Adventure створювалася саме для Facebook). І, незважаючи на те, що пізніше фокус розробки був зміщений на мобільні платформи, ми продовжили використовувати Parse.
Ще однією приємною особливістю Parse є його цінова політика. Спочатку вона здається трохи дивною, але, після роздумів і розрахунків, виявляється більш ніж вдалою. По суті, ви обмежені кількістю запитів в секунду. Хороша новина в тому, що 30 запитів в секунду даються безкоштовно. Може здатися, що це зовсім небагато, але на ділі цього достатньо для підтримки тисяч користувачів. За умови, що ви використовуєте ці запити розумно.
У Parse ви робите все через запити. Для отримання і зміни полів даних, створення відносини між таблицями, формування вибірки - для всього потрібен запит. На перший погляд, кількість запитів повинно бути досить великим, але, на ділі, більшу частину елементарних операцій можна об'єднати в один запит за допомогою методу ParseObject.SaveAllAsync. Крім того, Parse викине виняток, якщо межа запитів в секунду перевищено. Але нічого не заважає вам почекати деякий час і виконати запит повторно. І хоча гра в такому випадку може здатися користувачеві «підвішеному», ця проблема легко обходиться за допомогою внесення невеликих змін в призначений для користувача інтерфейс і логіку збереження і читання даних.
Єдине, для чого Parse не слід використовувати, так це для створення ігрового сервера. Навіть якщо ви розробляєте покрокову гру, призначення Parse в корені відмінно. Існують інші рішення, які значно краще підходять для цих цілей.
Використання Parse в рамках Unity не сполучена з особливими труднощами і добре документовано. По суті, вам необхідно завантажити Parse SDK, налаштувати вашу гру на сервері Parse і в проекті Unity, а також трохи попрограмміровать. Один очевидний нюанс: ви не зможете використовувати Parse, якщо пристрій, на яке встановлена ваша гра, не має доступу до інтернету.
Якщо є необхідність підтримувати офлайн-режим і оновлювати дані в Parse при наявності підключення до мережі, то вам доведеться написати для цього невелику окрему систему. Ми використовували для цього клас PlayerPrefs. Система зберігає дані локально і заливає їх в Parse, як тільки виявляє наявність підключення до інтернету.
Стаціонарні платформи проти мобільних: компроміси
Незважаючи на поступове зближення протягом останніх років, стаціонарні і мобільні платформи як і раніше сильно відрізняються один від одного. Це стає очевидним при спробі змусити «красиві» шейдери працювати прийнятно (не кажучи вже про те, щоб змусити їх працювати швидко) на всіх пристроях, на яких передбачається запуск гри. Unity істотно полегшує цей процес, але, на жаль, не вирішує всіх проблем.
Існує величезна кількість статей, присвячених оптимізації Unity-ігор під мобільні платформи, так що тут на цю тему буде сказано трохи.
Ось кілька рекомендацій:
- Якщо ви плануєте запуск на мобільних платформах і використовуєте тіні, то обмежтеся режимом forward lighting. Незважаючи на запікання освітлення і скорочення числа об'єктів, що відкидають тіні, ми не змогли домогтися прийнятної продуктивності в режимі deferred lighting. Можливо, ми недостатньо старалися, але форуми Unity, здебільшого, солідарні з нами в цьому питанні.
- Мінімізуйте кількість draw call-ів. Велика кількість полігонів в моделях не позначиться так сильно на продуктивності, як додаткові draw call-и. Ми планували велику оптимізацію, спрямовану на скорочення кількості draw call-ів, щоб краще підтримувати старі моделі мобільних пристроїв, але, на жаль, не змогли зробити її впродовж відведених жорсткі терміни.
- Не зловживайте текстурними вибірками в шейдерах. Це може привести до істотного падіння продуктивності. У нашій грі ми були змушені використовувати кілька спеціальних шейдеров замість одного універсального - саме з цієї причини.
Крім відмінностей в продуктивності і апаратних обмежень, існує ще одна важлива відмінність між стаціонарними і мобільними платформами. І ця відмінність - режим введення. Гра, створена для управління за допомогою клавіатури і миші, погано переноситься на мультитач і акселерометр. Ми переконалися в цьому на своєму гіркому досвіді. Перш за все, в Unity розділена обробка миші і мультитач. А тому було необхідно створити систему, уніфікує цей аспект. Для цих цілей ми використовували систему введення зі складу NGUI. яка, після невеликих доробок, показала себе дуже добре. Вона також дозволила нам вирішити проблему розподілу введення між призначеним для користувача інтерфейсом і ігровим керуванням, яка доставляла нам деякі неприємності на той момент.
Інтерфейс в цілому зажадав ряду модифікацій для коректної підтримки мобільних пристроїв. Наприклад, замість прокручування коліщатка миші і утримування кнопок довелося ввести мультитач-жести. Деякі з модифікацій можна було потенційно вблагати за допомогою готових рішень з Unity Assets Store. Але в нашому випадку це був простий pinch, а тому ми вирішили написати його за годину з нуля, замість того, щоб витрачати дні на підключення та налагодження системи, яка «робить все і навіть більше».
Найбільша кількість проблем викликало внутріігрового управління. Ми почали з традиційного набору ASWD + миша для управління персонажем і камерою, плануючи використовувати екранний джойстик на мобільних пристроях. Але все вийшло не зовсім так, як ми очікували: гра стала практично некерованою. Нам довелося терміново міняти внутріігрового управління, при цьому вносячи зміни навіть в ігрову механіку. Методом проб і помилок ми зупинилися на point-n-click управлінні, яке на мобільних пристроях сприймається інтуїтивно.
Локалізація: чим простіше, тим краще
Якщо ви хочете добитися успіху гри в світовому масштабі, то, поза всякими сумнівами, її необхідно локалізувати. А локалізація - це ще одна частина розробки, яку інді-команда практично ніколи не може зробити самостійно. Це означає тільки одне: за локалізацію доведеться заплатити.
Локалізувати необхідно все, що має відношення до людської мови. Тобто тексти, мова, написи на структурах - все це повинно бути локалізовано. Такий процес дуже швидко може стати вельми трудомістким і дорогим. Тому вкрай важливо звести кількість локалізуемое контенту до мінімуму.
Написів на структурах краще уникати, і використовувати, наприклад, текстові поля NGUI. Якщо в грі необхідна мова, то, швидше за все, будуть потрібні і субтитри, оскільки локалізація мови не тільки дороге задоволення, але ще й вимогливе з точки зору місця, займаного грою.
Але мінімізація локалізуемое контенту - це тільки початок. Наступний етап - підготовка самої гри до локалізації. Погана новина полягає в тому, що Unity (на момент написання даної статті) не має вбудованих механізмів для цих цілей. І хоча існує цілий ряд спеціалізованих рішень в Unity Assets Store (наприклад, l2 Localization), ми вирішили використовувати систему локалізації, що йде в складі NGUI.
Система локалізації NGUI проста і зрозуміла у використанні. Вона побудована на основі одного CSV-файлу, що містить колонку для кожної мови. Наявність такого файлу дуже зручно для відправки рядків на переклад (для цього існує велика кількість спеціалізованих сервісів) і подальшої вставки перекладеної версії.
Ми використовували Google Docs Sheets для зберігання файлу локалізації. У такому варіанті він легко доступний всім членам команди, може бути швидко оновлений і скачав в CSV форматі. Крім того, ми відкрили доступ до цього файлу ряду друзів, які говорять на інших мовах. Таким чином ми отримали частину перекладів безкоштовно.
На жаль, система локалізації NGUI вельми обмежена в своїх можливостях і не може бути використана в іграх з великою кількістю різноманітного локалізуемое контенту. Наприклад, вона не дозволяє змінити шрифт текстового поля, а ця можливість необхідна при локалізації на такі мови, як японський. У зв'язку з цим ми розширили функціональність класу NGUI UILocalize, додавши можливість змінювати шрифт і варіювати положення текстових полів.
висновок
Після того, як все зроблено, гру необхідно ретельно протестувати (варто це робити і неодноразово в процесі розробки). Цим має займатися максимальну кількість людей на максимальній кількості пристроїв. Ніщо не псує гарну гру так, як пропущений баг. При цьому потрібно обов'язково слухати скарги гравців. Оскільки ці скарги перетворяться в незадоволених клієнтів відразу після виходу гри на ринок. А цього точно ніхто не хоче.
Шляхом постійного тестування нашої гри в ході всього процесу розробки, ми виявили і виправили більше сотні різних багів. При цьому наша гра була не така вже складна і велика, але програмного забезпечення без помилок не буває. Крім того, на підставі пропозицій і скарг тестерів, ми внесли цілий ряд модифікацій в гру, включаючи зміни базової ігрової механіки, структури частини рівнів, розмірів і положення елементів призначеного для користувача інтерфейсу, внутріігрового управління.
Ця історія, разом з випущеної грою, завершує три місяці важкої і кропіткої робіт. І, незважаючи на те, що ми зіткнулися з безліччю труднощів, процес розробки Fold the Adventure був дуже захоплюючим. Сподіваємося, що гра, яку ми створили, а також отриманий нами досвід зроблять світ трохи краще. Удачі в створенні ваших ігор!