Game Development | YeaHub
375 subscribers
151 photos
192 videos
529 links
Теория, подготовка к интервью и курсы для Game Dev разработчиков

YeaHub — это платформа для IT-специалистов, объединяющая обучение, карьерный рост, развитие и сообщество единомышленников.

Платформа: https://yeahub.ru

Для связи: @ruslan_kuyanets
Download Telegram
Как работают Update и LateUpdate

Завершаем цикл постов про методы Update. Сегодня разберём, как ведут себя Update и LateUpdate, если игра подвисает.

Эти методы работают очень просто: кадр вызвался → методы вызвались.

Они не пытаются “догнать” пропущенные вызовы, как это делает FixedUpdate.
То есть один кадр = один вызов метода.

Теоретически при длительном зависмании нас может спасти Time.deltaTime, потому что он учитывает время между кадрами. Но тут есть важный нюанс.

У Time.deltaTime есть ограничение - Time.maximumDeltaTime (в инспекторе это Maximum Allowed Timestep).

Это означает, что значение Time.deltaTime никогда не будет больше ~0.333 секунды.

Подробнее можно почитать в документации:
https://docs.unity3d.com/ru/530/Manual/TimeFrameManagement.html
https://docs.unity3d.com/6000.3/Documentation/Manual/time-handling-variations.html

Как это выглядит на практике

Вспомним простой код движения:

private void Update()
{
transform.position += Vector3.forward * 10f * Time.deltaTime; // 10 м/с
}


Если игра подвиснет на 2 секунды, то Time.deltaTime всё равно будет равен 0.33.

В итоге - ожидали пройти 20 метров, а фактически пройдём 3.3 метра. Потому что deltaTime ограничен.

Можно ли это исправить?

Технически - да.

Можно использовать:

• Time.unscaledDeltaTime - deltaTime без ограничений
• Time.realtimeSinceStartup - реальное время с момента запуска приложения

Но это почти всегда плохая идея для игровой логики.

Если игра подвиснет, объект может “телепортироваться” на большое расстояние.

Кроме этого:
• физика не будет успевать за объектом
• логика станет сложнее
• нагрузка на CPU может увеличиться

По сути, можно раскрутить “спираль смерти”-— когда из-за лагов система начинает лагать ещё сильнее.

Когда это всё-таки имеет смысл


Использовать unscaledDeltaTime имеет смысл там, где важно реальное время, а не игровое.

Например, для таймера UI:

private void Update()
{
_uiTimer += Time.unscaledDeltaTime;
UpdateUITimerText(_uiTimer);
}


А что насчёт LateUpdate?

LateUpdate работает по тем же принципам, что и Update.
Единственная разница - порядок вызова. Сначала Update, потом LateUpdate.

То есть всё, что мы разобрали про Update (ограничение deltaTime, поведение при фризах и т.д.), полностью применимо и к LateUpdate.
Если понимать эти механизмы под капотом, можно без труда отвечать на каверзные вопросы на собеседованиях и, что важнее, писать более предсказуемую игровую логику.

🚀 Пост Guru Unity: @Minerope
Please open Telegram to view this post
VIEW IN TELEGRAM
#Собес #dns #ip
🤔 Что происходит после получения IP-адреса?

💬 Кратко:

После получения IP клиент выбирает маршрут и пытается установить соединение с сервером. Обычно сначала выполняется установление TCP-соединения, а если сайт по HTTPS — дополнительно идёт TLS-рукопожатие. Затем клиент отправляет HTTP-запрос и получает HTTP-ответ. Дальше браузер начинает обработку ответа и загрузку связанных ресурсов.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#video #начинающие
📚 Сборник видео для Джунов

Здесь собраны все видео с канала Лавка Разработчика, которые подходят для тех, кто находится на старте вхождения в видеоигровую индустрию, понимает самые базовые вещи в программировании и хочет развиваться в этом направлении далее

Перейти к материалу

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
2👍1
#Собес #linq #ienumerable #deferred_execution
🤔 В чём заключается классическая проблема с IEnumerable и отложенным выполнением в LINQ?

💬 Кратко:

Классическая проблема возникает, когда LINQ-запрос (который выполняется отложенно) оценивается более одного раза, особенно если источник данных или вычисления внутри запроса изменяются или являются "дорогими". Это может привести к неожиданным результатам (если данные изменились между оценками) или к серьёзным проблемам с производительностью (если сложные вычисления повторяются).

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
1
Давайте немного отдохнём от больших серий статей и разберём один вопрос с собеседования.

"Как бы ты реализовывал тип данных, который даёт значение с точностью до 100 знаков после запятой?"


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

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

Первое, что приходит мне в голову - это использование Nuget пакета для подобной ситуации.
Я знаю точно, что существует решение для случаев, когда тебе нужно очень большое целочисленное число. Пакет называется BigInteger. Я бы поискал нечто подобное в интернете.
Спойлер: решения реально существуют. Библиотеки Mpir.NET и Math.NET Numerics.

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

Третье - попробовать реализовать решение самостоятельно. Как это сделать? Давайте посмотрим на саму реализацию.
using System;
using System.Text;

public static string DivideLong(long a, long b, int digits)
{
if (b == 0)
throw new DivideByZeroException();

// negative будет true, если знаки чисел a и b различаются (одно положительное, другое отрицательное)
// Знак ^ - это побитовая операция XOR (исключающее ИЛИ)
// После этого приводим их абсолютными значениями (убираем минус в начале)
bool negative = (a < 0) ^ (b < 0);
a = Math.Abs(a);
b = Math.Abs(b);

// Целая часть
long integerPart = a / b;
// Остаток
long remainder = a % b;

StringBuilder result = new();

// Добавляется знак минус, если результат отрицательный и при этом не является нулём (условие (integerPart != 0 || remainder != 0) гарантирует, что для -0 минус ставиться не будет
if (negative && (integerPart != 0 || remainder != 0))
result.Append('-');

result.Append(integerPart);

// Разберём детальнее ниже
if (digits > 0)
{
result.Append('.');

for (int i = 0; i < digits; i++)
{
remainder *= 10;
long digit = remainder / b;
result.Append(digit);
remainder %= b;
}
}

return result.ToString();
}


Для каждого требуемого знака после запятой выполняется:
- Остаток умножается на 10;
- Определяется текущая цифра как целая часть от деления полученного числа на делитель b;
- Цифра добавляется к строке;
- Остаток заменяется остатком от деления на b.

Этот цикл повторяется ровно digits раз, формируя последовательность десятичных знаков без округления.

У этого решения есть свои слабые места. Я вижу несколько редких ситуаций, которые могут сломать логику. Но это здесь не так важно.
Главное, что вы:
- Понимаете суть алгоритма и на чём он строится.
- Примерно понимаете как нужно отвечать на вопросы подобного рода.

🚀 Пост Guru Unity: @Minerope
Please open Telegram to view this post
VIEW IN TELEGRAM
1
#Собес #linq #ienumerable #deferred_execution
🤔 В чём заключается классическая проблема с IEnumerable и отложенным выполнением в LINQ?

💬 Кратко:

Классическая проблема возникает, когда LINQ-запрос (который выполняется отложенно) оценивается более одного раза, особенно если источник данных или вычисления внутри запроса изменяются или являются "дорогими". Это может привести к неожиданным результатам (если данные изменились между оценками) или к серьёзным проблемам с производительностью (если сложные вычисления повторяются).

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#Собес #decapsulation #data_processing #osi_model
🤔 Что происходит в модели OSI, когда пакет данных перемещается от нижнего к верхнему уровню?

💬 Кратко:

Когда пакет данных перемещается от нижнего к верхнему уровню модели OSI, заголовки, добавленные ранее, удаляются, и остаются только исходные данные.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#repository #godotengine
📚 Godot Engine

Официальный исходный код открытого кросс‑платформенного игрового движка Godot. Это полноценная среда для разработки 2D‑ и 3D‑игр, включающая редактор, скриптовый язык GDScript (похожий на Python), систему сцен и узлов, инструменты анимации, физику и рендеринг. Репозиторий содержит всю кодовую базу движка, документацию, примеры, а также систему отслеживания задач и обсуждений. Подходит как для изучения архитектуры движка, так и для внесения собственных изменений, создания плагинов или сборки кастомных версий.

Перейти к материалу

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
🔥1
#Собес #addressables #grouping
🤔 Как лучше организовывать группы и бандлы Addressables для оптимальной загрузки?

💬 Кратко:

Группы и бандлы нужно организовывать по логическим модулям: общие ассеты помещаются в shared группы, UI — в отдельные мелкие бандлы, уровни — в крупные пакеты, а preview-ассеты — в отдельные лёгкие группы. Важно контролировать зависимость бандлов, избегать duplication через Analyze Tool, и выбирать тип упаковки (Pack Together / Pack Separately) в зависимости от частоты загрузки. Главная цель — минимальное количество больших скачиваний и отсутствие дубликатов ассетов.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#Собес #transaction_isolation #serializable #concurrency
🤔 Какой уровень изоляции транзакций в PostgreSQL поможет избежать конфликтов при параллельной обработке задач?

💬 Кратко:

Уровень REPEATABLE READ или SERIALIZABLE поможет избежать конфликтов при параллельной обработке задач. Однако в большинстве случаев достаточно REPEATABLE READ, который предотвращает непредсказуемое поведение за счёт повторного чтения одинаковых данных в рамках одной транзакции.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#roadmap #unity #roadmap
📚 Дорожная карта Unity-разработчика 2025: с нуля до джуна

Статья представляет собой дорожную карту для начинающих Unity-разработчиков, которая охватывает весь путь от освоения основ языка программирования C# до работы с физикой, сторонними SDK и другими аспектами разработки игр в Unity. В ней подробно расписаны ключевые темы, которые необходимо изучить: основы C#, объектно-ориентированное программирование, работа с коллекциями и данными, паттерны проектирования, архитектура Unity, программирование в контексте движка, физика, визуал и звук, работа с ресурсами, пользовательский интерфейс и многое другое. В конце статьи приведены полезные ссылки на ресурсы для обучения

Перейти к материалу

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#Собес #file #file_handling #c#
🤔 Что такое работа с файлами в C#?

💬 Кратко:

Работа с файлами в C# включает в себя операции чтения и записи данных в файлы. Для этого используется пространство имен System.IO, которое предоставляет классы для работы с потоками ввода и вывода. Потоки — это последовательности байтов, через которые происходит взаимодействие с файлами. В C# существуют два типа потоков: входной (для чтения) и выходной (для записи в файл).

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#Собес #boxing #unboxing #reference_type
🤔 Что такое упаковка (boxing) и распаковка (unboxing) в .NET и зачем они нужны?

💬 Кратко:

Boxing — это упаковка значения value type в объект object (на куче), а unboxing — извлечение значения обратно в value type. Необходимы для прозрачной работы с общим базовым типом object или интерфейсами. Упаковка создаёт дополнительный объект и копирует данные, распаковка проверяет тип и снова копирует, что может влиять на производительность.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#Собес #dns_protocol #udp #tcp
🤔 Какой протокол и порт у DNS?

💬 Кратко:

DNS использует протоколы TCP и UDP. Порт для DNS-запросов — 53.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#trainer #печать
📚 Тренируем печать

Быстро печатать — не просто приятно, а выгодно. Когда пальцы успевают за мыслью, код льётся плавно.

Перейти к материалу

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#Собес #optimization #ui #canvas
🤔 Как оптимизировать UI?

💬 Кратко:

Оптимизация UI в Unity — это в основном борьба с перерисовками (overdraw) и дорогими операциями перестроения (rebuild). Ключевые методы: 1) Разделять UI на несколько Canvas: статический на одном, динамический на другом. 2) Объединять текстуры в атласы, чтобы уменьшить количество переключений материалов. 3) Отключать Raycast Target у элементов, которые не должны реагировать на клик. 4) Для часто обновляемого текста использовать кеширование, чтобы не обновлять его каждый кадр, если значение не изменилось. 5) Использовать пулы объектов для динамически создаваемых элементов, например, сообщений об уроне.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
Forwarded from YeaHub
🚀 YeaHub развивается

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

Теперь у нас есть:
yeahub.ru — публичная SEO-ориентированная часть на Next.js с быстрым серверным рендерингом
app.yeahub.ru — основное приложение: личный кабинет пользователя со статистикой, прогрессом и аналитикой

🔥 Лайвкодинг — наконец-то готов

Мы серьезно прокачали сервис лайвкодинга:
— добавили привязку задач к коллекциям (собеседованиям)
— сделали связь с компаниями
— теперь можно готовиться по задачам с реальных собеседований

Уже доступны задачи из: Сбер, Яндекс, Авито, VK, Ozon, Т-Банк и других компаний.

📌 Сейчас добавлено ~100 задач.

Да, это меньше, чем планировали — но пришлось сделать шаг назад, чтобы сделать десять вперед.

Мы полностью переработали:
— шаблон задач
— систему тесткейсов

Ранее была допущена ошибка, из-за которой пришлось вручную исправить 80+ задач 😢

Но теперь база готова к масштабированию — и мы можем быстро и правильно наполнять её дальше.

📈 Что дальше по лайвкодингу

Мы будем активно развивать этот сервис.
Это не только про собеседования — это инструмент для роста и прокачки.
Планируется много новых фич.

📅 Регулярные обновления контента

Мы выстроили процесс: каждую неделю 4–8 собеседований, 6–10 задач
И каждое обновление будем анонсировать, чтобы вы всегда были в курсе.

🛠 Сейчас в разработке (2 ключевых сервиса)

Агрегатор вакансий + платформа размещения вакансий
ATS-оптимизация резюме
— Бэкенд почти готов.
— Идёт дизайн.
— Фронтенд начнем совсем скоро.

🎯 Цель — выпустить оба сервиса в бэта до лета.

🧠 Новая структура обучения

Раньше было: Навык → Вопрос
Теперь: Навык → Тема → Вопрос

Это сильно упрощает обучение.

Теперь можно: готовиться точечно к собеседованиям или системно изучать темы

💻 Мы — open source

Мы не бросаем слов на ветер. Мы делаем.

Код проекта открыт https://github.com/YeaHubTeam:
— фронтенд
— мобильные приложения
— backend на Python (решили новый сервис делать публично, для новичков)
— автотесты

Это open source платформа, где новички могут учиться и смотреть на реальные практики.

❤️ Поддержка

Вы можете поддержать нас, оформив подписку. Это напрямую влияет на:
— добавление контента
— развитие платформы
— новые фичи

Вы можете быть уверены — мы не стоим на месте. Работа реально кипит: почти каждый день мержатся новые фичи, мы постоянно развиваем продукт и улучшаем уже существующие сервисы.

У нас полностью открытый код, и это не просто слова. Вы в любой момент можете зайти и посмотреть активность, коммиты и то, как проект развивается каждый день.

По подписке: сейчас стоимость — 800 рублей за месяц и 1800 рублей за 3 месяца. Это уже ниже, чем у аналогичных сервисов. При этом важно понимать — после выхода новых сервисов (агрегатор вакансий и ATS для резюме) цена будет пересмотрена.

Если хотите зафиксировать текущую стоимость — лучше сделать это сейчас:
https://app.yeahub.ru/settings#select-tariff

Мы строим продукт.
Мы двигаемся вперёд.
И мы делаем IT снова великим.
💪🚀✊🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Поговорим про процесс билда.

Build
Билд или сборка проекта - это процесс подготовки готового к запуску приложения для конкретной платформы: Windows, Android, iOS и др. Через окно File → Build Settings вы выбираете платформу и запускаете сборку. В результате Unity формирует Player (например, .exe, .apk) и сопутствующие данные, которые можно запускать без редактора.

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

Player.
Это готовое к запуску приложение, которое Unity собирает из проекта для конкретной платформы: исполняемый файл и сопутствующие runtime-данные.

Player Build.
Процесс сборки проекта, результатом которого становится Player. Когда вы выбираете платформу в File → Build Settings и запускаете сборку - вы делаете Player Build. Часто это называют просто билд.

Артефакт.
Это любой файл или набор файлов, которые получаются на выходе или в процессе сборки. Если целевая платформа винда, то артефактами будут .exe + папка с data. Если андройд, то .apk или .aab. Это общепринятый термин в CI/CD. Когда говорят "сохранить артефакты сборки" - имеют в виду сохранить выходные файлы, чтобы их можно было, например, скачать, задеплоить или проанализировать. Отличается от Player тем, что Player - это готовая игра, которую можно запустить и поиграть. Каждый Player является артефактом, но не каждый артефакт является Player.

Content Build.
Отдельный процесс, который создаёт артефакты контента (каталог, бандлы, runtime-настройки для Addressables). Эти артефакты нужны Addressables, чтобы подгружать ассеты во время выполнения. Content build - не всегда часть Player build, так как его при желании можно запускать удалённо.

Процесс вроде понятен. Player Build берёт нужные файлы проекта и преобразует их в Player - исполняемый файл + сопутствующие файлы. Но что конкретно Player Build преобразует? Какие файлы в нашем проекте он включает в билд, а какие нет?

Об этом мы поговорим в следующем посте.

🚀 Пост Guru Unity: @Minerope
Please open Telegram to view this post
VIEW IN TELEGRAM
#Собес #editor #extension
🤔 Когда уместно расширять редактор?

💬 Кратко:

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

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа