Unity Game Lab
59 subscribers
42 photos
26 videos
3 files
17 links
🔧 Unity Game Lab | Геймдев-лаборатория

Разрабатываю динамичный fps:
https://redatomteam.itch.io/creatures
Download Telegram
🎮 Unity Physics: как работает и как оптимизировать
Физика в Unity — это не магия, а точные расчеты! Разберём, как устроен движок NVIDIA PhysX (стандартный для Unity) и как его правильно настроить.

🔧 Основы физики
- Фиксированный шаг: рассчитывается 50 раз в секунду (FixedUpdate).
- Настройки: Edit → Project Settings → Physics (3D) / Physics 2D (2D).

Ключевые параметры:
- Gravity – сила гравитации (по умолчанию (0, -9.81, 0)).
- Bounce Threshold – минимальная скорость для отскока.
- Sleep Threshold – объекты "засыпают" при низкой скорости.
- Solver Iterations – точность расчётов (чем выше, тем стабильнее).

⚡️ Оптимизация физики
- Статичные объекты – помечайте Static (кешируются).
- Layer Collision Matrix – отключайте ненужные столкновения.
- Примитивные коллайдеры – BoxCollider вместо MeshCollider.
- ArticulationBody – для сложных систем (роботы, цепи).

Профилирование:
- Window → Analysis → Physics Profiler – смотрите нагрузку.
- Статистика в Game View (Stats) – кол-во Rigidbody и коллайдеров.

💡 Итог
- Физика считается 50 раз в секунду (FixedUpdate).
- Оптимизируйте через Static, Layer Matrix и простые коллайдеры.
- Включите CCD для быстрых объектов.
Помните игру, о которой я писал? Так вот - я наконец то прошёл модерацию в Yandex Games и теперь игра доступна всем желающим! Неплохо, да? Ловите ссылку:

https://yandex.com/games/app/438741?lang=ru
🎮 Коллайдеры в Unity: полный гид за 2 минуты

Коллайдеры — это невидимые "физические оболочки" объектов. Они определяют, как объекты сталкиваются, но не влияют на графику. Давайте разберём их на практике!

🔧 Типы коллайдеров

① Примитивные (оптимальные)
- Box – кубы/платформы
- Sphere – шары/пули
- Capsule – персонажи

② Сложные
- Mesh Collider – точная форма (для статичных объектов)
- Convex – упрощённый Mesh (для динамики)
- Terrain – ландшафты

③ 2D-версии
- BoxCollider2D
- CircleCollider2D
- PolygonCollider2D

// Настройка триггера в коде
GetComponent<Collider>().isTrigger = true;


⚡️ Оптимизация
- Для динамики – только примитивы
- Статичные объекты – отмечайте Static
- Layer Matrix – отключайте ненужные столкновения

Совет:
// Отключение столкновений между слоями 8 и 9
Physics.IgnoreLayerCollision(8, 9);


🎯 Лучшие практики
Персонаж: CapsuleCollider + Rigidbody
Пули: SphereCollider + Continuous-режим
Сложные объекты: несколько примитивных коллайдеров

🔍 Отладка:
Включите Gizmos → Colliders в Scene View:
🔴 Красный – динамический объект
🟢 Зелёный – статичный
🔵 Синий – триггер

📌 Пример настройки:
public class Hitbox : MonoBehaviour
{
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Enemy"))
Destroy(other.gameObject);
}
}
🚀 Rigidbody в Unity:

Rigidbody — это "физическое тело" вашего объекта. Разберём ключевые особенности:

⚙️ Основные параметры
- Mass (масса) – влияет на инерцию (1 = 1кг)
- Drag – сопротивление движению (0 = нет трения)
- Use Gravity – падать или нет ⬇️
- Is Kinematic – управляется кодом, а не физикой

🎯 Режимы столкновений
Discrete — Декорации (экономит ресурсы)
Continuous — Пули, снаряды (нет туннелирования)
Continuous Dynamic — Игрок, важные объекты

💡 Применение сил
// Прыжок  
rb.AddForce(Vector3.up * 10, ForceMode.Impulse);

// Вращение
rb.AddTorque(Vector3.right * 5);

// Взрыв
AddExplosionForce(100, explosionPos, 5);


ForceMode:
Force – плавное ускорение (машина)
Impulse – мгновенный толчок (прыжок)

