Akrus Games | Unity
2.95K subscribers
408 photos
89 videos
11 files
351 links
Самые годные лайфхаки по unity c#

Сотрудничество/реклама/помощь @Akrus001
Download Telegram
ScriptableObjects: Данные без сцен

Что это?
Классы-контейнеры для хранения данных и логики, не привязанных к GameObject. Как "ресурсы" в проекте.

Зачем?
• Хранение настроек (оружие, враги, уровни)
• Создание системы событий (GameEvents)
• Реализация архитектуры на основе данных
• Упрощение балансировки игры

Как создать?
1. Создай класс-наследник ScriptableObject:
[CreateAssetMenu(fileName = "NewWeapon", menuName = "Items/Weapon")]
public class WeaponSO : ScriptableObject
{
public string weaponName;
public int damage;
public Sprite icon;
}


2. ПКМ в Project View → Create → Items/Weapon
3. Настраивай параметры в инспекторе

Как использовать?
public WeaponSO currentWeapon;

void Start()
{
Debug.Log($"Урон: {currentWeapon.damage}");
}


Важно!
• Идеально для конфигов и событий
• Не для динамических объектов
• Для runtime изменений нужен паттерн Memento

💡 Применяй: настройки игрока, система диалогов, глобальные ивенты.
#Unity #CSharp #ScriptableObjects #GameDev
🔥21😁11
Coroutines: Асинхронные операции

Что это?
Функции, выполняющиеся с задержками между кадрами. Не блокируют основной поток.

Зачем?
• Плавные анимации
• Таймеры и задержки
• Постепенная загрузка контента
• Работа с WWW/UnityWebRequest

Как использовать?
IEnumerator Fade() 
{
float alpha = 1f;
while (alpha > 0)
{
alpha -= Time.deltaTime * 0.5f;
GetComponent<Renderer>().material.color = new Color(1, 1, 1, alpha);
yield return null; // Ждём следующий кадр
}
}

// Запуск:
StartCoroutine(Fade());


Важные нюансы:
• Всегда объявляй как IEnumerator
yield return new WaitForSeconds(2f) - пауза
yield return new WaitUntil(() => condition) - ожидание условия
• Останавливай через StopCoroutine()

💡 Не используй для физики! Только для визуала и таймеров.
#Unity #Coroutines #CSharp #GameDev
🔥521
OnTrigger vs OnCollision: В чём разница?

Когда что использовать?
OnTriggerEnter():
• Объекты проходят "сквозь" друг друга
• Нужно детектировать пересечение (зоны, предметы)
• Обязательно: isTrigger = true на коллайдере

OnCollisionEnter():
• Объекты физически взаимодействуют (отталкиваются)
• Нужна реалистичная физика (падение, толчки)
• isTrigger = false

Пример триггера:
void OnTriggerEnter(Collider other) 
{
if (other.CompareTag("Coin"))
{
Destroy(other.gameObject);
coinsCount++;
}
}



Пример коллизии:
void OnCollisionEnter(Collision collision) 
{
if (collision.gameObject.CompareTag("Enemy"))
{
TakeDamage(10);
}
}


💡 Для 2D используй OnTriggerEnter2D и OnCollisionEnter2D!
#Unity #GameDev #Physics #CSharp
4🔥11
PlayerPrefs: Сохранение настроек

Что это?
Система для простого сохранения данных между запусками игры.

Что хранить?
• Настройки громкости
• Лучший счёт
• Прогресс уровней
• Язык интерфейса

Как работает?
// Запись:
PlayerPrefs.SetInt("HighScore", 100);
PlayerPrefs.SetFloat("Volume", 0.85f);
PlayerPrefs.SetString("PlayerName", "Nick");
PlayerPrefs.Save(); // Не забывай!

// Чтение:
int score = PlayerPrefs.GetInt("HighScore", 0); // 0 - значение по умолчанию


Ограничения:
• Только базовые типы (int, float, string)
• Максимум 1 МБ данных
• Не для сложных структур (используй JSON + FileIO)
• Легко редактируется игроком

💡 Всегда проверяй ключи через HasKey() перед чтением!
#Unity #CSharp #PlayerPrefs #GameDev
5🔥21
C# Events в Unity: Избавься от спагетти-кода

Что это?
Паттерн, позволяющий объектам общаться друг с другом без прямых ссылок.

Зачем?
- Сильно снизить связность кода
- Делать код modular и переиспользуемым
- Легко добавлять новую реакцию на событие (звук, анимацию, UI)
- Избегать постоянных проверок в Update (if (isDead) {...})

Как создать?
1. Объяви делегат и событие
2. Подпиши метод на событие
3. Вызови событие, когда что-то произошло

Пример (Смерть игрока):
public class PlayerHealth : MonoBehaviour
{
// 1. Объявляем событие
public static event Action OnPlayerDeath;

public void TakeDamage()
{
if (health <= 0)
{
// 3. Вызываем событие
OnPlayerDeath?.Invoke();
}
}
}

Как использовать?
public class GameManager : MonoBehaviour
{
void OnEnable()
{
// 2. Подписываемся на событие
PlayerHealth.OnPlayerDeath += HandlePlayerDeath;
}

void OnDisable()
{
// Важно: отписываемся при выключении
PlayerHealth.OnPlayerDeath -= HandlePlayerDeath;
}

void HandlePlayerDeath()
{
// Реакция на смерть игрока
Debug.Log("Game Over!");
Time.timeScale = 0f;
}
}

Важно!
- Всегда отписывайся от событий в OnDisable или OnDestroy, чтобы не было утечек памяти.
- ?.Invoke() проверяет, есть ли подписчики (null-check).

#Unity #CSharp #Events #Delegates #Optimization
🔥732🎄11
UnityEvents vs Action: когда что использовать?

В чём разница?
Оба подхода реализуют паттерн «наблюдатель», но с разным уровнем гибкости и сложности.

UnityEvent
Идеально для дизайнеров и работы в инспекторе.
Плюсы:
- Виден в инспекторе. Дизайнер уровней может сам настраивать связи между объектами.
- Сериализуется (сохраняется между запусками редактора).
- Простота использования.

Минусы:
- Меньшая производительность по сравнению с Action.
- Не такая гибкая подписка из кода.

Как использовать UnityEvent:
1. Объяви публичное поле в классе:
public UnityEvent OnSomethingHappened;
2. В инспекторе на объекте с этим скриптом появится сворачиваемый список вызовов (Calls).
3. Перетаскивай в него любой объект и выбирай его метод для вызова.

Action
Мощный инструмент для программистов. Работает только в коде.
Плюсы:
- Высокая производительность.
- Чистый и лаконичный синтаксис подписки.
- Полный контроль над подписками и отписками.

Минусы:
- Не виден в инспекторе. Только для программистов.

Как использовать Action:
1. Объяви событие в классе:
public static Action<int> OnEnemyDied;
2. Для вызова события в нужном месте:
OnEnemyDied?.Invoke(scoreValue);
3. В другом классе подпишись на событие:
GameManager.OnEnemyDied += AddScore;
Не забудь отписаться при уничтожении объекта:
void OnDestroy() => GameManager.OnEnemyDied -= AddScore;

Итог:
➡️ Используй UnityEvent для настройки взаимодействий между объектами в инспекторе (двери, кнопки, переключатели).
➡️ Используй Action для быстрых и частых событий внутри кода (система достижений, UI, логика игры).

Выбирай инструмент под задачу! 💪

Пост предложил @Fylht009
#Unity #CSharp #GameDev #Events #Gamedevelopment
🔥7111
C# Атрибуты в Unity: мета-инструкции для кода

Что это?
Специальные метки для классов, переменных или методов. Они дают подсказки движку и редактору Unity, как с ними работать.

Зачем?
- Делать переменные видимыми в Инспекторе без ключевого слова public
- Задавать диапазоны значений для ползунка
- Добавлять в контекстное меню кнопки для вызова методов
- Скрывать ненужные поля в Инспекторе

Как использовать?
Просто напиши имя атрибута в квадратных скобках [] перед элементом.

Популярные атрибуты:

[SerializeField]
Показывает private поле в Инспекторе.
[SerializeField] private int _health;


[Range(min, max)]
Создает ползунок для значения.
[Range(0f, 10f)] public float speed;


[Header("Название")]
Добавляет заголовок в Инспектор.
[Header("Player Settings")]
public int playerScore;


[Tooltip("Подсказка")]
Показывает текст при наведении курсора.
[Tooltip("Сила прыжка в ньютонах")] 
public float jumpForce;


[HideInInspector]
Прячет public поле из Инспектора.
[HideInInspector] public bool isGrounded;


Важно!
Атрибуты не меняют логику кода, а только управляют его отображением и поведением в редакторе Unity. Еще в поля можно писать только константы, не переменные!

💡 Используй, чтобы сделать процесс настройки объектов интуитивным и удобным.

Пост попросил @Cheeeeeeeb
#Unity #Unity3D #CSharp #Атрибуты #Gamedevelopment
🔥12211
Pattern Matching в C#: Property и Tuple patterns

Зачем?
Упростить проверки сложных условий. Вместо вложенных if — чистый и читаемый код.

Property pattern
Проверяет свойства объекта прямо в условии:

if (weapon is { Ammo: 0, IsReloading: false })
{
// Оружие без патронов и не перезаряжается:
StartReload();
}


Tuple pattern
Идеален для проверки нескольких значений одновременно:

string result = (x, y) switch
{
(0, 0) => "Точка в начале координат",
( > 0, > 0) => "Точка в первой четверти",
( < 0, _) => "Точка слева от оси Y", // _ — любое значение
_ => "Точка в другой области"
};


Где использовать?
• Вместо громоздких if/else для состояний объекта
• Для обработки входных данных (например, результат метода)
• В switch выражениях для возврата значений

Важно!
• Работает в is, switch и switch-выражениях (как выше)
_ — это discard (игнорирование значения)
• В property pattern можно проверять вложенные свойства: Player { Health: { Current: 0 } }

💡 Используй эти паттерны для чистого и безопасного кода. Сокращай количество строк и повышай читаемость!

Пост предложил @u006E10011
#CSharp #Unity #Programming #PatternMatching #UnityDev
8🔥31
Кастомные атрибуты в C#: твой код — чище и умнее

Что это?
Специальные метки для переменных, методов или классов. Они не меняют логику, но дают подсказки движку или редактору.

Зачем?
• Валидация данных прямо в инспекторе
• Красивое и логичное группирование полей
• Сокрытие или запрет на редактирование переменных при определенных условиях
• Автоматизация рутинных задач

Как создать?
Наследуйся от класса PropertyAttribute.

using UnityEngine;

public class HeaderColorAttribute : PropertyAttribute
{
public readonly Color Color;
public HeaderColorAttribute(float r, float g, float b)
{
Color = new Color(r, g, b);
}
}


Как использовать?
Повесь атрибут над полей класса.

public class Player : MonoBehaviour
{
[HeaderColor(1, 0, 0)] // Красный заголовок
[SerializeField] private string _playerName;

[HeaderColor(0, 1, 0)] // Зеленый заголовок
[SerializeField] private int _health;
}


Важно!
• Для отрисовки в инспекторе нужен кастомный Editor скрипт
• Атрибуты работают в рантайме — это мощный инструмент для архитектуры
• Не злоупотребляй сложной логикой в атрибутах

💡 Применяй для: создания понятных инспекторов, валидации настроек, автоматизации.
Создай свой первый атрибут для подсветки поля, если значение отрицательное!

#Unity #CSharp #Programming #Attributes #Gamedev
1🔥521
Паттерн «Состояние» (State): Умное управление поведением

Что это?
Паттерн, который позволяет объекту изменять свое поведение в зависимости от внутреннего состояния. Как режимы работы устройства.

Зачем?
• Избегать гигантских конструкций switch или if-else
• Четко разделять логику разных состояний
• Упрощать добавление новых состояний

Как работает?
1. Создаешь интерфейс состояния (IState) с методами Enter(), Update(), Exit()
2. Реализуешь конкретные состояния (например, IdleState, MoveState, AttackState)
3. Создаешь класс StateMachine, который управляет текущим состоянием

Пример: Простая машина состояний врага
// 1. Интерфейс состояния
public interface IEnemyState
{
void Enter();
void Update();
void Exit();
}

// 2. Конкретное состояние - Преследование
public class ChaseState : IEnemyState
{
public void Enter() { Debug.Log("Начинаю преследование!"); }
public void Update() { /* Логика движения к игроку */ }
public void Exit() { Debug.Log("Прекращаю преследование."); }
}

// 3. Машина состояний
public class EnemyAI : MonoBehaviour
{
IEnemyState currentState;

public void ChangeState(IEnemyState newState)
{
currentState?.Exit();
currentState = newState;
currentState?.Enter();
}

void Update()
{
currentState?.Update();
}
}

// Использование:
EnemyAI ai = GetComponent<EnemyAI>();
ai.ChangeState(new ChaseState());


Важно!
• Каждое состояние отвечает только за свою логику
• Переход между состояниями происходит в одном месте (StateMachine)
• Отлично сочетается с другими паттернами (например, Command)

💡 Применяй для: ИИ врагов, анимаций, управления игроком (бег, прыжок, атака).

#Unity #CSharp #Patterns #StateMachine #GameDev
6🎄4🤯2
Выбор IDE для Unity: инструменты для кода

