открытый код игры на юнити

Unity выложила исходный C#-код на Github

открытый код игры на юнити

Код был выложен вчера, официальный анонс состоится только в понедельник.

Ложка дегтя: код может быть использован только в справочных целях. Полную лицензию на использование можно посмотреть здесь.

Впрочем, это ничуть не остановило товарища, уже оформившего пулл-реквест с фиксом производительности.

Далеко не секрет, что крупные студии (например, авторы Cities: Skylines) имеют доступ к исходному коду (и C#, и C++) уже довольно давно — для этого необходимо приобретать отдельную лицензию. Раньше это было критически необходимым, если вам требовалось модифицировать стандартный процесс рендеринга (начиная с версии 2018, можно будет менять все под себя при помощи SRP и кода на C#).

За данную инициативу дружно благодарим Aras Pranckevičius, который занимался подготовкой кода к публикации последние несколько недель.

Движок Unity становится более модульным и проходит масштабное обновление: в нем появился пакетный менеджер, появилась система задач C# (позволяющая писать безопасный многопоточный код), была переработана система ECS (Entity Component System) с учетом низкоуровневых оптимизаций, а к версии 2018.3 наконец-то появятся (sic!) Nested Prefabs.

Глубокий уход Unity в сторону data-oriented design происходит под чутким надзором Майка Эктона (Mike Acton, бывший глава разработки движков в Insomniac Games), присоединившегося к компании прошлой осенью вместе с другим соратником по Insomniac, чей подход к игровой оптимизации приобрел широкую известность после доклада на CppCon 2014 «Data-Oriented Design and C++»).

Интересное недавнее интервью CTO Unity, главой R&D и Эктоном можно прочитать на английском по ссылке. По всей видимости, публикация исходного кода — это еще один важный шаг для нового курса компании.

Источник

Открытые проекты

Для энтузиастов, готовых объединить усилия в разработке игры, мы запустили первую программу Unity по разработке ПО с открытым исходным кодом. Присоединяйтесь к нашему путешествию.

открытый код игры на юнити

Unity Open Projects — это инициатива совместной разработки, в рамках которой Unity и сообщество разработчиков объединят усилия в разработке небольших игр с открытым исходным кодом. Принимайте активное участие или просто следите за работой, чтобы узнать, как выглядит разработка проекта изнутри.

Реалистичный процесс разработки игр

Проекты развиваются. Команды адаптируются. Как и в реальном мире, здесь возникают разные трудности, эффективное преодоление которых зависит от вклада всех участников. Это настоящая коллективная работа.

Внести свой вклад может каждый

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

Примите участие в приключении

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

открытый код игры на юнити

С помощью инициативы Open Projects мы хотим показать процесс реальной разработки проекта и приглашаем в проект всех желающих. Окажите посильную помощь проекту и заработайте свое место в списке создателей.

Источник

Практическое руководство по взлому (и защите) игр на Unity

открытый код игры на юнити

Когда речь идёт о программном обеспечении, термин «взлом» зачастую ассоциируют с пиратством и нарушением авторских прав. Данная статья не об этом; напротив, я решительно не одобряю любые действия, которые прямо или косвенно могут навредить другим разработчикам. Тем не менее, эта статья всё же является практическим руководством по взлому. Используя инструменты и методы о которых далее пойдёт речь, вы сможете проверить защиту собственной Unity игры и узнаете, как обезопасить её от взлома и кражи ресурсов.

Введение

В основе взлома лежит знание: необходимо понимать особенности компиляции Unity-проекта, чтобы его взломать. Прочитав статью, вы узнаете, каким образом Unity компилирует ресурсы игры и как извлечь из них исходные материалы: текстуры, шейдеры, 3D-модели и скрипты. Эти навыки будут полезны не только для анализа безопасности проекта, но также для его продвинутой отладки. В связи с закрытостью исходного кода, Unity часто работает как «черный ящик» и порой единственный способ понять, что именно в нём происходит — это изучение скомпилированной версии скриптов. Кроме прочего, декомпиляция чужой игры может стать серьёзным подспорьем в поиске её секретов и «пасхальных яиц». Например, именно таким образом было найдено решение финальной головоломки в игре FEZ.

открытый код игры на юнити

Находим ресурсы игры

Рассмотрим для примера игру, собранную под ОС Windows и загруженную через Steam. Чтобы добраться до директории, в которой находятся нужные нам ресурсы, откроем окно свойств игры в библиотеке Steam и в закладке «Local files» нажмём «Browse local files…».

открытый код игры на юнити

Извлекаем текстуры и шейдеры

открытый код игры на юнити

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

С шейдерами ситуация обстоит сложнее: они извлекаются в уже скомпилированным виде и, насколько мне известно, решений для их автоматической трансляции в удобочитаемый формат не существует. Тем не менее, это обстоятельство не мешает импортировать и использовать полученные шейдеры в другом Unity-проекте. Не забывайте, однако, что подобная «кража» нарушает авторские права и является актом пиратства.

Извлекаем 3D-модели

Трёхмерные модели в типовой Unity-сборке «разбросаны» по различным ресурсам, а некоторые из них и вовсе могут генерироваться во время игры. Вместо копания в файлах, существует интересная альтернатива — получить данные о геометрии прямиком из памяти графического ускорителя. Когда игра запущена, вся информация о текстурах и моделях, видимых на экране, находится в памяти видеокарты. С помощью утилиты 3D Ripper DX можно извлечь всю эту информацию и сохранить в формате, понятном 3D-редакторам (например, 3D Studio Max). Учтите, что программа не самая простая в обращении — возможно, придётся обратиться к документации.

открытый код игры на юнити

Взламываем PlayerPrefs

открытый код игры на юнити

Защищаем PlayerPrefs

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

Приведенный выше класс — упрощенный пример реализации, работающий со строковыми переменными. Для инициализации ему необходимо передать секретный ключ и список PlayerPrefs-ключей, значения которых должны быть защищены:

Затем его можно использовать следующим образом:

Взламываем исходный код

открытый код игры на юнити

открытый код игры на юнити

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

Защищаем исходный код

Раз Unity не заботится о сохранности нашего кода — сделаем это сами. Благо, существует утилита, готовая автоматически зашифровать плоды нашего интеллектуального труда: Unity 3D Obfuscator.

открытый код игры на юнити

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

Взламываем память игры

Cheat Engine — широко известная программа для взлома игр. Она находит ту область оперативной памяти, которая принадлежит процессу запущенной игры и позволяет произвольно её изменять.

открытый код игры на юнити

Эта программа пользуется тем фактом, что разработчики игр очень редко защищают значения переменных. Рассмотрим следующий пример: в некой игре у нас есть 100 патронов; используя Cheat Engine, можно выполнить поиск участков памяти, которые хранят значение «100». Затем мы делаем выстрел — запас патронов составляет 99 единиц. Снова сканируем память, но теперь ищем значение «99». После нескольких подобных итераций можно с легкостью обнаружить расположение большинства переменных игры и произвольно их изменять.

Защищаем память игры

Использовать нашу новую структуру можно следующим образом:

Если вы выводите значения переменных на экран, хакеры всё ещё смогут перехватить и поменять их, но это не повлияет на действительные значения, хранящиеся в памяти и использующиеся в логике игры.

Заключение

К сожалению, существует не так уж много способов защитить игру от взлома. Будучи установленной на пользовательское устройство, она фактически раскрывает все ваши текстуры, модели и исходный код. Если кто-то захочет декомпилировать игру и украсть ресурсы — это лишь вопрос времени.

Невзирая на это, существуют действенные методы, которые позволят серьёзно усложнить жизнь злоумышленникам. Это не значит, что нужно вдаваться в панику, шифровать весь исходный код и защищать каждую переменную, но по крайней мере задумайтесь, какие ресурсы вашего проекта действительно важны и что вы можете сделать для их защиты.

Источник

Игра на Unity, с открытым кодом

Суть игры

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

Познакомьтесь, это Кальцифер, ваш аватар в этой игре.

открытый код игры на юнити

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

Пояснения насчет кода

Начнем с GameManager. Он всему голова, именно в нем меняется состоянии игры — Initialization->GameLoop->Win или Lose. Одинок и един, ибо синглтон. Так как игра не сетевая, простая, и без сложных переходов, то было принято решение использовать этот паттерн. Здесь же идет обработка попаданий по игроку (см. ниже Известные проблемы), учет хитпоинтов и проверка на выигрыш\проигрыш. Был бы GodObject, да слишком мало у нас классов, поэтому знает не всё обо всех. На этапе инициализации, создается пул объектов отображающих анимацию урона по игроку и смерти врагов. Для отслеживания состояния хитпоинтов, можно подписаться на UpdateHpWizardDelegate или UpdateHpCalciferDelegate. В нашем случае это делает GUIManager для отображения текущего хп на экране.

