Как я ушел из Asset Server на GitHub

Как только я начал делать Verge, сразу же встал вопрос о системе контроля версий. Опыта с такими системами у меня было немного, всего лишь GitHub, который я использовал при работе над Cover Orange: Journey, в целом это меня устраивало, но в те далекие времена гитхаб с юнити не очень дружили. Поэтому я был открыт для нового. Конечно, работай я один, можно было бы обойтись и без такой системы, но времена разработки в одно лицо прошли очень давно, а системы контроля версий, даже если вас всего двое, во многом облегчают жизнь.

Возможно, вы не знаете, что это. В двух словах: внесли вы изменения в код, изменения эти были некой вехой (починили злой баг, прикрутили новую возможность, а то и просто – сделали рефакторинг или написали камменты к классу), и эту веху неплохо бы зафиксировать на случай, если вы пожелаете отменить свои следующие действия с кодом, если что-то пойдет не так. Немного простых заклинаний, и эти изменения уходят на удаленный сервер, где хранится ваш проект и все предыдущие сделанные в нем (и посланные на сервер, разумеется) изменения. Программа-клиент на вашем компьютере позволяет видеть список всех изменений, просматривать сами изменения (причем, не просто новую версию измененного файла, а именно – изменения, которые вы внесли), откатываться на прежние версии файлов, создавать новые ветки изменений (к примеру, вы хотите попробовать что-то, что не хотелось бы применять ко всему проекту сразу, вы можете сделать новую ветку изменений, вести работу там, возможно даже кардинально переделывая проект, при этом главная ветка, где находится основной проект, будет нетронута. Пока, конечно, вы не захотите этого). Одна из главных особенностей системы – это то, что к проекту на удаленном сервере может  быть подключено несколько человек, и каждый из них будет отправлять свои изменения (или дополнения) в него. Конечно, возможны конфликты, если двое изменяют один и тот же файл, но, как правило, все это без проблем решается системой.

Все это очень, повторюсь, облегчает. К примеру, у вас есть дизайнер уровней. Без системы контроля версий у вас и у дизайнера на ваших компьютерах было бы два обособленных друг от друга проекта. И вот дизайнер изменяет какой-то уровень. И, конечно, хочет, чтобы и вы этот уровень увидели. Что он должен сделать? Во-первых: вспомнить, какие изменения и в каких файлах он для этого сделал. Во-вторых: аккуратно собрать обновленные файлы и отправить вам. С инструкциями, конечно, где что заменить. В-третьих: материться вместе с вами, если оказалось, что среди отправляемых файлов есть файл, в котором поковырялись и вы тоже! Последнее может оказаться самым болезненным, так как, как правило, глядя на код сложно на сто процентов быть уверенным, что изменения в нем делались только там, куда вы сейчас смотрите.

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

g1

Вот такую картинку дизайнер уровней увидит, если запустит программу SourceTreeЯ создал проект, состоящий из одного пустого файла file.txt. На сервере он хранится именно в виде этого одного файла. Теперь на своем компьютере я вписал в этот файл строчку “новые изменения”. Программа постоянно мониторит изменения, которые произошли в папке проекта и, если они есть, вносит их в Uncommited changes (верхняя стрелка). Если дизайнер уровней утром открыл программу и увидел эту строчку, значит ему не приснилось, что он сделал что-то важное с уровнем вчера, и самое время посмотреть что же именно. Нижняя левая стрелка указывает, в каком именно файле произошли изменения. Правая – какие именно изменения в этом файле произошли. Левее строки “новые изменения”, вы видите +, что означает, что в файл была добавлена новая строка.

Теперь пришло время отправить наш уровень на сервер. На панели инструментов находим кнопку Commit. Программа покажет новое окно:

g2

Все, что нужно сделать, это пометить галкой файл file.txt (он переместится в staged files), написать пояснения к изменениям и нажать кнопку Commit.

g3

Под полем с описанием коммита есть галочка (закинуть изменения на сервер немедленно), если ее поставить, по кнопке Commit изменения тут же уйдут на сервер, если нет, то только в локальный репозиторий проекта, а чтобы отправить их таки на сервер, нужно будет потом нажать на кнопку Push.

g4

Теперь строки Uncommited changes у нас нет, потому что изменения уже закоммичены. Называются они так, как мы их назвали в поле описания, и они теперь всегда будут отображать свое содержимое – файл file.txt, в котором я сделал новую строку.

g5