Что это?
IDE — это твой главный редактор для написания скриптов. Где код становится игрой.

Топ-3 варианта:

Visual Studio (официальный стандарт)
• Плюсы: идеальная интеграция с Unity, автодополнение кода, отладка прямо в редакторе.
• Минусы: может быть тяжеловата для слабых ПК.

Rider — мощный профи
• Плюсы: умный анализ кода, находит ошибки "на лету", встроенные шаблоны для Unity.
• Минусы: платный (но есть бесплатный пробный период).

VS Code — легкий и быстрый
• Плюсы: быстрая работа, тысячи расширений, бесплатный.
• Минусы: требует ручной настройки для работы с Unity.

Как выбрать?
- Новичок? Бери Visual Studio — уже настроена под Unity.
- Профи-кодер? Попробуй Rider — скорость разработки возрастет.
- Любитель кастомизации? VS Code даст полную свободу.

💡 Важно: в Unity (Edit → Preferences → External Tools) выбери свою IDE как внешний редактор.

Пиши код в удобной среде — это ускорит разработку!
#Unity #IDE #GameDev #CSharp
622
Паттерн «Состояние» (State): Умное управление поведением

Что это?
Паттерн, который позволяет объекту изменять свое поведение в зависимости от внутреннего состояния. Как режимы работы устройства.

Зачем?
• Избегать гигантских конструкций switch или if-else
• Четко разделять логику разных состояний
• Упрощать добавление новых состояний

Как работает?
1. Создаешь интерфейс состояния (IState) с методами Enter(), Update(), Exit()
2. Реализуешь конкретные состояния (например, IdleState, MoveState, AttackState)
3. Создаешь класс StateMachine, который управляет текущим состоянием

Пример: Простая машина состояний врага
// 1. Интерфейс состояния
public interface IEnemyState
{
void Enter();
void Update();
void Exit();
}

// 2. Конкретное состояние - Преследование
public class ChaseState : IEnemyState
{
public void Enter() { Debug.Log("Начинаю преследование!"); }
public void Update() { /* Логика движения к игроку */ }
public void Exit() { Debug.Log("Прекращаю преследование."); }
}

// 3. Машина состояний
public class EnemyAI : MonoBehaviour
{
IEnemyState currentState;

public void ChangeState(IEnemyState newState)
{
currentState?.Exit();
currentState = newState;
currentState?.Enter();
}

void Update()
{
currentState?.Update();
}
}

// Использование:
EnemyAI ai = GetComponent<EnemyAI>();
ai.ChangeState(new ChaseState());


Важно!
• Каждое состояние отвечает только за свою логику
• Переход между состояниями происходит в одном месте (StateMachine)
• Отлично сочетается с другими паттернами (например, Command)

💡 Применяй для: ИИ врагов, анимаций, управления игроком (бег, прыжок, атака).

#Unity #CSharp #Patterns #StateMachine #GameDev
🎄432
Чистый код в Unity: правила для читаемости и поддержки

Что это?
Правила написания кода, которые делают его понятным для тебя и других разработчиков.

Зачем?
• Легче находить и исправлять ошибки
• Упрощается командная работа
• Ускоряется добавление нового функционала

Основные правила:

1️⃣ Именуй методы как действия
Название должно сразу объяснять суть.
// Хорошо:
void MovePlayer() {}
void CalculateDamage() {}

// Плохо:
void DoSomething() {}
void Process() {}


2️⃣ Заменяй "магические числа" на константы
Числа в коде без пояснений запутывают.
// Вместо:
if (health < 30) {}

// Используй:
private const int LOW_HEALTH_THRESHOLD = 30;
if (health < LOW_HEALTH_THRESHOLD) {}


3️⃣ Разделяй ответственность по классам
Один класс — одна задача.
• PlayerMovement.cs — за перемещение
• PlayerHealth.cs — за здоровье
• PlayerInventory.cs — за инвентарь

4️⃣ Убирай дублирование кода
Повторяющуюся логику выноси в отдельные методы.
// Вынеси в метод:
private void PlaySound(AudioClip clip)
{
audioSource.PlayOneShot(clip);
}


5️⃣ Пиши осмысленные комментарии
Объясняй "почему", а не "что".
// Плохо: 
x += 10; // Добавляем 10 к x

// Хорошо:
x += bonusScore; // Начисляем бонус за сложное достижение


💡 Помни: код читают чаще, чем пишут. Делай его понятным!
#Unity #CSharp #GameDev #ЧистыйКод
🔥74311
⚡️ Unity: C# Data-Oriented Design для максимальной производительности