открытый код игры на юнити

К этому времени SpawnManager уже составил список точек спавна врагов

открытый код игры на юнити

a WaveManager загрузил порядок волн создания врагов. Волны можно настроить двумя способами: прописать в коде игры или загрузить с Json файла. Для редактирования этого Json написан кастомный editor:GameDataEditor

открытый код игры на юнити

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

Создание волн сделанно с помощью хитрой корутины:

Вначале проходит firstWaveDelay секунд до начала запуска 1 первой волны. После этого в цикле прогоняют все волны по очереди, вставляя нужную задержку step.delay между шагами волны. Почему в корутине а не например в Update? Да собственно можно и так и эдак, просто тут более наглядно, видно где задержка ( yield return new WaitForSeconds) и не надо городить лишние циклы и проверки.

Давай те глянем что же представляют из себя SpawnPoint. Это MonoBehavior c 2 компонентами: SpawnPoint и CircleCollider2D. В первом, с помощью второго, определяется занят ли спавн каким то врагом. OnDrawGizmos отображает в редакторе Unity расположение спавнов.

открытый код игры на юнити

Все враги происходят от базового класса BasicEnemy в котором есть несколько виртуальных методов:

Кстати, врагов и многие другие объекты (много и часто создаваемых на сцене) мы не удаляем с помощью Destroy(this), а отправляем обратно в пул объектов — ObjectPool.Recycle(this). Таким макаром мы неплохо экономим на создании объектов, которое как известно достаточно затратное дело.

Так например анимации заканчиваются вызовом SelfDestroy(), который и возвращает объект анимации обратно в пул.

открытый код игры на юнити

Движутся же враги с помощью силы пафоса компонента BasicEnemyMoving. В нем нас интересуют два метода: OnEnable()и Move(). OnEnable () вызывается после вытаскивания врага с пула и нужен для поворота врага (если необходимо) в сторону цели.

Move() же является виртуальным методом, который и движет врага к цели. Его можно переопределить в потомках и сделать особенное движение (с рывками, синусоидальное и т.п.)

Источник

Делаем простую игру с кнопками, ящиками и дверями на Unity

открытый код игры на юнити

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

Для самых нетерпеливых по ссылкам ниже находится готовый прототип.
Онлайн версия
Скомпилированная версия для Windows [Зеркало]

Что мы собираемся делать? Двумерную головоломку с колобком в роли главного героя, который может двигать ящики, которые могут нажимать кнопки, которые могут открывать двери, за которыми скрывается выход из уровня, который построил я. Или вы, у нас же здесь туториал как-никак.

Подразумевается, что вы уже успели скачать Unity и поигрались немного в редакторе. Нет? Сейчас самое время, я подожду.

Грубый набросок

открытый код игры на юнити

Я соврал, я не буду ждать. Создаём пустой проект без лишних пакетов и выбираем схему расположения окошек на свой вкус, я буду использовать Tall. Добавляем в иерархию сферу, перетаскиваем на неё главную камеру. Теперь камера будет следовать за нашей сферой, если она вдруг захочет погулять. Переименовываем сферу в «Player», перетаскиваем в Project, теперь у нас есть prefab, который мы можем использовать в любых новых сценах, если таковые будут. Не забывайте проверять координаты префабов при создании и использовании, если мы хотим делать игрушку в двух измерениях, то третья ось должна быть выставлена в ноль для всех взаимодействующих объектов.

Добавим на сцену кубик, назовём его «Wall» и перетащим в Assets. Одинокая кубическая стена рядом со сферическим колобком не очень-то впечатляет, да? Три поля Scale в инспекторе позволят нам вытягивать стенку, а комбинация клавиш Ctrl+D создаст её копию. В Unity есть много других полезных горячих клавиш, например зажатый Ctrl ограничивает перемещение объектов единичными интервалами, а клавиша V позволит тягать объект за вершины, и они будут липнуть к вершинам других объектов. Замечательно, не правда ли? И вы всё ещё пишете свой движок? Ну-ну.

открытый код игры на юнити

Сообразите что-нибудь похожее на комнату, сохраните сцену, нажмите Play и полюбуйтесь своим творением пару минут. Хорошие гейм-дизайнеры называют это тестированием. Чего-то не хватает, да? Хмм. Возможно, если я полюбуюсь ещё немного, то…