Я сделал еще некоторые изменения в “проекте”. На картинке вы можете видеть, что они заключаются в том, что я добавил новый файл file2.txt,  и сделал изменения в нашем первом file.txt. “Минус” слева от первой строки означает, что строка была удалена, и ниже две строки были добавлены (они начинаются “плюсом”). Я могу послать и эти изменения на сервер, но потом, если вдруг окажется, что они мне не нужны, могу отменить их и откатиться на прежнюю версию проекта, где file2.txt еще не было. Также, если изменения были сделаны по ошибке, или я решил от них отказаться, я могу выделить файл и сделать Discard. Это полностью отменит изменения в этом файле, и он, соответственно, перестанет отображаться в Uncommited changes.

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

Если я попытаюсь принять изменения, которые конфликтуют с моими (например, кто-то, кто тоже подключен к нашему проекту, отправит изменения в файл file.txt до того, как это сделаю я), программа заботливо скажет об этом, укажет конфликтный файл и даст возможность сделать merge – объединить изменения – если это возможно или же сделать это вручную, благо вы будете знать номера строк, где они были сделаны другой стороной. Это, и многие другие возможности этой системы я тут описывать не буду. Во-первых: это за рамками этого поста. (А во-вторых: я не очень-то профи в этом высшем пилотаже. Больше того, меня уже половина пользователей систем контроля версий заплюет за этот пост, потому что они не пользуются программами клиентами, а работают в командной строке. Таких людей я очень уважаю и немного боюсь.)

Как бы то ни было, начав работать с юнити, я стал пользоваться системой контроля версий под названием Asset Server. Эта штука встроена в юнити (небесплатно, конечно, точно не помню, но что-то около 500 долларов, не знаю, как сейчас). Штука эта оказалась весьма примитивной, непростой в настройке, а в довершение ко всему еще и медленной. Для нее пришлось заводить сервер на Azure, чтобы там работал сам сервер системы контроля (дополнительные траты), чтобы он вообще заработал там также пришлось помудрить. В работе Asset Server очень нестабильный, иногда (мы уже почти поняли, когда это происходит, и это очень грустно) он отправлял все изменения на сервер, хотя требовалось отправить только пару файлов, бывало, что ему казалось, что проект у нас совсем пустой и нужно скачать все изменения заново. А это очень болезненно, потому что скачивает изменения с сервера он с крайне черепашьей скоростью (и дело тут не в ширине интернет-канала), а когда проект начинает весить гигабайты, полное скачивание проекта с сервера может занять долгие часы. В довершение ко всему хваленый юнитиевский Cloud Build (когда билд проекта для разных платформ собирается на серверах юнити) не работает с юнитиевским же Asset Server. Не то чтобы я хотел Cloud Build, но это стало последней каплей.

Камрады уже давно и успешно пользовались GitHub для своих проектов на юнити, несколько дней назад я понял, что время настало. На github.com вы регистрируетесь, платите несколько долларов в месяц за то, чтобы ваши репозитории были приватными (если вы работаете в открытую и не скрываете свои исходные коды ни от кого, тогда никаких денег тратить не придется), создаете репозиторий и указываете при создании, какого типа нужно сделать специальный файл .gitignore. Файл этот нужен для того, чтобы система контроля версий не возбуждалась на изменения в каких-то конкретных файлах. Например, сам проект юнити состоит из двух папок: Assets и ProjectSettings. Также есть папки Library, obj и Temp, где юнити хранит всякую вспомогательную информацию для проекта: временные файлы, кэш шейдеров, различную метаинформацию, билды каких-то библиотек. Изменения в этих папках нужны только для локальной машины, отправлять на сервер их ни к чему. Но системе контроля версий об этом нужно сообщить, для чего и предназначен файл .gitignore. Возиться с его созданием при создании репозитория на github вам не нужно, тамошние ребята сделали удобно:

g6

Просто выберите его из списка.

После того, как вы создали пустой репозиторий на github, самое время перенести туда свой проект на юнити.

g7

Для этого нажмите кнопку Clone в SourceTree, нажмите кнопку с изображением земного шара (Source Path), войдите в аккаунт (если программа не предложила этого раньше) github, укажите Destination Path – папку, где будет храниться репозиторий проекта, и нажмите Clone. Проект с github будет склонирован на ваш компьютер. Теперь самое важное. Откройте проект, который нужно перенести на github, в юнити. Нужно кое-что настроить. Откройте Edit -> Project Settings -> Editor. После чего сделайте в строчках, на которые указывают стрелки, так:

g8

Юнити на какое-то время призадумается, дождитесь окончания этого процесса.