Устал от медленного foreach по тысячам объектов? Struct of Arrays — это подход, который ускоряет обработку данных, как в настоящем ECS.

Проблема стандартного подхода:
foreach (var enemy in enemies) {
enemy.Update(); // Кэш-промахи, разбросанные объекты в памяти
}

• Кэш-промахи процессора
• Разбросанные в памяти объекты
• Виртуальные вызовы

Решение: Struct of Arrays (основа ECS)

1️⃣ Правильная структура данных:
public struct EnemyChunk {
public Vector3[] positions;
public float[] healths;
public int count;
}

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

2️⃣ Оптимизированная итерация:
for (int i = 0; i < chunk.count; i++) {
chunk.positions[i] += Vector3.forward * speed;
chunk.healths[i] -= Time.deltaTime;
}

• Нет виртуальных вызовов
• Данные последовательны в кэше
• Автоматическая векторизация
• Параллелизация

💡 Реальный результат:
Обработка 10 000 юнитов ускоряется в 2-5 раз по сравнению с GameObject/GetComponent в цикле. Даже против готового списка MonoBehaviour выигрыш за счет кэш-дружественности.

🚀 Следующий уровень:
Unity.Entities (DOTS) — автоматическое управление чанками, параллельная обработка и Burst компиляция.

💬 Используешь плотные массивы для данных? Делитесь опытом в комментариях!
🔔 Подпишись — больше фишек для инди-оптимизации впереди.

👉Akrus Games | Unity

#Unity3D #UnityOptimization #ECS #DOTS #CSharp
71
C# Атрибуты в Unity: мета-инструкции для кода

Что это?
Специальные метки для классов, переменных или методов. Они дают подсказки движку и редактору Unity, как с ними работать.

Зачем?
- Делать переменные видимыми в Инспекторе без ключевого слова public
- Задавать диапазоны значений для ползунка
- Добавлять в контекстное меню кнопки для вызова методов
- Скрывать ненужные поля в Инспекторе

Как использовать?
Просто напиши имя атрибута в квадратных скобках [] перед элементом.

Популярные атрибуты:

[SerializeField]
Показывает private поле в Инспекторе.
[SerializeField] private int _health;


[Range(min, max)]
Создает ползунок для значения.
[Range(0f, 10f)] public float speed;


[Header("Название")]
Добавляет заголовок в Инспектор.
[Header("Player Settings")]
public int playerScore;


[Tooltip("Подсказка")]
Показывает текст при наведении курсора.
[Tooltip("Сила прыжка в ньютонах")] 
public float jumpForce;


[HideInInspector]
Прячет public поле из Инспектора.
[HideInInspector] public bool isGrounded;


Важно!
Атрибуты не меняют логику кода, а только управляют его отображением и поведением в редакторе Unity. Еще в поля можно писать только константы, не переменные!

💡 Используй, чтобы сделать процесс настройки объектов интуитивным и удобным.

Пост попросил @Cheeeeeeeb
#Unity #Unity3D #CSharp #Атрибуты #Gamedevelopment
11🔥5
C# Атрибуты в Unity: мета-инструкции для кода

Что это?

Специальные метки для классов, переменных или методов. Они дают подсказки движку и редактору Unity, как с ними работать.

Зачем?

- Делать переменные видимыми в Инспекторе без ключевого слова public
- Задавать диапазоны значений для ползунка
- Добавлять в контекстное меню кнопки для вызова методов
- Скрывать ненужные поля в Инспекторе

Как использовать?

Просто напиши имя атрибута в квадратных скобках [] перед элементом.

Популярные атрибуты:

[SerializeField]
Показывает private поле в Инспекторе.
[SerializeField] private int _health;


[Range(min, max)]
Создает ползунок для значения.
[Range(0f, 10f)] public float speed;


[Header("Название")]
Добавляет заголовок в Инспектор.
[Header("Player Settings")]
public int playerScore;


[Tooltip("Подсказка")]

Показывает текст при наведении курсора.
[Tooltip("Сила прыжка в ньютонах")] 
public float jumpForce;


[HideInInspector]

Прячет public поле из Инспектора.
[HideInInspector] public bool isGrounded;


Важно!

Атрибуты не меняют логику кода, а только управляют его отображением и поведением в редакторе Unity. НО есть атрибут Obsolete который не относится к юнити и не влияет на отображение в редакторе. Еще в поля можно писать только константы, не переменные!

💡 Используй, чтобы сделать процесс настройки объектов интуитивным и удобным.

#Unity #Unity3D #CSharp #Атрибуты #Gamedevelopment
🔥8🎄2