Скрипты и физика

Нам нужно больше движения и цвета! Хотя, если ваше суровое детство было наполнено бетонными игрушками, то можно оставить всё как есть. Для всех остальных пришло время скриптов. Я буду приводить примеры на C#, но можно писать и на JS или Boo. На самом деле выбирать последние два смысла не имеет, они были добавлены в Юнити скорее как довесок, меньше поддерживаются, хуже расширяются и для них сложнее найти примеры. Особенно ужасен Boo, который по сути является unpythonic Python. Мерзость. Виват, питонисты!

Создаём C# Script, называем его «PlayerController», перетаскиваем на префаб Player и открываем с помощью Visual Studio любимого редактора. Сперва нужно потереть лишний мусор, оставим только нужное.

Функция Update вызывается в каждом кадре, что очень удобно для реализации движения, внутри неё мы и будем размещать код. Нажатия кнопок игроком можно получить с помощью класса Input. В комплекте с Unity идут замечательные настройки ввода, достаточно написать Input.GetAxis(«Horizontal») и мы уже знаем нажал ли игрок на клавиатуре стрелку вправо или влево. Если у игрока подключён геймпад, то он может управлять и с него, нам даже не надо писать лишний код.

Функция AddForce имеет несколько интересных вариантов приложения силы, но для начала нам хватит и значений по умолчанию.

Готово! Сохраняем, жмём Play, тестируем.

открытый код игры на юнити

Эээм, знаете, мне это напомнило тот момент из фильма Inception, где мужик бешено вращал глазами и катился кубарем то по стене, то по потолку. Наверное так он себя чувствовал.

Нам нужно запретить вращение и передвижение по оси Z. Выделяем префаб, смотрим на компонент Rigidbody и видим раздел Constraints. Оставляем неотмеченными только первые две галочки X и Y, остальные четыре включаем. Чуть выше снимаем галочку Use Gravity и прописываем Drag равный четырём (в разделе об эстетике я расскажу зачем это было сделано). Тестируем ещё раз.

Оно шевелится и не вертится! Ура! Но делает это слишком медленно. Добавим одну переменную к нашему скрипту и задействуем её в формуле нашего движения. Весь код будет в итоге выглядеть так:

Заметили как в инспекторе появилось новое поле Acceleration у нашего скрипта? Эффектно, да? Вбиваем в поле тридцатку или что-нибудь на ваш вкус и проверяем в действии.

Материалы и коллайдеры

Пора уже сделать какую-нибудь кнопку, чтобы было на что нажимать. Дублируем префаб Wall и переименовываем его в «Button». В инспекторе у коллайдера ставим галочку Is Trigger. Это развоплотит нашу кнопку и заставит другие объекты проходить сквозь неё. Создаём скрипт «Button» и вешаем на кнопку.

У коллайдеров-триггеров есть события OnTriggerEnter и OnTriggerExit, которые вызываются всякий раз, когда что-то пересекает область триггера. На самом деле это не совсем так, ибо есть множество разных объектов и физический движок обрабатывает не все столкновения, подробнее читайте здесь.

Для начала просто проверим как работают триггеры. Напишем что-нибудь в консольку Unity. Функция Debug.Log очень полезная, кроме текста она также умеет печатать разные игровые объекты.

Класс Color может принимать кроме тройки RGB ещё и альфу, но у нас стоит обычный диффузный шейдер, поэтому она для нас не важна. Тестируем!

открытый код игры на юнити

Если вы ещё не сделали это, то настала пора прибраться в нашем проекте, иначе мы заблудимся в мешанине префабов и скриптов. Например создадим папку «Levels» для хранения сцен, «Prefabs» для складирования заготовок, «Materials» для материалов и «Scripts» для скриптов, а потом рассортируем накопившееся богатство по папочкам.

Знаете, а ведь наша кнопка до сих пор не похожа на кнопку! Давайте её сплющим и заставим продавливаться под колобком. Выберите кнопку в иерархии, сделайте её толщиной в 0.3 единицы и положите на пол, т. е. выставьте координату Z в 0.35. Видите в инспекторе наверху три удобных кнопочки «Select», «Revert» и «Apply»? С помощью них можно взаимодействовать с префабом прямо на месте. Нажмите Apply и все кнопки отныне будут плоские и лежачие.