⚡️ Оптимизация
Sleep Mode – "усыпляет" неподвижные объекты
Freeze Position – блокировка осей
Interpolate – сглаживание дёрганий

⚠️ Частые проблемы
Туннелирование → Включите Continuous режим
Дрожание → Увеличьте Solver Iterations (до 6-8)
Лаги → Проверьте массу (0.1–10 кг оптимально)

🔗 Пример использования:
public class PlayerMovement : MonoBehaviour  
{
private Rigidbody rb;
void Start() => rb = GetComponent<Rigidbody>();
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
rb.AddForce(Vector3.up * 5, ForceMode.Impulse);
}
}
🎮 Physic Material в Unity: настройка трения и отскока

Физические материалы определяют, как объекты взаимодействуют при столкновениях. Давайте разберём их на практике!

⚙️ Основные параметры
Dynamic Friction (0-1) – трение при движении
Static Friction (0-1) – трение в покое
Bounciness (0-1) – сила отскока
Combine Mode – как комбинируются параметры при столкновении

💡 Готовые пресеты

Лёд — Friction: 0.05, Bounce: 0.1, Combine: Min
Резина — Friction: 0.8, Bounce: 0.9, Combine: Multiply
Металл — Friction: 0.4, Bounce: 0.3, Combine: Average

🔧 Создание материала
Через редактор:
ПКМ → Create → Physic Material → перетащите на коллайдер
Через код:
PhysicMaterial mat = new PhysicMaterial();
mat.bounciness = 0.8f;
GetComponent<Collider>().material = mat;

⚡️ Важные нюансы
Не работает с Is Trigger
Требует Rigidbody на одном из объектов
Для 2D используйте Physics Material 2D

📌 Пример для скользкой поверхности:
void MakeSurfaceSlippery() 
{
PhysicMaterial mat = new PhysicMaterial();
mat.dynamicFriction = 0.1f;
mat.staticFriction = 0.15f;
mat.frictionCombine = PhysicMaterialCombine.Minimum;
GetComponent<Collider>().material = mat;
}
🎯 Raycast в Unity: Гид по лучшему инструменту обнаружения

Physics.Raycast() — ваш главный инструмент для "пуль", детекции препятствий и взаимодействий. Разберём всё самое важное коротко!

🔍 Базовое использование
if (Physics.Raycast(transform.position, transform.forward, out RaycastHit hit, 10f)) 
{
Debug.Log($"Попал в: {hit.collider.name}");
Debug.DrawLine(transform.position, hit.point, Color.red); // Визуализация
}


Ключевые параметры:
- origin — откуда выпускаем луч
- direction — направление (обязательно нормализуйте!)
- hit — информация о столкновении
- maxDistance — дальность луча
💡 Фишки RaycastHit
- hit.point — точка попадания
- hit.normal — нормаль поверхности
- hit.distance — дистанция до объекта

⚡️ Оптимизация
1. Фильтр по слоям
int enemyLayer = 1 << LayerMask.NameToLayer("Enemy");
Physics.Raycast(..., enemyLayer);


2. NonAlloc-версия (без лишних выделений памяти)
RaycastHit[] hits = new RaycastHit[5];
int count = Physics.RaycastNonAlloc(..., hits);


3. Короткие лучи → Быстрее расчеты
Physics.Raycast(..., maxDistance: 5f);


🛠 Вариации Raycast
- RaycastAll — все пересечения луча
- SphereCast — луч с радиусом (толстые объекты)
- BoxCast — луч в форме куба

⚠️ Частые ошибки
- Луч из коллайдера → Игнорируйте свой объект:
if (hit.collider != myCollider) { ... }

- FixedUpdate → Raycast зависит от физики, поэтому лучше вызывать там.
- Ненормализованный direction → Используйте transform.forward, а не transform.forward * 10.

📌 Пример для пуль:
if (Physics.Raycast(gun.position, gun.forward, out hit, 100f, enemyLayer))
{
hit.collider.GetComponent<Enemy>().TakeDamage(10);
}
🔗 3D Joints в Unity: краткий гид по соединениям
Соединяйте объекты как профессионал! Joints — это инструменты для создания реалистичных физических связей между Rigidbody.

🔧 Основные типы Joints
Fixed Joint – жёсткое соединение (сварка)
Hinge Joint – дверная петля (вращение по оси)
Spring Joint – пружина (гибкость и упругость)
Character Joint – шарнир для Ragdoll
Configurable Joint – максимальная настройка

💡 Когда что использовать?
Двери/рычаги → Hinge Joint
Тросы/подвески → Spring Joint
Тряпичные куклы → Character Joint
Сложные механизмы → Configurable Joint

⚙️ Общие настройки
Connected Body – к чему крепим
Anchor – точка соединения
Break Force – сила разрыва связи
Enable Collision – разрешить столкновения

⚠️ Частые проблемы
Дрожание → Уменьшите массу, добавьте Damping
Разрыв соединения → Увеличьте Break Force
Проваливание → Настройте Fixed Timestep

📌 Пример для двери:
var hinge = door.AddComponent<HingeJoint>();
hinge.connectedBody = doorFrame.GetComponent<Rigidbody>();
hinge.anchor = new Vector3(0, 0.5f, 0); // Петля сверху
hinge.axis = Vector3.up; // Вращение вокруг Y
👍4
🎮 Что такое сцена в Unity? | Часть 1

Сцены (Scenes) — это основные строительные блоки любого Unity-проекта. Представьте их как отдельные «комнаты» вашего приложения, где каждая отвечает за свою часть логики и контента.

🔍 Зачем нужны сцены?
Организация проекта
- Каждая сцена — это отдельный уровень, меню или экран.

Например:
MainMenu — главное меню
Level_1 — первый уровень игры
Settings — настройки

Изоляция логики

Объекты и скрипты из одной сцены не влияют на другую (если не загружены одновременно).
Можно разрабатывать уровни параллельно.

Управление потоком игры
Переходы между сценами = навигация в приложении.
Пример: Главное меню → Уровень 1 → Уровень 2 → Финал

🎯 Типичные примеры использования
- Уровни игры (Forest_Level, Dungeon_Level)
- Интерфейсы (Menu, Settings)
- Загрузочные экраны (LoadingScreen)
- Изолированные тесты (Test_Physics, Test_AI)

🛠 Как это выглядит в Unity?
Иерархия (Hierarchy) — все объекты сцены.
Окно Scene — визуальное представление.
Project-панель — файлы сцен (.unity).

💡 Советы для новичков
- Называйте сцены понятно: Level1_Forest, а не Scene23.
- Используйте пустые сцены для тестов (например, Sandbox).
- Храните префабы вне сцен (чтобы использовать их повторно).

📌 Кратко:
Сцена = отдельный «экран» проекта.
Нужны для порядка, изоляции и навигации.
Примеры: уровни, меню, загрузки.
👍1
🚀 Scene Manager в Unity: работа со сценами | Часть 2

Сегодня разберем как работать со сценами в Unity с помощью SceneManager — ключевого инструмента для управления "уровнями" вашей игры.

🔄 Работа с классом Scene
Сцены в коде представлены классом Scene. Через SceneManager можно получить данные о сценах:
// Текущая сцена
Scene currentScene = SceneManager.GetActiveScene();
Debug.Log($"Текущая сцена: {currentScene.name}");

// Проверка, загружена ли сцена
if (currentScene.IsValid())
{
Debug.Log("Сцена корректна!");
}


🔧 Основы SceneManager
Класс SceneManager (пространство имён UnityEngine.SceneManagement) отвечает за:
Загрузку/выгрузку сцен
Получение информации о текущей сцене
Обработку событий (например, перед загрузкой)

📌 Загрузка сцен в режиме Single
Single — стандартный режим, который:
Загружает только одну сцену
Выгружает текущую сцену полностью

1. Базовый пример
using UnityEngine.SceneManagement;

// Загрузка сцены по имени
SceneManager.LoadScene("Level_1");

// Загрузка по buildIndex (из Build Settings)
SceneManager.LoadScene(2);


2. Важные нюансы
Build Settings: Сцена должна быть добавлена в File → Build Settings (иначе вызовет ошибку).
Имена чувствительны к регистру: "Menu" ≠ "menu".

⚡️ Полезные методы SceneManager
- LoadScene() — Загружает сцену (по имени или индексу).
- GetActiveScene() — Возвращает текущую активную сцену.
- GetSceneByName() — Находит сцену по имени (без загрузки).
- GetSceneByBuildIndex() — Находит сцену по индексу.

🎮 Практический пример
Сценарий для кнопки "Start Game":
using UnityEngine;
using UnityEngine.SceneManagement;

public class LoadLevel : MonoBehaviour
{
public void LoadNextLevel()
{
// Загружаем следующий уровень (индекс текущей сцены + 1)
int nextSceneIndex = SceneManager.GetActiveScene().buildIndex + 1;
SceneManager.LoadScene(nextSceneIndex);
}
}


⚠️ Частые ошибки
- Сцена не в Build Settings → Добавьте её через File → Build Settings.
- Неверное имя/индекс → Проверьте регистр и цифры.
- Устаревший метод → Не используйте Application.LoadLevel() (он устарел).
👍1
🚀 Аддитивная загрузка сцен в Unity | Часть 3
Сегодня разберём мощный инструмент — аддитивную загрузку сцен, который позволяет комбинировать несколько сцен в одной!

🔍 Что такое аддитивная загрузка?
Это режим, при котором новая сцена добавляется к текущей, а не заменяет её.
Ключевые отличия от Single-режима:
1. Все объекты из текущей сцены остаются
2. Можно создать "композитный" уровень из нескольких сцен
3. Идеально для:
3.1. Динамической подгрузки локаций
3.2. Разделения логики (например, UI + игровой мир)

📌 Загрузка сцены аддитивно
using UnityEngine.SceneManagement;

// Загрузка сцены "Dungeon" поверх текущей
SceneManager.LoadScene("Dungeon", LoadSceneMode.Additive);


Параметры:
sceneName/buildIndex — имя или индекс сцены
LoadSceneMode.Additive — режим добавления

🗑 Выгрузка сцен
Есть 3 способа выгрузить сцену:

1. По имени
SceneManager.UnloadSceneAsync("Dungeon");


2. По индексу
SceneManager.UnloadSceneAsync(2);


3. Через объект Scene
Scene dungeonScene = SceneManager.GetSceneByName("Dungeon");
SceneManager.UnloadSceneAsync(dungeonScene);


Важно:
Используйте UnloadSceneAsync (а не синхронный метод)
Нельзя выгрузить активную сцену

🔄 Режимы выгрузки
При выгрузке можно указать UnloadOptions:
// Выгрузить сразу (без проверки зависимостей)
SceneManager.UnloadSceneAsync("Dungeon", UnloadSceneOptions.None);

// Безопасная выгрузка (проверяет ссылки на объекты)
SceneManager.UnloadSceneAsync("Dungeon", UnloadSceneOptions.UnloadAllEmbeddedSceneObjects);


🔗 Обмен объектами между сценами
Чтобы объект сохранился при выгрузке сцены:

1. Перенос в другую сцену
GameObject player = GameObject.Find("Player");
SceneManager.MoveGameObjectToScene(player, SceneManager.GetActiveScene());


2. Создание DontDestroyOnLoad - Объект не уничтожается при загрузке другой сцены
GameObject audioManager = GameObject.Find("AudioManager");
DontDestroyOnLoad(audioManager);


⚠️ Важные нюансы
- Порядок загрузки — последняя загруженная сцена может перекрывать предыдущие
- Производительность — слишком много сцен = нагрузка на CPU
- Освещение — требует перестройки (Lightmap) при комбинации сцен
Стоит ли мне сделать такую игру на Unity?
Shape Match!

Ещё неделю назад закончил небольшую игрушку, но написать решил только сейчас.

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

При разработке помимо стандартного функционала Unity использовался DOTween для анимаций интерфейса и YG Plugin для интеграции с Yandex Games.

Подробнее изучить архитектуру проекта можно вот тут:
https://github.com/RedAtomTeam/ShapeMatch

Поиграть вот здесь:
https://yandex.com/games/app/442255?lang=ru
🎨 UI в Unity: Часть 1 – Canvas в Unity

Графический интерфейс в Unity строится на трёх китах: Canvas, Raycaster и Canvas Scaler. Давайте разберём, как они работают вместе!

🖼 Canvas — холст для UI
Что делает?
1. Контейнер для всех UI-элементов (кнопки, тексты, изображения)
2. Определяет пространство рендеринга:
2.1. Screen Space (поверх камеры)
2.2. World Space (как 3D-объект в сцене)
2.3. Camera Space (привязан к камере)

🎯 Graphic Raycaster — обработка кликов
Зачем нужен?
1. Отвечает за взаимодействие с UI (клики, наведение)
2. Работает только с объектами внутри Canvas

Совет:
1. Для World Space UI добавьте Physics Raycaster на камеру – он нужен для обработки кликов в мировом пространстве.

📏 Canvas Scaler — контроль масштаба
Решает проблему: Как UI должен выглядеть на разных разрешениях?
Режимы масштабирования:

1. Constant Pixel Size — UI всегда одного размера в пикселях(Десктоп-приложения)
2. Scale With Screen Size — Масштабируется относительно разрешения(Мобильные игры)
3. Constant Physical Size — Сохраняет размер в реальных единицах (мм/дюймах)(AR/VR)

Настройки для Scale With Screen Size:
Reference Resolution (например, 1920x1080)
Match (Width/Height) — что в приоритете

🔗 Как они связаны?
Canvas рендерит UI-элементы
Canvas Scaler адаптирует их под разные экраны
Graphic Raycaster обрабатывает ввод (клики, тачи)

💡 Практические советы
Для мобильных игр используйте:
Scale Mode: Scale With Screen Size
Screen Match Mode: Expand (чтобы UI не обрезался)
Оптимизация:
Объединяйте элементы в одном Canvas (меньше draw calls)
Отключайте Raycaster для статичных UI
World Space UI:
Настройте Event Camera в Graphic Raycaster
Добавьте Physics Raycaster на основную камеру

⚠️ Частые ошибки
1. UI не кликается → Проверьте:
1.1. Наличие Graphic Raycaster
1.2. Блокирующие прозрачные объекты
1.3. Order in Layer
2. Размытый текст → Выберите правильный Render Mode в Canvas
3. UI "уплывает" → Для World Space настройте Rect Transform
🛠 UI в Unity: Часть 2 – Пассивные UI-элементы

Пассивные элементы — это UI-компоненты, которые не взаимодействуют с пользователем напрямую, но критично важны для организации интерфейса.

🔍 Основные элементы:
1. Image (Raw Image)
1.1. Простое отображение спрайтов/текстур
1.2. Используется для:
1.2.1. Фонов
1.2.2. Иконок без клика
1.2.3. Декоративных элементов
2. Text (TextMeshPro)
2.1. Вывод статичного текста (подписи, описания)
2.2. Важно: Для динамического текста лучше использовать TextMeshPro
3. Mask
3.1. Обрезает дочерние элементы по заданной области
3.2. Пример: скролл-списки с видимой областью
4. Layout Group
4.1. Автоматически упорядочивает дочерние объекты:
4.1.1. Horizontal/Vertical – линейное расположение
4.1.2. Grid – сетка
4.1.3. Content Size Fitter – подстраивает размер под контент
5. Panel
5.1. Группирует другие элементы (обычно с Image-фоном)

💡 Зачем нужны?
Организация – структурируют интерфейс
Оптимизация – уменьшают количество draw calls при группировке
Гибкость – работают в связке с активными элементами (кнопками, полями ввода)

⚠️ Ошибки новичков:
Использование Image вместо Raw Image для динамических текстур
Отсутствие Layout Group при ручном позиционировании однотипных элементов
🥰1
🎬 UI в Unity: Часть 3 – Видео

Хотите добавить видеоролики в свою игру?

Разберём все ключевые моменты — от форматов до практической реализации.

📹 Поддерживаемые форматы
Unity работает с этими видеоформатами:
- MP4 (H.264 + AAC) — рекомендуемый
- MOV (только для macOS/iOS)
- WebM (для WebGL)

⚠️ Важно:
- Видео должно быть перекодировано под платформу (например, через HandBrake)
- Разрешение желательно кратное 4 (например, 1920×1080)

🛠 3 способа вывода видео
1. VideoPlayer + RenderTexture (универсальный)
Как настроить:
- Импортируйте видеофайл в проект
- Создайте RenderTexture (Assets → Create → Render Texture)
- Добавьте компонент VideoPlayer на объект:
VideoPlayer vp = gameObject.AddComponent<VideoPlayer>();
vp.renderMode = VideoRenderMode.RenderTexture;
vp.targetTexture = myRenderTexture; // Ваша RenderTexture
vp.Play();

- Назначьте RenderTexture на материал объекта

Плюсы:
- Работает на всех платформах
- Можно проецировать на 3D-объекты

2. VideoPlayer + RawImage (для UI)
Настройка:
- Создайте Canvas и добавьте RawImage
- Настройте VideoPlayer:
VideoPlayer vp = gameObject.AddComponent<VideoPlayer>();
vp.renderMode = VideoRenderMode.MaterialOverride;
vp.targetMaterialRenderer = GetComponent<Renderer>();
vp.Play();

Идеально для:
- Заставок
- Видеофонов меню

3. Прямой вывод на камеру
Настройка:
VideoPlayer vp = cameraGO.AddComponent<VideoPlayer>();
vp.renderMode = VideoRenderMode.CameraFarPlane;
vp.Play();

Особенности:
- Видео заменяет фон камеры
- Подходит для AR/VR

⚠️ Частые проблемы
1. Чёрный экран → Проверьте:
- Назначен ли RenderTexture
- Поддерживается ли кодек на целевой платформе
2. Нет звука → Добавьте AudioSource и настройте вывод аудио
3. Тормозит на мобилках → Уменьшите разрешение видео (720p вместо 4K)
🎮 UI в Unity: Часть 4 – EventSystem или как работает взаимодействие с UI?

EventSystem — это "мозг" обработки ввода в Unity UI. Без него ваши кнопки не будут кликаться! Разберём его работу в 5 ключевых пунктах.

🔧 Что делает EventSystem?
1. Обрабатывает клики/тапы через StandaloneInputModule (ПК/мобилки)
2. Передаёт события всем UI-элементам
3. Управляет фокусом (например, для клавиатурного ввода)

🛠 Основные компоненты
Input Module — Преобразует ввод (мышь/тач/геймпад) в события
Raycaster — Определяет, по какому объекту кликнули
EventSystem — Координирует работу всей системы

Важно:
На сцене должен быть ровно один EventSystem
Для World Space UI нужен Physics Raycaster

💡 Как настроить?
1. Автоматически:
При создании UI через GameObject → UI → Button Unity добавляет:
- EventSystem
- StandaloneInputModule
- GraphicRaycaster
2. Вручную:
// Добавить кастомный ввод (например, для геймпада)
var es = gameObject.AddComponent<EventSystem>();
es.AddComponent<StandaloneInputModule>();


⚠️ Частые проблемы
1. Кнопки не работают → Проверьте:
- Наличие EventSystem на сцене
- Не перекрывают ли другие объекты UI
- Не отключён ли Raycaster
2. Не работает тач на мобилках → Замените StandaloneInputModule на TouchInputModule
3. World Space UI не кликается → Добавьте PhysicsRaycaster на камеру
🎮 UI в Unity: Часть 5 – Активные UI-элементы

Активные элементы — это "живые" компоненты интерфейса, которые реагируют на действия пользователя. Давайте разберём ключевые из них!

🕹 Основные активные элементы
1. Кнопка (Button)
- Зачем: Основной элемент для кликов/тапов
- Фишки:
- 4 состояния (Normal, Highlighted, Pressed, Disabled)
- Событие onClick для привязки действий

// Пример скрипта для кнопки
button.onClick.AddListener(() => Debug.Log("Клик!"));


2. Поле ввода (InputField/TMP_InputField)
- Зачем: Текстовый ввод (логины, чаты)
- Фишки:
- Валидация (цифры/буквы/пароли)
- События onValueChanged, onEndEdit

inputField.onEndEdit.AddListener(text => Debug.Log($"Введено: {text}"));


3. Переключатель (Toggle)
- Зачем: Чекбоксы и радио-кнопки
- Фишки:
- Группировка через Toggle Group
- Событие onValueChanged

toggle.onValueChanged.AddListener(isOn => Debug.Log($"Состояние: {isOn}"));


4. Слайдер (Slider)
- Зачем: Выбор значений в диапазоне (громкость, настройки)
- Фишки:
- Настройка min/max значений
- Событие onValueChanged

slider.onValueChanged.AddListener(value => audio.volume = value);


5. Скроллвью (ScrollView)
- Зачем: Прокрутка контента (списки, инвентарь)
- Фишки:
- Вертикальный/горизонтальный режим
- Оптимизация через Mask + Layout Group

⚡️ Важные особенности
- Наследование от Selectable – все активные элементы имеют:
- Состояния (Hover, Pressed)
- Навигацию (клавиши/геймпад)
- Требуют EventSystem – без него не будут работать!

💡 Советы по использованию
1. Для текста всегда выбирайте TextMeshPro (лучше качество)
2. Оптимизация: Отключайте ненужные Raycast Target у декоративных элементов
3. Анимации: Добавляйте эффекты через Animator к состояниям (например, пульсацию при наведении)