Затем откройте папку проекта юнити и скопируйте в папку, куда вы только что склонировали проект с github, папки Assets и ProjectSettings (и файлы, которые вы лично создали вне этих папок, если такие есть). После чего возвращайтесь в SourceTree, который покажет вам в Uncommited changes все файлы вашего проекта. Жмите Commit, пометьте галочками все файлы, пишите что-то в описании коммита и делайте коммит. Потом жмите Push, чтобы отправить эти изменения на сервер. Возможно, если ваш проект большой, придется подождать.

После этого возвращайтесь в юнити и в меню выберите “открыть проект”, укажите папку, куда вы скопировали папки Assets и ProjectSettings, после чего юнити снова задумается на некоторое время. После чего, собственно, все. Возможно, после того, как юнити импортирует все файлы заново, в SourceTree появятся Uncommited changes, просто закоммитьте их на сервер.

И некоторое добавление: если вы создадите новый префаб, новую сцену или просто добавите файл в библиотеку юнити, в Uncommited changes вы увидите сразу два файла, файл того, что вы создали и такой же файл с дополнительным расширением .meta. Отправлять на сервер нужно оба файла. В дальнейшем, когда вы будете делать изменения в этом файле, .meta в Uncommited changes не появится.

Вот и все. Можете подключать на github.com участников проекта (им тоже нужно будет зарегистрироваться на сайте). Им всего лишь нужно будет склонировать проект на свои компьютеры и открыть его в юнити. Конечно, в самом начале, перед отправкой проекта на сервер github, вы должны убедиться, что все участники проекта отправили все свои изменения на сервер Asset Server, а вы их приняли, и что в процессе того, пока вы переносите проект на github, они не сделали новых изменений.

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

И спасибо @TimNedvyga за то, что надоумил его написать.

Tweet about this on TwitterShare on FacebookShare on Google+Share on VK

Поиграл тут в Skyhill, Train Valley и Party Hard

Я не казуальщик, я люблю проходить игры полностью. Заработал недавно платину (собрав все ачивменты) в “Dishonored”. Выбил платину и в “Wolfenstein: The New Order” (а среди достижений игры есть такое: “Complete game on ÜBER”). Почти уже заработал платину в “Mad Max” (собрал весь лут на карте), но споткнулся об совершенно ужасное управление машиной, которое не позволяло выиграть многие гонки, отсутствие быстрого перемещения к гонке (из-за чего приходилось пилить километры, чтобы ее начать) и ландшафт, который цеплял автомобиль мелкими и неожиданными выступами, из-за чего гонка оказывалась запоротой. Поэтому пришлось отложить Макса на какое-то время. И я люблю небольшие игры. Если небольшая игра сделана хорошо и позволяет получать удовольствие от процесса, играю долго, зарабатываю новые ощущения, наслаждаюсь.

Поиграл тут в демку “Skyhill“. Обнаружил, что ловлю кайф от прокачки, радуюсь когда выпадает клевый лут, самодовольно крякаю, когда ловко валю какого-нибудь гада и не получаю значительных повреждений. Но вот второй раз увидев “Новая игра” в главном меню, понял, что не хочу запускать “Skyhill” в третий. Потому что придется начинать все с самого начала. Да, дадут какие-то пассивные и активные умения, которые иногда даже вредят, чем приносят пользу, но это дела не меняет: я не хочу начинать все с самого начала. И генерация новых комнат ситуацию не улучшает – наказание за смерть слишком жестокое.

Недавно имел разговор с Лешей Flazm‘ом Давыдовым про его “Train Valley“. Как по мне (весь этот текст про “как по мне“, я не могу говорить за остальных игроков, которым все это может “быть ок”. Из чего может следовать, что я заблуждаюсь во многих вещах, связанных с играми, и пора все это бросать и устраиваться менеджером по продажам на придорожный прилавок с дынями), в игре прекрасно все, кроме того, что она наказывает меня за ошибки самым жестоким образом: заставляет начинать уровень (в котором я уже мог провести не один десяток минут) с самого начала, не давая никакой возможности выкарабкаться из банкротства. Я выстраиваю свои железные дороги, делаю красивые развязки, творю! И в один прекрасный момент игра говорит: “бро, ты ошибся где-то. Давай-ка я все это сотру, и ты начнешь свое творчество заново”. Да не стану я начинать. Нету у меня времени (хотя, жизнь моя так устроена, что я могу играть и играю в игры 25-30 часов в неделю) на эти переигрыши. Есть другие, которые не заставляют тебя переигрывать снова и снова одно и то же. Даже если тебе нравится это одно и то же. Даже если будут вариации (в виде сгенеренного заново ландшафта). Это одно и то же, это боринг. Надеюсь, что Леша учтет мои пожелания, потому что желаю ему только лучшего в общем и еще лучших продаж в частности.

Я могу ошибаться, и вполне может случиться так, что в полной версии игры “Skyhill” все не так, что там есть сюжет, что там нет возвращения к самому началу, что есть какие-то чекпоинты и возможность пополнить здоровье или немного утолить голод поедая убитых монстров или глодая ножки столов (чтобы была возможность в каких-то точках немного восстановить здоровье так, чтобы опять появился смысл играть дальше. Баланс, конечно, в этом случае нужно соблюдать еще лучше). Если же нет, то в голову приходит только один совет: не сбрасывать прокачку героя. Тогда, конечно, это уже будет не “новая игра” в главном меню, а как-то иначе, но зато каждый сеанс будет определенно вносить лепту в общий прогресс игры. То есть, вот я проиграл во второй раз, дошел до 81, кажется, этажа. Каких-то новых умений для третьего раза мне не дали, весь мой прогресс ушел вникуда, второго раза как будто и не было (хотя досада осталась и минут 15 из жизни стерлись). Сейв, кстати, не помог бы, если я где-то на 80 этаже, и у меня 20 здоровья и голода, я однозначно умру, сохраняйся не сохраняйся.

Почему недавно я бросил “Alien: Isolation”? Потому что отсутствуют чекпоинты, и игра отбрасывает тебя очень далеко назад и заставляет заново ползать по тем же коридорам (хотя она и сама-то далеко не короткая). И ты уже не испытываешь новые ощущения, а ругаешься на Чужого: “давай, скотина тупая, уходи уже! мне в третий раз надо пытаться открыть эту чертову дверь, а до нее еще нужно добежать!” Почему я бросил “The Evil Within”? Да все потому же – загрыз меня очередной гад, игра загружает очень далекий чекпоинт и под злобненький смех геймдизайнера я обнаруживаю, что меня отшвырнуло черт знает куда и нужно заново прибивать уже неинтересных (и кривых) врагов.

Смотрел недавно летсплей тоталбискита. Играл тоталбискит в “Party Hard”. И был момент, когда на главного героя набежала какая-то тетка и запинала его каблуками до смерти. Вот так ни с того ни с сего игра заставила бедного летсплеера проходить уровень с самого начала. С самого начала убивать этих пиксельных сволочей. А их десятки. Тут, конечно, просто помог бы обычный сейв. Можно, чтобы игрок не испортил сейвом ситуацию навсегда, не давать сохраняться, когда по сцене шныряет полицейский. Вот тогда я прошел бы игру и получил бы удовольствие. Пусть не за 10 часов, а за час-два, но я прошел бы ее. Если есть вера в сумасшедших хардкорщиков, всегда можно сделать режим, когда вообще есть только одна жизнь на игру и начинать после смерти нужно с самого первого уровня. В таком режиме я бы не играл, я бы играл в easy с возможностью сейва, но и хардкрощики были бы счастливы вместе со мной.

Вспомните “Super Meat Boy”. Там уровни быстрые, скоротечные, начинать их с самого начала – это не слишком облом, нет жесткой фрустрации после проигрыша (хотя, финальный забег в конце каждой части таки может ее вызвать, но это простительно, он не слишком длинный). Хоть она и хардкорная, но относится к игроку с уважением. Представьте, если в случае смерти она заставляла бы играть уровни с самого начала чаптера, а их в чаптере несколько десятков. Время относительно, кто-то может себе позволить такие забеги, кто-то нет. Как по мне, удовлетворять нужно и тех и других. Я не думаю, что разработчики этих игр скажут: “эта игра для хардкорщиков, не для тебя, не играй в нее”. Но я-то хочу в них играть, мне нравится процесс, дайте мне возможность.

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

Всем пеас!

Tweet about this on TwitterShare on FacebookShare on Google+Share on VK

Простои

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

Блог тоже решил поломаться пару дней назад. WordPress обновился, и блог сказал, что больше не хочет. Чинить так чинить, решено было сменить еще и хостера. Теперь GoDaddy. Быстрый, местами удобный. Посмотрим. Во время поисков обнаружилось, что популярные хостеры делают свои сервисы для инопланетян.

С FDG Entertainment вовсю готовимся к GamesCom. Меня там не будет, врачи пока не велят, зато FDG покажут там Verge. Игра, конечно, еще не финальная, в демке на выставке сюжета не будет, но побегать-поиграть можно будет вполне. Для этого запиливаю специальную версию с самыми годными уровнями.

Дел много. Нужна эта самая версия, какие-то преверсии для рейтинг-группы (которые ищут свастики во всем, что им дают), трейлер (КАКОЙ ТРЕЙЛЕР??? У нас и клон не валялся!), скрины, лого… Все делается в спешке, конечно, это нехорошо, но уже пора вылезать из под плинтусов. Пусть и так скомканно.

Да, игра про клонов, как написано в блоге игры. Расскажу позже.

Verge_FirstScreenshot

 

Tweet about this on TwitterShare on FacebookShare on Google+Share on VK

Why so serious?

Внимательные читатели блога наверняка заметили, что мой профиль, профиль Владимира и даже профиль FDG – казуальные игры. Физические паззлы, развеселенькие персонажи и всякое такое. А тут, стало быть, такие мрачные цвета, ржавая кровать, жутковатое помещение и повязка на глазах у такого же, не слишком вселяющего радостные эмоции, героя.

Для начала, я расскажу, как мы с Владимиром пришли к идее создания 3Д паззла от первого лица. Мы большие поклонники игры Portal (а кто нет?), а если покопать поглубже – паззлов в принципе. Именно поэтому почти все игры, которые создавались с момента начала пути по дороге вымощенной желтым кирпичом с указателем “Геймдев – туда”, были паззлами. С бросанием кубиков, с какой-то физикой, с “из точки А в точку Б” и вариациями, осознанием того, что очень много физических объектов на экране – это к тормозам, и что физика в большинстве случаев только притворяется физикой, и сбросить один треугольник острием на острие другого треугольника так, чтобы первый треугольник не падал, в физике компьютерных игр гораздо проще, чем в реальной жизни, с первыми опытами изменения гравитации… (Ну ладно-ладно, моей первой игрой был “Гвоздоноид”, и он не про физику и паззлы.)

Но с паззлами в 2Д мире стало тесно. Больше того, 3Д выглядело чем-то “серезным”, большим делом, “по-взрослому”. А еще срочно требовалось залить себя чем-то новым, последние игры были самоповторениями, удовольствия в разработке не приносили, становилось грустно.

Помнится, как в декабре 2013 года мы с Владимиром отвлеклись от андроидной версии Cover Orange, и стали сочинять новую механику для 3Д паззла. Дырки в стенах, в одну из которых входишь, а из другой выходишь – это круто, но это было. Изменение гравитации или физических свойств объекта – тоже. Повторять игровой механикой другие игры совершенно не наш путь. Скоро игровая механика созрела, и мы начали прототипировать уровни. Выглядели они вот так (кстати, именно этого уровня в игре уже нет):

level

Об уровнях вам рассказывает Владимир, лишь с гордостью скажу, что они получились очень умными, и на каждом ты растерянно бегаешь из угла в угол и приговариваешь: “а как? а как?” Очень скучаю по такому чувству, очень за него благодарен Portal и Quantum Conundrum. И желание вызвать такое же чувство у тех, кто играет в твою игру, а еще и в 3Д пространстве и было основной причиной Verge.

Никакой истории, никакой комы, никаких повязок на глазах не было и в помине.

Пока я не сказал вдруг: “а если это будет игра про человека в коме? Который ищет из своей комы выход” Сказал и ужаснулся своей оригинальности. Сколько в играх уже перележало в коме людей? Сотни. И каждый искал выход. И всякий раз это было грустно. И мрачно. Может, и без повязки на глазах, но все-равно казалось, что Леди Оригинальность скептически поджимала губы. Так казалось, а оказалось, что игр не так уж и много, что не так уж и поджимала. Посчитав, что тема комы и интересного проведения в ней времени еще недостаточно полно раскрыта, мы остановились на коме.

Кстати, раньше это была не повязка на глазах. Раньше это была медицинская маска:

mask

Но персонаж выглядел совсем жутковато, а издалека напоминал инопланетянина. А сняли маску, намотали ему на голову тряпку (типа, слепой), и его сразу же стало жалко. (Кто назовет фильм, в котором слепого персонажа с повязкой на лице было жалко?)

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

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

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

Вот так.

 

(английский вариант)

Tweet about this on TwitterShare on FacebookShare on Google+Share on VK

Как я работаю с триггерами в Unity

Unity (а Verge мы делаем в Unity3D) позволяет мастерить триггеры. Все вы знаете, что это за штуки. Для тех, кто не знает: триггер – это некий объем, который чувствует, что в него кто-то вошел, находится или вышел. Это нужно для того, чтобы игра умела реагировать на разные игровые события. Например, вешаем некий триггер (который может быть сферой, прямоугольным параллелипипедом или чем-то еще) на дверной проем и, если туда вошел игрок, правильно приготовленный триггер возбудится на это событие и доложит куда следует (обработчику событий игры или тому самому одному классу, в который вы пытаетесь запихнуть всю игру).

Триггеры работают прекрасно, пока вы не начинаете требовать от них всякий маразм. Мой маразм заключается в том, что объект, который вошел в триггер, не всегда может оттуда выйти, он может просто сгинуть посредством Destroy прямо в этом триггере. И события OnTriggerExit не произойдет. Если это какая-то дрянь, которая окрашивается красным, если в нее кладут, например, кубик, дрянь останется красной, если кубик уничтожить без выноса оного из этой дряни.

Честно говоря, в случае какой-то особенной дряни я не использую триггеры. Я использую функцию Physics.OverlapSphere, которая в нужный мне момент генерирует в нужной точке пространства сферу-триггер с нужным мне радиусом, после чего возвращает массив всякой фигни, которую эта сфера наперекрывала. Делать это я могу реже или чаще, обладаю относительно полным контролем, то есть. Мне почему-то кажется, что вызывая эту функцию реже, я экономлю какие-то ресурсы процессора. Скорее всего, это все шизофрения или, как минимум, менингит, потому что таких сфер я генерирую в количестве максимум 6 штук, ну что тут можно наэкономить?

Но есть ситуации, когда кастовать сферу для проверки какого-то объема нецелесообразно. Например, объем, который нужно проверить кодом, разный, а код один, или объем – плоский, и сфера сюда не подходит. Например, есть у нас торчащие из пола кусочки бумаги (“что за херню делают эти ребята???”), если положить на них кубик, они войдут в него, как горячий нож в сливочное масло, а если вошел не весь кусочек, он будет неприятно торчать из кубика у его основания. Делать кусочек физическим – не круто, кубики должны ложиться на пол ровно. Было решено сделать кусочки триггерами, которые могут визуально пропадать, если почувствуют, что в их объем попал кубик. И все прекрасно, кидаем на кусочки кубик, триггеры кусочков, на которые попал кубик, генерируют событие OnTriggerEnter, в котором мы сам кусочек исчезаем. Если же у триггера случилось событие OnTriggerExit, кусочек появляем. Выглядит хорошо, пока мы не решим уничтожить кубик. Событие OnTriggerExit не сработает, кусочек, на котором лежал кубик перед уничтожением, не появится.

(Я только что осознал, что вполне могу получить комментарий, типа: “а, ламер, вот же событие, которое генерируется триггером, если в нем был уничтожен какой-то объект!” Как бы – конфуз. Ну и ладно, хоть кто-то научится чему-то из этого поста).

У триггера есть событие OnTriggerStay, которое генерируется, если в триггере что-то имеется. Как бы это дело и использовать? – подумал я.

Спустя какое-то время скрипения мозгом, придумалось вот что.

(Не густо придумалось, надо сказать.) Это переменные класса. Назначение смотрим ниже.

Ниже – функция OnTriggerEnter, которая будет вызвана, если в триггер что-то попало. Если триггер уже был активирован, ничего не делаем, возбуждаемся только если триггер неактивный. Первым делом активируем триггер флажком _isTriggered, а потом реагируем триггером на вход в него чего-то.

Функция FixedUpdate. Она вызывается движком перед обработкой OnTriggerStay функции (может быть вызван реже, чем Update(), которая вызывается каждый кадр, может чаще), если триггер активирован, просто сбрасываем флажок _isStay; собственно, эта функция нам нужна только потому, что она вызывается строго перед OnTriggerStay.

Функция OnTriggerStay, которая вызывается, если в триггере что-то находится (вызывается для каждого объекта, попавшего в триггер, но нас это не тревожит). Просто устанавливаем флажок _isStay в true.

Функция LateUpdate. Вызывается после (на самом деле, нет) обработки движком всех физических событий. Нас мало волнует так ли это, самое главное, что эта функция не будет вызвана МЕЖДУ FixedUpdate и OnTriggerStay. В LateUpdate мы проверяем – не тру ли наш флажок вызова OnTriggerStay. Если не тру, значит, OnTriggerStay не вызывалась, значит, в триггере ничего больше нет, реагируем триггером на выход (или на исчезновение) из него всех объектов. И сбрасываем флажок активности триггера.

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

Не знаю, почерпнули ли вы что-то полезное из этой простынки, и надеюсь, что в Unity это сделали.

Всем пис.

Tweet about this on TwitterShare on FacebookShare on Google+Share on VK

Немного лжи (из блога игры Verge, русский вариант)

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

Еще раз – это неправда.

Серьезно, не верьте мне.

Я никогда не был в коме. Я даже никогда не был под общим наркозом. Вернее был, но обеспечил его я сам себе в детстве, когда по собственной глупости получил по затылку угловой сталью советских детских качелей. Мне много рассказывают про тот день, я, оказывается, творил жуткие вещи, но для меня он остался монтажной склейкой пленки моего существования. С людьми, вернувшимися из комы, я тоже не встречался; в интернете пишут, что они видели какие-то сны, но подозреваю, что сны эти им показывали уже на выходе, а в самой коме было что-то другое. Или не было ровным счетом ничего. Именно с этого я и решил (это неправда, не забывайте) начать. С ничего. Ну, с почти ничего.

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

Пойду спрошу, не уходите никуда.

 

(английский вариант)

Tweet about this on TwitterShare on FacebookShare on Google+Share on VK

Первый пост (из блога игры Verge, русский вариант)

Добро пожаловать в блог о создании игры “Verge“. Бла-бла-бла, бла-бла-бла, бла-бла-бла.

Вот уже год мы мастерим игру про человека, который лежит в коме. Нет, это не симулятор человека в коме. А, может, и симулятор. Я не знаю, чем занимаются в коме. Возможно, бьют битой по пингвину, возможно, смотрят все серии “Стар Трека” на киргизском языке. Не исключено, что бродят по уровням и решают головоломки. Если знаете, напишите мне.

Мы – это два с половиной человека (на самом деле, три. На самом деле, нет.). И еще FDG Entertainment. Первый человек – это я, Евгений Кузьмин. Меня вы можете знать по играм “Ragdoll Cannon“, “Roly-Poly Cannon” и “Cover Orange“. Второй – Владимир Гусев. Его вы можете знать по играм “Roly-Poly Cannon“, “Cover Orange“, “300 Miles to Pigsland” и “All we need is Brain“. Половинка человека – Леша Бабай. Его вы можете знать по мультфильму “Кочет i курiца” (смотреть строго на работе в присутствии начальника). Половинка он потому что первые двое сидят в одной комнате и пилят игру из нее, а Леша работает с комнатой издалека. А еще совсем недавно к нам присоединилась Ressa M. Schwarzwald. Кто за что отвечает будет описано позже.

И еще есть FDG Entertainment. Их вы тоже можете знать.

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

Оказалось, что могут сделать игру. И скоро доделают. А пока этого не случилось, постараются развлечь вас рассказами о разработке. Любая разработка – это скука большую часть времени, но остальную часть иногда выходит смешно и интересно. Про это и расскажем.

P.S. Посты могут делать разные люди, поэтому, если вы увидите еще одно “Добро пожаловать в блог о создании игры”, это нормально, возможно это Филипп из FDG решил поприветствовать вас менее неформальным способом.

 

(английский вариант)

Tweet about this on TwitterShare on FacebookShare on Google+Share on VK

Игра Verge

Несколько дней назад мы запустили блог нашей игры. Располагается тут: vergethegame.com

Туда пишу я, Филипп (FDG-Entertainment) и Владимир Гусев (VladG).

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

Пишем мы там по-английски. Вернее, я-то заготавливаю посты на русском, Владимир (он умеет) переводит на английский, а Филипп редактирует (он умеет). Если я буду писать по-английски сам, это будет нелепо и смешно, решили, что лучше не надо. Посты получаются несколько отцензурированными Филиппом, наверное, это правильно, неподготовленные могут быть отпугнуты от блога потоком моего сознания. Но русские версии моих постов пропадают. Как вы думаете, стоит ли выкладывать их сюда, если вдруг среди читателей имеются люди, которых английский текст расстраивает больше, чем русский?

Tweet about this on TwitterShare on FacebookShare on Google+Share on VK

Про Азуру

Раз нужен блог, нужен и хостинг. Этот блог хостится у Микрософта с помощью чудо-штуки под названием Azure.

(это не реклама, если Микрософт начнет платить мне деньги вместо того, что я ему плачу, виниловый Стив Джобс у меня на обоях перекрестится)

Азура – это про облака. Все, что вы мастерите в Азуре, вы мастерите в облаках.

Вот что можно смастерить:

a1

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

a2

WordPress тоже есть, как без него.

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

Но это все про хостинг.

Когда мы приступили к работе над проектом, нам понадобилась система версий для юнити. У юнити есть своя, ее и решили использовать. Asset Server должен был крутиться на внешнем сервере (наш художник, он же моделлер, работает удаленно), в связи с чем я вспомнил об азуре. Микрософты дают возможность запилить виртуальную машину в облаке. Также, кстати, с возможностью масштабирования на лету. Лично я выбрал самую убогую конфигурацию, Asset Server вполне работает и на такой. Называется конфигурация А0, общее ядро (не знаю, что это значит), 768 мегабайт оперативной памяти, стоит аренда такого калькулятора пятьсот рублей в месяц. На виртуальную машину можно было поставить много всякого, даже Убунту:

a3

Мак Озь не давали, пришлось поставить Windows Server 2008. Слово Server немного настораживало, ведь я во всем этом еще хуже, чем в английском языке. Но, как оказалось, все было небольно. После небольшой возни, Азура сказала, что сервер готов, можно пользоваться. Я запустил Remote Desktop (для мака, кстати, тоже есть) и получилось вот что:

a4

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

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

И еще одно про виртуальные машины. Собрать в Азуре можно очень неслабую конфигурацию. 16 ядерную со 112 Гб оперативной памяти (на самом деле, можно и с 32 ядрами и 448 Гб оперативки, но мне такое чудовище пока не дают создавать, полагаю, что из-за санкций того, что оно пока еще тестируется). Это, конечно, стоит солидных денег. Если убогое А0 стоит 60 копеек в час, А9 с 16 ядрами и 112 гигабайтами оперативной памяти стоит уже почти 170 рублей в час. Сколько будет стоить G5 с 32 ядрами, боюсь даже представить.

Зачем все это?

Уровней в нашей игре будет 45 штук, и м

ы, типа как правильные девелоперы, будем использовать лайтмаппинг. Для комнаты с дверью, скрины которой я показывал в прошлых постах, запекание теней занимает на моем ядерном реакторе 4 минуты. А это мощный ядерный реактор:

a5

А на А9, который с 16 ядрами и 112 гигабайтами, это занимает уже 2 с небольшим минуты. В два раза быстрее. Учитывая, что запекание – штука частая, времени будет отъедать немало. С 45 уровнями можно провозиться немало. Конечно, 32 ядра могли бы и полторы минуты выдать, но пока так. Всего за 170 рублей в час. И никакой возни – на виртуальной машине устанавливается юнити, присоединяется к системе версий проекта, а после запекания запеченное отправляется всем участникам проекта. К слову, А9 – это еще и мощный интернет-канал, полуторагигабайтный дистрибутив юнити, например, скачивается виртуальной машиной всего за несколько секунд. Если бы еще можно было устанавливать на виртуальную машину Windows XP или Windows 7, было бы совсем хорошо (серверные винды помешаны на безопасности, задают при каждом удобном и неудобном случае массу глупых вопросов).

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

Так и работаем.

Tweet about this on TwitterShare on FacebookShare on Google+Share on VK

Про название и про блог игры

На прошлой неделе придумали название для игры. На самом деле это FDG название придумали, технично отбраковав все наши предложения. Название нам понравилось. Но вслух произносить его нельзя, FDG говорит, что рано, что надо еще немного кой-чего поутрясать. Название состоит из одного слова, слово красивое, означает разное. Что, как мы полагаем, хорошо. Так что, скоро озвучу.

Еще FDG (FDG Entertainment – это мои издатели) сказали, что нужен блог про разработку игры. Филипп показал блог игры Thimbleweed Park, которую мастерит Рон Гилберт, и сказал, что так делают, и что так делать – круто. Раз круто, будем делать такой спец-блог. Вести его будем вместе с FDG, наполнен он будет скринами, мыслями, реализованными и нет идеями. Ругаться про Юнити, наверное, будет нельзя, поэтому ругаться про Юнити буду по-прежнему здесь. Будем стараться, чтобы блог был и на русском, и на английском. С английским у меня особые отношения, поэтому переводить мои русские напевы про игру на английский будет VladG, а я буду помогать ему переводить на русский напевы Филиппа. Конечно, будет тратиться ценное время, которое могло бы быть с пользой употреблено на саму еще незавершенную игру, но FDG меня убедили, что эта затея не менее ценная.

Кстати, решили приделать к игре еще 11 уровней, что в итоге нам дает 45 уровней и больше шести часов геймплея. В блоге, например, могли бы уже написать, почему решили добавить еще уровней. Но блога пока нет, напишем потом.

Такие дела.

Tweet about this on TwitterShare on FacebookShare on Google+Share on VK