Для реализации программной анимации мы будет использовать класс Transform. У него есть свойство localPosition, которое позволит нам двигать кнопку:

Этот код нажмёт кнопку. В целом это выглядит так:

Двери, ящики и магниты

Теперь, когда у нас есть полнофункциональная кнопка, можно заставить её что-нибудь делать. Склонируем префаб стенки, назовём его «Door», создадим красненький материал «Door Mat», повесим его куда нужно и закинем свежеиспечённую дверь на сцену. Для того, чтобы как-то воздействовать на дверь, нам нужно иметь ссылку на её объект, поэтому создадим у кнопки новую переменную.

GameObject это класс, в который заворачиваются все-все-все объекты на сцене, а значит у них у всех есть функция SetActive, которая представлена в инспекторе галочкой в левом верхнем углу. Если вы ещё пользуетесь Unity третьей версии, то вам придётся воспользоваться альтернативами. С помощью свойства активности можно прятать объекты не удаляя их. Они как бы пропадают со сцены и их коллайдеры перестают участвовать в расчётах. Прям то, что надо для двери. Приводим код к следующему виду:

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

открытый код игры на юнити

Наезд колобком на кнопку автомагически растворяет дверь и возвращает её на место после разъезда. Но какой толк нам от кнопки, которая постоянно выключается и запирает нам дверь? Настал час ящиков! Копируем префаб стенки, называем его «Box», добавляем к нему Rigidbody, не забываем проделать те же самые операции, что и с Player’ом, а затем кидаем его на сцену.

открытый код игры на юнити

Как вы наверное заметили, толкать ящик не очень-то удобно. Кроме того, если он застрянет в углу комнаты, то достать его будет невозможно. Как вариант, мы можем сделать зоны-телепорты по углам комнаты, которые будут перемещать все попавшие в них ящики, но это немного мудрёно. Добавим в PlayerController магнит, который будет притягивать все близлежащие ящики. Функция Input.GetButton в отличие от Input.GetButtonDown будет возвращать true до тех пор, пока нажата запрашиваемая кнопка. То, что нам нужно.

Как мы будем находить ящики? Вариантов множество, например, мы можем прицепить к Player’у ещё один коллайдер и регистрировать OnTriggerEnter или OnTriggerStay, но тогда нужно будет решать проблему раннего реагирования триггера кнопки. Помните ту ссылку на матрицу с разными коллайдерами? Вот-вот. К тому же магнит должен работать только по нажатию кнопки, в остальное время он не нужен. Поэтому мы будем вручную проверять столкновения с помощью Physics.OverlapSphere. Transform.position даст нам координаты центра колобка. Поищем объекты поблизости:

Поищем объекты, практически касающиеся колобка.

Нашли объект в большой сфере, проверили его наличие в малой сфере, проверили метку, двинули к себе. Немного математики с векторами, ничего сложного для тех, кто не прогуливал школу.

открытый код игры на юнити

Ящик всё равно нас немного толкает, не не будем сейчас на этом заморачиваться, в движении всё равно это не мешает.

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

открытый код игры на юнити

Если в поле коллайдера попадает два объекта, а потом один объект уходит по своим делам, то срабатывает лишнее выключение кнопки. Что делать? Нам нужно считать количество колобков и ящиков в области коллайдера и выключать кнопку, когда рядом никого нет, а включать при любом количестве тех и других. К сожалению, в Unity нет списка текущих столкновений. Очень жаль. Возможно, у разработчиков ещё не дошли до этого руки. В любом случае это решается парой строчек кода. Мы можем сделать свой список и складывать в него все приходящие объекты, вынимать все уходящие, а состояние кнопки менять в Update.

Lertmind предложил вместо списка использовать счётчик. Этот способ однозначно изящнее, но старый код оставляю выше для примера, как не надо делать.

Сцены, частицы и шейдеры

У нас есть игровой персонаж, стены, кнопка и дверь, но за ней ничего не скрывается. Пора уже сделать перемещение между уровнями.

Дублируем префаб стенки, переименовываем в «Finish», меняем метку на одноимённую, превращаем коллайдер в триггер. Создадим материал «Finish Mat» с манящим голубеньким цветом и повесим на финиш.

открытый код игры на юнити

