Pull to refresh

История персонажа: менеджеры звука, рекламы и языка в Unity3D

Reading time 15 min
Views 6.1K
Меня зовут Элай и я… червь.

Да-да, Вы не ослышались. Самый обычный кольчатый червь, который сейчас скачет по клавиатуре и переставляет грузики, чтобы Вы, мой дорогой читатель, могли насладиться знаками препинания и заглавными буквами. Однажды я издам книгу «Быстрая печать на клавиатуре для кольчатых червей и их зомби-половинок за 23 года». Возможно, до конца этой книги не доживет ни один червь, но должен же быть какой-то изъян в совершенно безукоризненной книге.

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

Еще у нас есть геймдизайнер (Г). Я вообще не понимаю: что это за человек и зачем он нужен? Его я ни о чем не просил и не уговаривал, хотя, мне кажется, что он думает наоборот. Или я думаю наоборот. Или он думает, что я думаю наоборот. Короче, кто-то из нас благодаря кому-то лихорадочно рекурсивно думает, периодически переполняя стек. Я как-то слышал, что он придумал Идею, но что за Идея, и зачем она нужна, я так и не выяснил. А объяснять никто не хочет. Так или иначе, эти люди держат меня за спятившего червя, когда я пытаюсь убедить их в том, что моя история межгалактического спасения вселенной может быть кому-то невероятно интересна. Хотя я начинаю готовиться к открытию фан-клуба.

Итак, эпохальная история. Началась она, как и все великие дела — в 5 утра (как минимум в одном из часовых поясов явно было 5 утра). Мои Создатели прознали о грядущей опасности инопланетного вторжения, грозившей всем мобильным девайсам планеты Земля. Но будучи людьми благородными, они не стали поднимать шумихи, а начали осторожно набирать команду. У меня тут, кстати, осталось первое письмо отправленное для П. от Г.

image


Правда красавчик? Буду показывать своим внукам. Буквально первое «дофронтовое» письмо. Хотя, если бы П. прождал еще пару недель, этой статьи могло бы и не быть. Вернее, её и так нет. Но могло бы и совсем не быть. Как и меня. Как и Вас, мой дорогой читатель.

Создатели долго копошились с выбором идеального героя спасителя. Оно и понятно, ведь было столько критериев для поиска, которым герой должен был отвечать: быть червем, быть кольчатым, имя должно начинаться на «Э» и заканчиваться на «лай» и по возможности он должен быть немного эластичным. Долго превозмогая сложнейший конкурсный отбор, я успешно прошел все испытания. Жаль, правда, что не было других претендентов, возможно, так было бы интереснее. Но с другой стороны, я их понимаю. Мало кому хочется рисковать своей жизнью ради других.

Для меня же это хобби.



Измерение и пространство, выбранное для моих испытаний и для моего становления как супер героя, называется Unity3D. Когда я спросил П., почему именно Unty3D, он многозначительно сверкнул очками и сказал мне: «Потому что лень». Я был обижен, потому что совершенно не понял, что именно он имел в виду – выглядело как издевка. А ведь пару раз я видел, как он с пеной у рта доказывал кому-то про гибкость, кросплатформенность, бесплатность, сишарпность, ООПшность, офигенность, VisualStudioPluginость, большую комьюнитинность и прочую %text%ность. А потом ворчал себе под нос, что-то про текучие абстракции, когда работал с потоками и коорутинами в моей нервной системе. Мне кажется, что он чертовски предвзят. Уверен кто-то из «людей свыше» доплачивает ему, чтобы он пиарил Unity3D. Да он даже по выходным обмазывается Unity3D и бегает по Интернет, зазывая всех кодить на C# и писать коорутины. А еще он знает один отличный-действительно-смешной анекдот. Но об этом потом. Идея в том, что его мозг полностью захвачен одержимой идеей творить в измерении Unity3D, которое и стало моим полигоном. Поправляли мой здоровье сначала в MonoDevelop (примитивными Debug.Log() Debug.Error() и Debug.Break() ), но потом перешли на более современные и действенные препараты в виде VisualStudio 2015 Comunity Edition в купе с бесплатным плагином от Visual Studio для Unity3D. Это дало возможность дебажить каждый кадр, устраняя причины болезни, вместо того чтобы драпировать симптомы. Что интересно – Debug.Log() не хило так жрет производительность на билде — особенно, если он в методе Update(). Поэтому из меня кропотливо вытаскивали (закомменчивали) все операционные инструменты (дебаговый вывод в консоль) перед сборкой.

Правда, есть небольшой нюанс. Крохотный.

Я был его первым проектом.

Самым первым.

Как бы вам объяснить чтобы Вы поняли, мой дорогой читатель… А!

Ну вот:



Этот сумасшедший думал, что иметь “3D” в названии игрового движка вполне достаточно, чтобы надеть стереоочки и писать игры в трехмерном пространстве. Не имея нормальных шейдеров и опыта работы со светом. Просто смешно. Как эти люди надо мной только не издевались – увеличивали количество полигонов, выворачивали мне нормали, перекручивали мне руки, светили лампочкой в лицо. Результат мало походил на ожидания. Как в итоге сказал Г.: «Да! Этот точно не наш герой!» В итоге меня привели в человеческое двухмерное измерение, и я стал потрясающ и неотразим. Меня даже можно было трогать руками.



Знаете, какую важную штуку я понял за время работы с этими парнями? Я осознал, что такое настоящая команда. Вы уж поверьте, я тут поспрашивал пару птиц и растений с соседних ферм. П., не только всегда безукоризненно реагировал на малейшее замечание других, но еще и сам проявлял инициативу, вкручивая свои фичи и идеи. При этом все прекрасно понимали: что сделано сегодня (потрачены гигатметры нервосил и стройматериалов), то завтра может оказаться в мусорном ведре (это еще, если повезет и нажмут Delete без Shift’а). А бывало и наоборот — забавные баги перетекали в механику.

Я, например, до сих пор не знаю, куда делся мой нос и уши и… а нет.

Все в шлеме.

Фух.

Интересно, что самое сложное было научить игрока мной управлять. Я считал себя довольно покладистым парнем, но миф об интуитивном управлении был довольно быстро рассеян. Г. больше всего заморачивался именно с туториалом, чтобы помочь игроку понять, что нужно «начинать» свайп на моей территории, а заканчивать в любой точке экрана. Говорят 30% игроков отвалилось именно на моем туториале. Тридцать процентов… Мы боялись потерять даже одного. Поэтому по-быстрому собранный консилиум, едва набрав кворум, решил вырезать этот элемент космического симулятора из моего казуального мира.

Вот небольшое МРТ моего мозжечка. Думаю, специалисты быстро смекнут принципы моего телепания.

// Отключаем мультиач
Input.multiTouchEnabled = false; 
 
if ((Input.touchCount == 1)){ 	
  Touch touch = Input.touches [0];
  // Фаза тача - "Свайп начат, палец прижат к эрану"
  if (touch.phase == TouchPhase.Began){
    // Считываем позицию тача
    p0 = touch.position; 
    // Перевод координаты тача в координату из игрового пространства
		p0_cam = Camera.main.ScreenToWorldPoint(p0);
  }
  
  // Фаза тача - "Палец передвинут"
  if (touch.phase == TouchPhase.Moved){ 
    p1 = touch.position; 
    p1_cam = Camera.main.ScreenToWorldPoint(p1);
    // Поворачиваем и растягиваем червя за пальцем		
  }

  // Фаза тача - "Свай закончен, палец убран с экрана"
  if (touch.phase == TouchPhase.Ended){
    dis = Vector2.Distance(p0, p1);
    // Проверка на дистанцию, чтобы можно было отменить свайп
    if (dis > 5  ){
      //Пульнуть червя		    			
    } else {
      //Отменить свайп
    }
  }
}

В андроиде нет “мышки”. Там есть “тач”. Чтобы его тестить, нужен Android девайс с UnityRemote на борту. Моему П. всегда было интересно — работает ли “тач” в Unity Editor’е на моноблоках с тач-экраном. Тачем управляется только мое туловище, и магазин. Все кнопочки работают на старых добрых методах вида OnMouseDown().

Стоит рассказать про операционный стол, на котором меня собирали. Железо среднее. Два ядра, два гига. Более чем скромно, но для того чтобы компилить хватает. Однако есть три важных момента, без которых меня бы не было. Меня и так нет, но без этого не было бы совершенно:

  • Android-девайс,
  • Mac с последней версией MacOS,
  • iOS-девайс.

Без андроида, во-первых, физически невозможно проверить управление тача. Во-вторых, некоторые сервисы: реклама (кроме UnityAds), баннеры, InApp в Editor’e все равно не потестить (вываливающаяся инфа в консоли за тест не считается).

Плохая новость: без Мака (хотя бы mini) невозможно собрать iOS версию. Даже чтобы попользовать Unity Cloud Build понадобится .p12-файл и provisionfile, которые без Мака не сгенерировать. И уж слишком много подводных камней в компиляции под iOS, чтобы сразу выходить на облако. Само-собой, нужен еще и девайс для тестов, причем, желательно последнего-предпоследнего поколения. Так что, если горите желанием деплоить в апстор, готовьтесь к объемным инвестициям.

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

Из разговора с П.:
Первое, что я делал, когда писал код — просто копировал папки и переименовывал их, подставляя в конец дату и время… Ой, да все так делали поначалу. Я до сих пор считаю этот способ самым надежным способом бекапа. Особенно после случая, когда вместо того чтобы влить ветку фичи в мастера, я сделал наоборот. Кстати говоря, с тех использую только одну ветку — master, о чем стыдливо молчу, но этот разговор же только меду нами, Элай?

Затем встала проблема о последовательной работе на двух компьютерах и я добавил к этому DropBox. При каждом сохранении “кинь-короб” светил мне сообщением о невозможности обновления index.lock файла. Исключил Темп и Library.

Сейчас я, конечно, во всю использую систему контроля версий. Очень рекомендую использовать SourceTree+Git (скачивается при установке SourceTree) + BitBucket. Бесплатно и удобно. Только в отличие от того же дропбокса нужно коммитить каждое изменение проекта. Выглядит как очевидная мысль, но когда только знакомишься с системами контроля версий, то думаешь, что сможешь отследить каждое свое изменение вплоть до каждой точки с запятой (что-то типа бесконечного Ctrl-Z). На деле же оказалось, что сравнения могут быть только между коммитами — своеобразными чекпоинтами. Само собой, можно коммитить хоть каждый символ, но это за рамками здравого смысла (к каждому коммиту нужен комментарий о списке изменений). Поэтому я коммичу и пушу на сервер два-три раза за рабочий день. Фичу закончил — закомитил, запушил.

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

Перед использованием git проект unty нужно немного настроить:

1. Зайдите в меню Edit > Project Settings > Editor
2. Параметр Version Control выставить на Meta Files
3. Параметр Asset Serialization выставить в Forced Text

И добавить в папку с проектом файл с именем “.gitignore“ без кавычек со следующим содержанием.

Файл .gitignore
Temp/*
Obj/*
UnityGenerated/*
Library/*
ExportedObj/*
*.svd
*.userprefs
*.csproj
*.pidb
*.suo
*.sln
*.user
*.unityproj
*.booproj
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
Icon?
ehthumbs.db
Thumbs.db
*.apk
*.rar
*.zip
*.unitypackage

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

PathSource — путь до папки с исходным кодом
Path7Zip — путь до папки c 7zip
PathDropBox — путь конечной папки в DropBox
NameDropbox — имя архива

Bat-файл для создания резервных копий
@ECHO OFF
set CY=%date:~6,4%
set CM=%date:~3,2%
set CD=%date:~0,2%
set TH=%time:~0,2%
set TM=%time:~3,2%
set PathSource=D:\Repo\btbw
set Path7Zip=D:\Program Files\7-Zip
set PathDropBox=D:\Dropbox\#BTBW
set NameDropbox=btbw

echo.
echo Backup started at %TIME%
echo ===============================
echo 5%%.. [Directory copying]
echo f|xcopy /y "%PathSource%" "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\" /e >nul


echo 35%%.. [Directory clearing]
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\.git" rd /s /q "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\.git" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\.vs" rd /s /q "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\.vs" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\Temp" rd /s /q "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\Temp" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\Obj" rd /s /q "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\Obj" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\UnityGenerated" rd /s /q "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\UnityGenerated" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\Library" rd /s /q "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\Library" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\ExportedObj" rd /s /q "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\ExportedObj" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.svd" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.svd" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.userprefs" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.userprefs" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.csproj" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.csproj" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.pidb" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.pidb" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.suo" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.suo" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.sln" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.sln" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.user" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.user" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.unityproj" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.unityproj" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.booproj" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.booproj"
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\.DS_Store" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\.DS_Store" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\.DS_Store?" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\.DS_Store?" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\._*" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\._*" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\.Spotlight-V100" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\.Spotlight-V100" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\.Trashes" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\.Trashes" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\Icon?" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\Icon?" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\ehthumbs.db" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\ehthumbs.db" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\Thumbs.db" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\Thumbs.db" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.apk" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.apk" >nul
IF EXIST "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.unitypackage" del /s "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\*.unitypackage" >nul


echo 40%%.. [File compressing]
"%Path7Zip%\7z.exe" a -tzip "%PathSource%_%CD%%CM%%CY%-%TH%%TM%.zip" -i!"%PathSource%_%CD%%CM%%CY%-%TH%%TM%\" >nul

echo 70%%.. [Archives copying]
echo y | copy "%PathSource%_%CD%%CM%%CY%-%TH%%TM%.zip" "%PathDropBox%\%NameDropbox%_%CD%%CM%%CY%-%TH%%TM%.zip" >nul

echo 95%%.. [Deleting temporary files]

rd /s /q "%PathSource%_%CD%%CM%%CY%-%TH%%TM%\"
del "%PathSource%_%CD%%CM%%CY%-%TH%%TM%.zip"

echo 100%%.. DONE! 
echo ===============================
echo Backup ended at %TIME%.
echo.
pause


Единственная проблема — при распаковке архива с бекапом, в котором отработал такой bat-файл, приходится еще раз переключать платформу для билда.

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

Наверное, немного не в тему, но раз уж зашел разговор о системе контроля версий, то стоит упомянуть и о тикет трекере. Мы использовали RedBooth. Это такое место, где мы выкладывали друг другу простыни из подзадач. Кстати, Элай! Я тут услышал потрясающий анекдот: Заходит гелий в бар...


Честно говоря, я практически ничего не понял из того что сказал П. Но «практически ничего», ведь не так уж плохо для кольчатого червя, а? Если что-то хочешь узнать подробнее, о мой дорогой читатель, пишите в комментарии мне на почту: eli@greensnowgames.com. В комментариях здесь сидят только всякие умные дядьки, для которых то, что пишет П. уже давно является очевидным.

Помимо моего хобби – спасения населения девайсов от инопланетных овощей у меня еще есть работа. Причем эту работу я менял пару раз. Сначала я работал продавцом кнопки «Continue», которая открывалась в главном меню, когда игрок покупал игру. Работка была не пыльная, но прибыли практически не приносила. Пришлось уйти в бюджетную сферу. Деньги здесь стабильные, но небольшие, поэтому приходится подрабатывать сразу в 4х местах: 3 видеорекламы (Charboost, Vungle, UnityADS) и баннеры от AdMob. Чтобы везде успевать и нигде не запутаться, мне даже пришлось нанять менеджера, благо хотя бы работа везде более-менее однотипная. Вот должностная инструкция моего менеджера, кропотливо прокомментированная П.

AdManager.cs

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

Из разговора с П.:
Элай, с ним все просто. После того, как внедрены нужные библиотеки, где-то в коде указывается:
If (AdManager.IsReady()) {
 AdManager.me.ShowAd(AdManager.Reward.Coin);
}

Менеджер ищет, какой сервис уже закэшировал рекламу и, в зависимости от этого запускает метод Show() этого сервиса. Напимер, если выстрелил евент Vungle. onAdFinishedEvent, сообщающий о том, что реклама успешно просмотрена до конца, то управление передается на делегат AdManager.OnAdFinished, в котором уже запускается метод GiveReward(). Последний метод, собственно, и выдает “пряничек” закодированный магическим номером. Элай! Ты в тот раз не дослушал один потрясающий анекдот! Так вот, заходит гелий в бар, а бармен ему говорит – мы инертные газы не обслуживаем, а гелий…


Рекламный менеджер – не единственный нанятый работяга. К сожалению, я всего лишь кольчатый червь и много чего попросту не имею. К примеру, мой дорогой, читатель, я не умею говорить. Х. нарисовал мне язык, а в команду пригласили нового человека – Музыканта (М.). Но ни Х. ни М., ни даже П. не смогли наделить кольчатого червя голосовыми связками. Поэтому было принято решение призвать за небольшую долю от продаж менеджера по словоблудию. Правда в этот раз менеджером стала девушка с именем Voman (от Voice Manager).

Как и в предыдущем случает вот её должностная:

VoiceManager.cs

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

VoiceManager.me.PlaySound(myClip);

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

Но даже они не могут иногда найти со мной общий язык. Быть может (я сужу по своей компании), в любой компании есть люди, которые мало общаются между собой, хотя при этом находятся в этой самой общей компании. Что же их объединяет? Наверное, другие люди. Люди, через которых они получают доступ друг к другу. Я называю таких посредниками. Они есть и в нашей компании. Целых двое братьев по фамилии “Синглтон”. Первый посредник существует от сцены к сцене — его зовут «Татор». Его поля прописаны или вычислены в его внутренней логике, а доступ к ним всегда можно получить через static. Не могу вспомнить тусовки, в которой бы он не участвовал. Второго зовут «Меди» – посредник внутри одной сцены. Его я вижу пореже, но если уж вижу, то буквально на него молюсь. Он знает все и про всех, но только внутри этой конкретной тусовочной сцены.

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

Работают братья примерно по тому же принципу, что и менеджеры, только не имеют конкретной специализации, а просто… посредничают? Словом, они – душа нашей компании. Мне иногда кажется, что вся наша работа лежит на их широких плечах.



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

Или нет…

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

Дело в том, что у меня есть мечта.

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

LanguageManager.cs

А вот вторая часть. Я помечаю этой логикой объект, который хочу перевести. Предварительно я несколько ночей кропотливо перевожу плашку и подкладываю её в папку Resources/язык. Сразу скажу, что здесь есть объективная проблема: если языка не окажется — игра вылетит. Проверку делать бесполезно, потому что плашки с «эталонным» языком может внезапно тоже не оказаться. Поэтому использовать такой способ необходимо с осторожностью.

LanguageClient.cs

Уверен, моментально возник вопрос: что же такое Messenger и где его взять? Это делегаты. Без этих ребят в пространстве измерений Unity3D (а может и за его пределами) не было бы очень многого. Состоит оно из двух частей – слушатель и вещатель. Вещатель кричит во весь голос разные смешные фразы, а слушатель пытается различить в этих фразах что-то знакомое для себя и отреагировать. Я однажды подглядел, как этот трюк делает П. Здесь можно почитать об этом подробнее:

Advanced C# Messenger

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

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

Встретимся все вместе.

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



Материалы, представленные в статье, можно найти в репозитории гитхаба.
Tags:
Hubs:
+2
Comments 9
Comments Comments 9

Articles