Чат DeepSeek - чемпион по переобуванию, только попросите 😄
Миниутилита для вашего удобства в Unity!
Как-то мы работали в команде и мне понадобилось выделить объекты с определёнными компонентами в иерархии сцены, чтобы левелдиз чётко видел, где и что именно он редачит.
Тогда я начал искать способ подсветить нужное, но в юньке не оказалось чего-то встроенного. И я написал кастомный класс, который находит нужный компонент на сцене и пририсовывает рядом с ними иконку, которую я укажу.
Мне это так зашло, что я решил сделать ещё удобнее: в самом верху скрипта есть словарь (см. скрин 2), в котором вы можете перечислить все свои компоненты и указать иконку по имени в проекте. Редактор всё подтянет и начнёт отображать даже во вложенной иерархии все компоненты с иконками.
Утилитку прикрепляю. Я заботливо для вас добавил демо-сценку, где всё настроено. Если находите это полезным, не жопьтесь на реакции, я заморочился и сделал ещё удобнее, чтобы вам не пришлось париться )
Как-то мы работали в команде и мне понадобилось выделить объекты с определёнными компонентами в иерархии сцены, чтобы левелдиз чётко видел, где и что именно он редачит.
Тогда я начал искать способ подсветить нужное, но в юньке не оказалось чего-то встроенного. И я написал кастомный класс, который находит нужный компонент на сцене и пририсовывает рядом с ними иконку, которую я укажу.
Мне это так зашло, что я решил сделать ещё удобнее: в самом верху скрипта есть словарь (см. скрин 2), в котором вы можете перечислить все свои компоненты и указать иконку по имени в проекте. Редактор всё подтянет и начнёт отображать даже во вложенной иерархии все компоненты с иконками.
Утилитку прикрепляю. Я заботливо для вас добавил демо-сценку, где всё настроено. Если находите это полезным, не жопьтесь на реакции, я заморочился и сделал ещё удобнее, чтобы вам не пришлось париться )
👍2🔥2🤯2
Начинаете делать игру, но вскоре забрасываете её на стадии прототипа? Без паники! Возможно вам просто нравится кодить, а как только архитектура становится понятной и остаётся только рутина, вам становится скучно и вы ищете что-то новое.
У меня так. Я с удовольствием пишу новый код и ковыряю старый, но сделать/найти хорошие спрайты, модельки, звуки - для меня пытка. Считаю, что это нормальная реакция мозга на то, что не вызывает достаточно интереса. Поэтому забейте и пилите то, что нравится. Если хотите забросить проект - иногда полезно не отказывать себе в этом.
А если не знаете, где черпать мотивацию, попробуйте просто найти единомышленников.
У меня так. Я с удовольствием пишу новый код и ковыряю старый, но сделать/найти хорошие спрайты, модельки, звуки - для меня пытка. Считаю, что это нормальная реакция мозга на то, что не вызывает достаточно интереса. Поэтому забейте и пилите то, что нравится. Если хотите забросить проект - иногда полезно не отказывать себе в этом.
А если не знаете, где черпать мотивацию, попробуйте просто найти единомышленников.
Увидел, что делает одна из команд в этой группе https://t.me/IndieGameMill и захотелось повторить с нуля с небольшими доработками. Такое вот получилось. Билд можно скачать и потрогать, архив прикрепляю.
🔥1
TyapLyapDev - Разработка игр | Движуха Сакутина
Photo
Уже сутки дерусь с пользовательским редактором юнити, чтобы сделать эту систему ещё удобнее, настраиваемой в специальном окне. Думаю, это станет полноценной утилитой, чтобы легко настраивать и не лезть в код. Сначала меня пугала работа в редакторе. Сейчас тоже пугает, но меньше, т.к. я начал раскидывать логику по ответственностям и дебажить, расширять, модифицировать становится проще.
Такой вот совет: если перед вами страшный код, раскидайте его по скриптам и работайте с кусочками.
Такой вот совет: если перед вами страшный код, раскидайте его по скриптам и работайте с кусочками.
🔥2
Please open Telegram to view this post
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Показыватель иконок в иерархии сцены 2.0! Теперь достаточно открыть окно, добавить элемент в список и выбрать там иконку и компонент, который висит на объектах для отрисовки. Чем это удобно? Ну, вы можете подсветить в иерархии сцены все объекты, на которые вашим коллегам по разработке надо обратить особое внимание. Я выделял объекты с дорожными модельками для человека, который собирал уровень. Оказалось очень даже удобно. Не тестил на разных версиях юньки, поэтому пишите, если найдёте баги 🙂
🔥4
TyapLyapDev - Разработка игр | Движуха Сакутина
Video
Какое было решение для снижения нагрузки: каждый кубик - объект, который внутри себя содержит триггер-коллайдер в виде сферы, чисто для плавности и саму модельку куба, которая выключена. Позиция триггера никогда не меняется, а вот позиция модельки при деактивации (и на старте) присваивает случайное сферическое отклонение и случайную дистанцию. При активации моделька получает ссылку на цель (игрока) появляется по направлению от цели на эту самую рандомную дистанцию, плюс рандомное отклонение и вращение. Чем меньше дистанция до цели, тем ближе моделька к нулевым координатам позиции и вращению.
Теперь игрок. У него есть детектор в виде сферы, который активирует кубы при входе в триггер и деактивирует при выходе. Физика настроена так, что детектор видит только кубы, а кубы детектор. Все остальные слои игнорируются.
Чтобы ручками не составлять лабиринты из кубиков, я сделал их генерацию с заполнением по всему объёму коллайдеров стен. Компонент принимает размер кубов для каждой стены, зазор между кубами и цветовую схему. После заполнения кубами у стены удаляется рендерер, отрисовывается гизмос в сцене и остаётся только коллайдер, по которому двигается коллайдер игрока.
В целом я постарался в оптимизацию, поэтому всё работает без лагов, сколько бы кубов на сцене не находилось.
Теперь игрок. У него есть детектор в виде сферы, который активирует кубы при входе в триггер и деактивирует при выходе. Физика настроена так, что детектор видит только кубы, а кубы детектор. Все остальные слои игнорируются.
Чтобы ручками не составлять лабиринты из кубиков, я сделал их генерацию с заполнением по всему объёму коллайдеров стен. Компонент принимает размер кубов для каждой стены, зазор между кубами и цветовую схему. После заполнения кубами у стены удаляется рендерер, отрисовывается гизмос в сцене и остаётся только коллайдер, по которому двигается коллайдер игрока.
В целом я постарался в оптимизацию, поэтому всё работает без лагов, сколько бы кубов на сцене не находилось.
🔥4❤1
Сделай первую игру с нуля и получи грант на 1 000 000 рублей
Привет! Я веду этот канал как участник творческой мастерской Романа Сакутина. Наша цель создавать творческие игры и радовать игроков.
Становись разработчиком игр вместе со мной здесь - https://ijunior.ru/workshop-gamedev?utm_source=telegram_workshops&utm_medium=pinned_post&utm_campaign=tyaplyapdev
Привет! Я веду этот канал как участник творческой мастерской Романа Сакутина. Наша цель создавать творческие игры и радовать игроков.
Становись разработчиком игр вместе со мной здесь - https://ijunior.ru/workshop-gamedev?utm_source=telegram_workshops&utm_medium=pinned_post&utm_campaign=tyaplyapdev
ijunior.ru
Сделай первую игру с нуля и получи грант на 1 000 000 рублей
Бесплатная творческая мастерская от Романа Сакутина. Тебя ждут лекции и клуб творцов
😁4
TyapLyapDev - Разработка игр | Движуха Сакутина pinned «Сделай первую игру с нуля и получи грант на 1 000 000 рублей Привет! Я веду этот канал как участник творческой мастерской Романа Сакутина. Наша цель создавать творческие игры и радовать игроков. Становись разработчиком игр вместе со мной здесь - https:/…»
TyapLyapDev - Разработка игр | Движуха Сакутина
Как по мне, офигенно получается. Тема - "Шутер". Доп тема - "Гравитационные аномалии". На видео результат 4 недель кодинга 😎 Спасибо 3-дшнику @TrutnevI за подготовленный ассет пистолета-обливалки 🔫
SoakPC.zip
50.1 MB
Я по ходу билд не скидывал этого проекта. Можете игрануть, это на ПК
🔥1
Media is too big
VIEW IN TELEGRAM
Языковая локализация игры.
Вам уже доводилось переводить игры на другие языки? Я уже с этим несколько раз сталкивалася, поэтому просто сделал для себя заготовку.
Самый простой, понятный и эффективный способ - накидывать на объекты с текстовыми компонентами кастомный скрипт, в котором есть несколько полей для записи. Вся логика уложилась в 3 скрипта, в которых суммарно 132 строчки кода - это уже с удобным переключением.
Ассет с демосценой прикреплю в комментариях (при импорте так же подтяните TMP). Ещё я в комменты запульну сообщения с кодом чтобы вы могли посмотреть, а кто-то возможно найдёт косяки.
Пишите замечания, задавайте вопросы, с радостью пообщаюсь 🙂
Вам уже доводилось переводить игры на другие языки? Я уже с этим несколько раз сталкивалася, поэтому просто сделал для себя заготовку.
Самый простой, понятный и эффективный способ - накидывать на объекты с текстовыми компонентами кастомный скрипт, в котором есть несколько полей для записи. Вся логика уложилась в 3 скрипта, в которых суммарно 132 строчки кода - это уже с удобным переключением.
Ассет с демосценой прикреплю в комментариях (при импорте так же подтяните TMP). Ещё я в комменты запульну сообщения с кодом чтобы вы могли посмотреть, а кто-то возможно найдёт косяки.
Пишите замечания, задавайте вопросы, с радостью пообщаюсь 🙂
🔥4👍2
Зачем кешировать transform?
Кеширование трансформа в Unity (например, _transform = transform) делают для повышения производительности. Вот основные причины:
1. Избежание повторных вызовов геттера
Свойство transform в Unity не просто возвращает поле - оно вызывает внутренний метод GetComponent<Transform>(), который ищет компонент в GameObject. Это требует вычислительных затрат.
Кеширование сохраняет ссылку на трансформ один раз (например, в Awake()), избегая повторного поиска.
2. Сокращение накладных расходов
В циклах (например, Update()) частые обращения к transform без кеширования могут снижать FPS, особенно на мобильных устройствах или при большом количестве объектов.
Пример без кеширования:
Пример с кешированием:
Важно!
Современные версии Unity (особенно с 2018+) оптимизировали геттер transform, и разница в производительности стала менее заметной. Однако для критичных к производительности проектов кеширование всё ещё рекомендуется.
Всегда кешируйте компоненты в Awake() или Start(), а не в Update(), чтобы избежать лишних операций.
Что ещё кешируют?
Другие компоненты: Rigidbody, Renderer, Canvas и т.д.
Ссылки на игровые объекты, если они используются часто.
Таким образом, кеширование — это простая и эффективная практика для оптимизации кода в Unity.
Кеширование трансформа в Unity (например, _transform = transform) делают для повышения производительности. Вот основные причины:
1. Избежание повторных вызовов геттера
Свойство transform в Unity не просто возвращает поле - оно вызывает внутренний метод GetComponent<Transform>(), который ищет компонент в GameObject. Это требует вычислительных затрат.
Кеширование сохраняет ссылку на трансформ один раз (например, в Awake()), избегая повторного поиска.
2. Сокращение накладных расходов
В циклах (например, Update()) частые обращения к transform без кеширования могут снижать FPS, особенно на мобильных устройствах или при большом количестве объектов.
Пример без кеширования:
void Update()
{
// Каждый раз вызывается геттер transform
transform.Translate(1, 0, 0);
transform.Rotate(0, 1, 0);
}
Пример с кешированием:
private Transform _transform;
void Awake()
{
_transform = transform; // Сохраняем ссылку один раз
}
void Update()
{
_transform.Translate(1, 0, 0); // Работаем с кешированной ссылкой
_transform.Rotate(0, 1, 0);
}
Важно!
Современные версии Unity (особенно с 2018+) оптимизировали геттер transform, и разница в производительности стала менее заметной. Однако для критичных к производительности проектов кеширование всё ещё рекомендуется.
Всегда кешируйте компоненты в Awake() или Start(), а не в Update(), чтобы избежать лишних операций.
Что ещё кешируют?
Другие компоненты: Rigidbody, Renderer, Canvas и т.д.
Ссылки на игровые объекты, если они используются часто.
Таким образом, кеширование — это простая и эффективная практика для оптимизации кода в Unity.
👍4❤2🔥2
Хочу поделиться с вами своими соображениями по поводу комментариев в коде. Мне кажется это плохой практикой и вот почему:
1. Код желательно писать так, чтобы он сам говорил за себя. Для этого достаточно придумывать понятные названия для классов, полей и методов, а так же раскидывать логику по ответственностям.
2. Если в коде и комментариях одно и то же, то какой смысл в этих комментариях?!
3. Если вы изменили логику в коде, но не поправили пояснения в комментариях, то это скорее запутает, чем поможет.
Таким образом комментирование - скорее бесполезная штука и двойная работа.
Но не будем голословными. Для примера я качнул из ассет стора Starter Assets - ThirdPersonController .
Давайте посмотрим кусочки:
Вообще в этом классе 392 строки и он занимается сразу всем. Если раскидать по скриптам, то внезапно окажется, что поля с комментарием // cinemachine попадут в один класс, // player в другой класс и т.д. Это означает, что сама архитектура снимет с вас необходимость группировать поля таким способом. Но допустим, это прототип и не страшно, что здесь всего напихано. Смотрим ещё раз:
В самом названии полей написано _cinemachine , так же и в остальных. Здесь можно поудалять комментарии, оставить лишь разделение групп пустыми строками и читаемость нисколько не пострадает, а даже улучшится.
Смотрим дальше:
В комментарии говорится "// получите ссылку на нашу основную камеру". А в коде что? А вот: если ссылка на Камеру равна null , получить ссылку по тегу "MainCamera" и присоить её _mainCamera
Пока закроем глаза на использование тегов, но чем сам код здесь объясняет хуже комментария?
Дальше:
// reset our timeouts on start - // сбросьте наши тайм-ауты при запуске. А что мешает сделать метод:
Во-первых не придётся писать, что сбрасываем при старте - логично же, что раз метод вызывается в старте, то там идёт сброс таймаутов. Во-вторых, можно переиспользовать этот метод в других частях кода.
Дальше просто поскидываю такие кусочки кода. Посмотрите, как это комично выглядит:
1. Код желательно писать так, чтобы он сам говорил за себя. Для этого достаточно придумывать понятные названия для классов, полей и методов, а так же раскидывать логику по ответственностям.
2. Если в коде и комментариях одно и то же, то какой смысл в этих комментариях?!
3. Если вы изменили логику в коде, но не поправили пояснения в комментариях, то это скорее запутает, чем поможет.
Таким образом комментирование - скорее бесполезная штука и двойная работа.
Но не будем голословными. Для примера я качнул из ассет стора Starter Assets - ThirdPersonController .
Давайте посмотрим кусочки:
// cinemachine
private float _cinemachineTargetYaw;
private float _cinemachineTargetPitch;
// player
private float _speed;
private float _animationBlend;
private float _targetRotation = 0.0f;
private float _rotationVelocity;
private float _verticalVelocity;
private float _terminalVelocity = 53.0f;
// timeout deltatime
private float _jumpTimeoutDelta;
private float _fallTimeoutDelta;
// animation IDs
private int _animIDSpeed;
private int _animIDGrounded;
private int _animIDJump;
private int _animIDFreeFall;
private int _animIDMotionSpeed;
Вообще в этом классе 392 строки и он занимается сразу всем. Если раскидать по скриптам, то внезапно окажется, что поля с комментарием // cinemachine попадут в один класс, // player в другой класс и т.д. Это означает, что сама архитектура снимет с вас необходимость группировать поля таким способом. Но допустим, это прототип и не страшно, что здесь всего напихано. Смотрим ещё раз:
// cinemachine
private float _cinemachineTargetYaw;
private float _cinemachineTargetPitch;
В самом названии полей написано _cinemachine , так же и в остальных. Здесь можно поудалять комментарии, оставить лишь разделение групп пустыми строками и читаемость нисколько не пострадает, а даже улучшится.
Смотрим дальше:
private void Awake()
{
// get a reference to our main camera
if (_mainCamera == null)
{
_mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
}
}
В комментарии говорится "// получите ссылку на нашу основную камеру". А в коде что? А вот: если ссылка на Камеру равна null , получить ссылку по тегу "MainCamera" и присоить её _mainCamera
Пока закроем глаза на использование тегов, но чем сам код здесь объясняет хуже комментария?
Дальше:
private void Start()
{
...
// reset our timeouts on start
_jumpTimeoutDelta = JumpTimeout;
_fallTimeoutDelta = FallTimeout;
}
// reset our timeouts on start - // сбросьте наши тайм-ауты при запуске. А что мешает сделать метод:
private void ResetTimeouts()
{
_jumpTimeoutDelta = JumpTimeout;
_fallTimeoutDelta = FallTimeout;
}
Во-первых не придётся писать, что сбрасываем при старте - логично же, что раз метод вызывается в старте, то там идёт сброс таймаутов. Во-вторых, можно переиспользовать этот метод в других частях кода.
Дальше просто поскидываю такие кусочки кода. Посмотрите, как это комично выглядит:
// set sphere position, with offset
Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - GroundedOffset,
transform.position.z);
// clamp our rotations so our values are limited 360 degrees
_cinemachineTargetYaw = ClampAngle(_cinemachineTargetYaw, float.MinValue, float.MaxValue);
_cinemachineTargetPitch = ClampAngle(_cinemachineTargetPitch, BottomClamp, TopClamp);
// Cinemachine will follow this target
CinemachineCameraTarget.transform.rotation = Quaternion.Euler(_cinemachineTargetPitch + CameraAngleOverride, _cinemachineTargetYaw, 0.0f);
// set target speed based on move speed, sprint speed and if sprint is pressed
float targetSpeed = _input.sprint ? SprintSpeed : MoveSpeed;
// reset the fall timeout timer
_fallTimeoutDelta = FallTimeout;
❤3👍1🔥1