Вся семья в сборе. Но как-то не очень маняще и слишком похоже на стенку. И на дверь. И на кубик. На помощь приходят шейдеры! Сейчас у нас для всех материалов используется обычный матовый диффузный шейдер. В свойствах материала выберем для финиша Transparent/Specular. Этот шейдер будет учитывать альфу цвета и отсвечивать вторым цветом, который мы укажем. Поставим у голубенького альфу в половину, а отблеск сделаем белым. Тестируем.

открытый код игры на юнити

Осталось заставить финиш перемещать игрока на следующий уровень. Для управления сценами в Unity есть несколько полезных функций и переменных. Application.loadedLevel покажет нам текущий уровень, Application.levelCount покажет их количество, а Application.LoadLevel загрузит желаемый. Кроме того, нам нужно указать в Build Settings все сцены, в которые мы хотим попасть. Создадим новый скрипт «Finish», повесим на префаб и напишем внутри следующее:

Мы проверяем, что на финиш попал игрок, а потом перемещаемся на следующий или первый уровень. Дегустируем наш новый полнофункциональный финиш.

Эстетика, динамика и механика

Вот наш прототип и готов. Мы теперь можем нажимать на кнопки, открывать двери и переходить с уровня на уровень. Если мы хотим только протестировать новую механику, то этого достаточно. Но если мы хотим сделать прототип игры, то нужно думать ещё об эстетике и динамике. Возможно вы не часто слышали эти термины в применении к играм. Если вкратце, то механика — это какое-то взаимодействие пользователя с игровым миром. Кнопка, которую может нажать пользователь, чтобы открыть дверь, это одна механика. Ящики, которые тоже могут нажимать кнопки — другая. Механики взаимодействуют друг с другом и создают динамику игры. Игрок нашёл ящик, дотащил до кнопки, открыл дверь, перешёл на другой уровень. Эстетика — это ощущение от игры. Бывало ли у вас в какой-нибудь стрелялке чувство, что вы действительно нажимаете курок? Приятная отдача, анимация, звук — всё это влияет на эстетику стрельбы. На эстетику игры в целом влияет множество факторов, от скорости загрузки до сюжета. Кропотливая работа над эстетикой отличает игры-однодневки от игр, которые помнят.

Посмотрим на наше творение. Самая часто используемая механика — передвижение. Давайте внимательно посмотрим всё ли у неё в порядке. Открываем код.

Если приглядеться, то видно, что по диагоналям наш вектор длиннее, а значит больше и прилагаемая сила. Можно исправить это нормализовав вектор:

А можно это не исправлять. Особенности игрового движка тоже могут быть частью эстетики. Quake 3 без распрыжек был бы совсем другим. Именно знание тонкостей механики отличает новичков от летающих демонов-убийц профессиональных игроков. Но тонкости не должны вредить удобству, именно поэтому мы ранее поменяли Drag у Rigidbody игрока на четвёрку. Такое трение заставляет колобка останавливаться быстро, но не сразу. А большое ускорение даёт чувство контроля. В идеале, старт тоже должен происходить не сразу, это пригодилось бы для точных манёвров. Эти маленькие детали механики влияют на общую эстетику.

Вглядываемся сильнее и замечаем, что… Видите? Нет? Скомпилируйте проект и поставьте настройки на минимум. Здорово колобок летает, правда? Да так шустро, что пролетает коллайдеры насквозь. Это всё из-за функции Update в скрипте управления, которая выполняется в каждом кадре. Если игра ускоряется в два раза, то и все силы прикладываются в два раза чаще. Для решения этой проблемы можно просто поменять Update на FixedUpdate, который не зависит от частоты кадров, а обноляется по таймеру. Если бы для движения использовался не Rigidbody, а Transform, то проще было бы отвязать перемещение от FPS с помощью Time.deltaTime.

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

открытый код игры на юнити

Внешний вид игры тоже имеет большое значение. Под внешним видом я подразумеваю не количество полигонов в кадре. Помните, игры это искусство. Какие вещи важны в смежных видах искусства? Стилистика, цвет, свет, тень. Попробуйте найти интересное сочетание цветов здесь или соберите свой набор здесь. Посмотрите например на Proun. Эта игра выполнена в духе супрематизма, так близкого хабру. Можно попробовать скопировать некоторые цветовые решения, но без текстур и колдовства с шейдерами получится не так красиво. Нетерпеливые уже посмотрели результат моей попытки по ссылкам наверху, а внимательные читатели могут увидеть их ещё раз в конце статьи.

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

Заключение

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *