Привет, Хабр!
Это моя первая статья, поэтому для начала представлюсь. Меня зовут Виктор, мне 40 лет, из которых почти 20 я на разных ролях участвую в разработке различного программного обеспечения для крупных корпораций (в основном финтех). Путь был долгий и тернистый, но сейчас я занимаю роль Системного архитектора и по совместительству Руководителя направления интеграции.
Я всегда любил игры, у меня даже был собственный канал с летсплеями и обзорами разных игр, который, к сожалению, не сыскал успеха. Несмотря на это, около двух лет назад я решил с ноги ворваться в мир геймдева. Ничто не предвещало беды, просто одним февральским вечером будто щелкнуло что-то в мозгу - ХОЧУ… ДЕЛАТЬ… ИГРЫ…
Я человек самодостаточный, так что если хочу, значит, делаю. И на самом деле это очень интересное ощущение - в 40 лет почувствовать себя беспробудным джуном в той области, в которой совершенно ничего не понимаешь, но тебе так интересно.
С чего начать? Паника первого шага
Первые недели были похожи на блуждание в тумане. В корпоративном мире у меня есть имя, репутация, я понимаю каждый процесс и знаю, к какому специалисту обратиться с любым вопросом. Здесь же я был чистым листом.
Мой внутренний архитектор сразу же попытался выстроить «стратегию»:
Выбор движка. Начал с банального гугления «какой движок выбрать для новичка». Unity vs Unreal Engine - это холивар, который для новичка звучит как спор о преимуществах космических кораблей, когда ты не умеешь водить машину. После недели изучения остановился на Unity. Я хорошо знаком с Java, они с C# как братья близнецы, а вот “плюсы” в моей жизни были слишком давно. Плюс, сообщество казалось более дружелюбным к инди-разработчикам.
Первый “Hello, World!”... который в геймдеве превращается в “Hello, Cube!”. Помню этот детский восторг, когда я заставил красный куб вращаться по нажатию кнопки. Это было волшебство. Но эйфория быстро сменилась осознанием: между вращающимся кубом и даже самой простой игрой - пропасть.
От корпоративной Java к Unity API
Знание Java из enterprise (и, соответственно “Узнавание C#”) не подготовило меня к работе с Unity API. В корпоративной Java ты работаешь с классами, коллекциями, базами данных. В Unity - с GameObject, Transform, Rigidbody, Collider.
Конкретный пример: "Простейшая задача - заставить объект двигаться”. Вместо привычного цикла или таймера, я столкнулся с Update() и FixedUpdate(). Понятие Time.deltaTime для независимости от частоты кадров стало небольшим открытием. Вот мой первый “движок” для куба:
public class SimpleMover : MonoBehaviour{ public float speed = 5.0f; void Update() { //Вначале я делал так: // transform.position += new Vector3(speed, 0, 0); // Но потом прочитал документацию: float movement = speed * Time.deltaTime; transform.Translate(movement, 0, 0); }}
Стена: когда 20 лет опыта мешают
Самым неожиданным для меня стало то, как мой богатый опыт в enterprise-разработке мешал мне.
Перфекционизм vs Прототипирование. В финтехе любая строчка кода - это потенциальные миллионы убытков или риски для безопасности. Все должно быть идеально: архитектура, паттерны, документация. В геймдеве на ранних этапах главное - скорость итераций. “Сделал работающий прототип? Отлично! Выкидывай и делай заново, но уже с новыми знаниями”. Мой внутренний архитектор плакал, когда я видел свой “говнокод”, но играющий прототип уровня “собери 10 монеток” приносил несоизмеримо больше пользы.
Архитектурная битва: MonoBehaviour vs Чистый C#
Мой перфекционизм архитектора требовал создать абстракции для всего. Я пытался делать GameEntity, ICharacterController и инжектить зависимости, но сталкивался с тем, что MonoBehaviour не любит сложных конструкторов и живет в своем собственном жизненном цикле.
Конкретный пример: я потратил день, пытаясь заставить систему управления состоянием персонажа работать через интерфейсы. В итоге, для прототипа оказалось достаточно простого конечного автомата прямо внутри MonoBehaviour:
public class SimplePlayerController : MonoBehaviour
{
public enum PlayerState { Idle, Running, Jumping }
public PlayerState CurrentState { get; private set; }
void Update()
{
switch (CurrentState)
{
case PlayerState.Idle:
if (Input.GetKey(KeyCode.Space)) CurrentState = PlayerState.Jumping;
break;
case PlayerState.Jumping:
// Логика прыжка...
break;
}
}
}
Вывод: Я осознал, что на прототипировании не нужно бороться с экосистемой движка. MonoBehaviour - это и есть твой основной строительный блок, и сначала нужно научиться эффективно использовать его, а уже потом придумывать надстройки.
Сложное vs Простое. Мой мозг сразу же начинал выстраивать сложные абстракции и системы данных для игры-платформера. А нужно было просто заставить персонажа прыгать и не падать сквозь пол. Я потратил три дня на проектирование “масштабируемой системы управления игровыми сущностями”, вместо того чтобы просто сделать десять платформ.
Проблема коллизий: 2D vs 3D физика
Конкретный пример. Создавая свою первую 2D-игру, я по привычке использовал Rigidbody (который по умолчанию 3D) и долго не мог понять, почему коллизии не работают. Оказалось, для 2D нужен Rigidbody2D и коллайдеры BoxCollider2D. Это кажется очевидным, но для новичка - час-два гугления. Понимание разницы между OnCollisionEnter и OnTriggerEnter было еще одним ключевым моментом.
Синдром самозванца... наоборот. В корпорации я - эксперт. Здесь я - ноль. Было непривычно и даже унизительно смотреть 40-минутные туториалы на YouTube, чтобы понять, как работает Rigidbody. Приходилось заново учиться быть учеником: не бояться задавать глупые вопросы на форумах, признаваться в незнании и принимать критику.
Что же помогло? Три столпа выживания
Несмотря на все трудности, я не сдался. Мне помогли три вещи, которые я вынес из своего “прошлого” опыта.
Дисциплина. Я не ждал вдохновения. Я выделил под геймдев ровно 10 часов в неделю (два вечера по будням и одно воскресное утро) и жестко их придерживался. Это был мой “технический долг” перед самим собой.
Умение учиться. За 20 лет в IT я сменил с десяток технологий. Я давно понял, что главный навык - не знание конкретного фреймворка, а умение находить и усваивать информацию. Этот навык оказался бесценным.
Сообщество. Я нашел локальное сообщество инди-разработчиков. Видеть, как другие, такие же энтузиасты, сталкиваются с теми же проблемами, что и ты, и вместе искать решения - это невероятно мотивирует. В корпоративном мире ты часто варишься в собственном соку, а здесь - чувствуешь себя частью чего-то живого и творческого.
Технические инсайты: что я вынес спустя два года
Вот несколько конкретных технических уроков, которые могут быть полезны другим новичкам:
1. ScriptableObjects — лучший друг архитектора
Эти объекты стали для меня открытием. Я использую их для хранения данных о врагах, настройках оружия, конфигурации уровней. Это чистейшие данные, которые не привязаны к сцене, и их можно менять в рантайме, что идеально ложится на мой опыт работы с конфигами в enterprise.
[CreateAssetMenu(fileName = "WeaponData", menuName = "Game/Weapon Data")]
public class WeaponData : ScriptableObject
{
public string weaponName;
public float damage;
public float fireRate;
public GameObject projectilePrefab;
}
2. Оптимизация Draw Calls
Когда количество объектов на сцене перевалило за тысячу, игра начала тормозить. Статический батчинг и использование Атласов для спрайтов решили проблему. Я научился пользоваться Профайлером и Frame Debugger — инструментами, без которых в геймдеве никуда.
3. Работа с Asset Bundles и Addressable Assets
Для моей текущей комплексной игры стало ясно, что ресурсы нужно подгружать динамически. Изучение этой системы изменило мой подход к организации контента. Вместо ручного перетаскивания ассетов на сцену, я теперь думаю о том, как они будут загружаться в память и выгружаться из нее.
public class AssetLoader : MonoBehaviour
{
public async Task<GameObject> LoadAssetAsync(string address)
{
var handle = Addressables.LoadAssetAsync<GameObject>(address);
await handle.Task;
return handle.Result;
}
}
И что в итоге?
Прошло почти два года. Я не создал новый “Ведьмак” и даже не разбогател. Но я сделал несколько джем-игр, пару небольших, но законченных казуалок для мобилок. А сейчас я полностью погружен в разработку своего первого комплексного проекта. Это амбициозно, сложно и невероятно увлекательно.
Это по-прежнему хобби, которое отнимает все свободное время, которого и так немного, но оно того стоит.
Так что же я получил, сменив уютное кресло архитектора на нелегкий путь джуна в геймдеве?
Оживление ума. Изучение совершенно новой области встряхнуло мой мозг так, как никакие корпоративные тренинги не могли. Я снова почувствовал азарт первооткрывателя.
Новое видение своей основной работы. Невероятно, но эти “игрушки” сделали меня лучше в моей основной работе. Я стал проще относиться к прототипам, чаще применять подход “сделай-проверь-переделай” и ценить быстрые итерации.
Чистое творчество. В корпоративном мире твой успех измеряется в KPI, ROI и выполненных спринтах. В геймдеве (на моем уровне) успех - это момент, когда твой друг смеется от придуманной тобой глупой механики или когда ты сам ��олучаешь удовольствие от геймплея, который создал. Это невероятно заряжает.
Резюме для тех, кто думает так же
Если вам за 30, 40, 50, и у вас в голове зажегся тот самый “огонек” - не гасите его. Неважно, геймдев это, керамика или Data Science.
Ваш опыт - не якорь, а балласт, который поможет вам не сбиться с курса. Вы уже умеете учиться, планировать и доводить дело до конца. Вам будет сложно, некомфортно и временами стыдно за свои “детские” ошибки. Но ощущение, когда ты преодолеваешь очередную “стену” и видишь результат своего труда - бесценно.
Это не призыв бросить работу и ринуться в омут. Это напоминание, что можно быть серьезным архитектором днем и безумным джуном-геймдевом по вечерам. И в этом безумии есть своя гармония.
А у вас был подобный опыт? Пробовали ли вы кардинально сменить фокус в зрелом возрасте? Делитесь в комментариях!
