Unity C# — скрипты для новичков
Подборка готовых скриптов Unity на C# с построчным разбором — «что написано» и «зачем так». Материал рассчитан на тех, кто ищет в Google «unity скрипт движение wasd», «monobehaviour пример», «unity прыжок rigidbody», «OnTriggerEnter собрать предмет», «unity instantiate prefab» или готовит лабораторную, курсовую и первый мини-проект в редакторе.
Для кого эта статья
| Аудитория | Зачем открыть |
|---|---|
| Школьники | Информатика, кружок, первый Unity-проект |
| Студенты | Лабораторная «игровой движок», зачёт по C# |
| Самоучки | Скопировать код → прикрепить к объекту → разобрать по таблице |
| После Python | Уже делали Turtle или Pygame — те же идеи (цикл, ввод, счёт), другой синтаксис |
Как работать с примером:
- Создайте скрипт в Unity (
Create→C# Script). - Скопируйте код — имя файла = имя класса (
MoveWASD.cs→class MoveWASD). - Перетащите скрипт на объект в Hierarchy.
- Заполните поля в Inspector (ссылки на объекты, префабы, слои).
- Нажмите Play ▶ — смотрите результат и Console при ошибках.
Скрипты запускаются только в Unity Editor или в собранной игре. В браузере, как симулятор Turtle на этой же странице Lab, они не выполняются.
Установка редактора, окна, GameObject — Разработка на Unity. Синтаксис C# — первая программа, ООП в C# (блок Unity). Lifecycle и API — Справочник по Unity. 2D на Python без движка — Pygame — мини-игры.
Краткий указатель — что ищут в Google
| Раздел | Типичный запрос |
|---|---|
| Каркас MonoBehaviour | unity monobehaviour пример, unity script template, awake start update |
| Вращение куба | unity rotate object script, transform rotate c# |
| Движение WASD | unity movement wasd, input getaxis horizontal, transform translate |
| Прыжок | unity jump rigidbody, addforce space, fixedupdate physics |
| Монетка | unity ontriggerenter, collect coin script, comparetag player |
| Спавн | unity instantiate prefab, spawn object on key press |
| Камера | unity camera follow player, lateupdate camera script |
| UI и счёт | unity ui button script, update text score |
| Смена цвета | unity change material color, getcomponent renderer |
| Патруль и враг | unity enemy follow player, move towards script |
| Перезагрузка сцены | unity reload scene, scenemanager loadscene |
| Частые ошибки | nullreferenceexception unity, ontriggerenter not working |
Из чего состоит любой Unity-скрипт
В консольном C# программа начинается с static void Main(). В Unity точки входа нет — движок сам вызывает методы вашего класса каждый кадр или один раз при старте.
| Часть | Роль |
|---|---|
Файл .cs | Исходный код; компилируется Unity при сохранении |
MonoBehaviour | Базовый класс — скрипт становится компонентом на GameObject |
[SerializeField] | Поле видно в Inspector; значение можно менять без правки кода |
transform | Позиция, поворот, масштаб этого объекта на сцене |
Update | Логика каждый кадр — ввод, UI, движение через transform |
FixedUpdate | Шаг физики (~50 раз в секунду) — силы, Rigidbody |
Time.deltaTime | Сколько секунд прошло с прошлого кадра — без него скорость зависит от FPS |
Чем Unity отличается от консольного C# и Pygame
| Консоль | Pygame | Unity | |
|---|---|---|---|
| Старт | Main() один раз | while running вручную | Awake / Start / Update вызывает движок |
| Мир | Только переменные | Окно + поверхность | Сцена с объектами в Inspector |
| Ввод | Console.ReadLine | event.get() | Input.GetKey, GetAxis |
| Вывод | WriteLine | draw + flip | Движок рисует 3D/2D сам |
Обязательный каркас MonoBehaviour
Любой учебный скрипт повторяет одну структуру. Имя файла и имя класса должны совпадать — иначе Unity покажет ошибку компиляции.
using UnityEngine;
public class MyFirstScript : MonoBehaviour
{
[SerializeField] private float speed = 5f;
void Awake()
{
Debug.Log("Awake: объект создан");
}
void Start()
{
Debug.Log("Start: сцена пошла");
}
void Update()
{
// Каждый кадр — ввод, таймеры, transform.Translate
// Rigidbody — в FixedUpdate
}
}
Разбор сигнатуры класса — по словам
| Часть | Смысл |
|---|---|
using UnityEngine; | Подключает API движка: MonoBehaviour, Vector3, Input, Debug |
public class MyFirstScript | Имя класса = имя файла MyFirstScript.cs |
: MonoBehaviour | Наследование — без этого Unity не прикрепит скрипт к объекту |
[SerializeField] private float speed | Поле private, но видно в Inspector; 5f — литерал float |
void Awake() | Вызывается один раз при создании объекта; кешируйте GetComponent |
void Start() | Один раз перед первым Update; все Awake уже отработали |
void Update() | Каждый кадр; умножайте скорость на Time.deltaTime |
Debug.Log(...) | Белое сообщение в Console; ошибки — Debug.LogError |
Порядок вызова lifecycle (важно для экзамена)
| Момент | Метод | Пример использования |
|---|---|---|
| Объект появился | Awake | rb = GetComponent<Rigidbody>() |
| Перед первым кадром | Start | score = 0, загрузка из PlayerPrefs |
| Каждый кадр | Update | Input.GetKeyDown, таймеры |
| Шаг физики | FixedUpdate | AddForce, изменение velocity |
| После всех Update | LateUpdate | Камера следует за игроком |
Что попробовать: прикрепите скрипт к Cube, нажмите Play — в Console появятся две строки Awake и Start (порядок всегда такой).
В примерах — классический Input.GetAxis("Horizontal") и Input.GetKeyDown. Он работает в большинстве учебных проектов (WASD и стрелки уже настроены). В новых шаблонах Unity может быть пакет Input System — тогда в Project Settings → Player → Active Input Handling выберите один подход. Подробнее — глава 3.
Стартовые скрипты
Примеры ниже — для 3D-шаблона Unity (Cube, Capsule, Plane). Для 2D используйте Rigidbody2D, Collider2D, OnTriggerEnter2D — логика та же, другие типы.
Вращение объекта
Типичный запрос: unity rotate cube script, transform rotate update.
Задача: куб крутится вокруг вертикальной оси без участия игрока — первый «живой» объект на сцене.
Настройка сцены:
GameObject→3D Object→ Cube (или используйте куб по умолчанию).- Создайте скрипт
RotateCube.cs, вставьте код ниже. - Перетащите скрипт на Cube → Play.
using UnityEngine;
public class RotateCube : MonoBehaviour
{
[SerializeField] private float degreesPerSecond = 90f;
void Update()
{
transform.Rotate(Vector3.up, degreesPerSecond * Time.deltaTime);
}
}
Разбор построчно:
| Строка | Что происходит |
|---|---|
degreesPerSecond = 90f | Полный оборот (360°) займёт 4 секунды при 90°/с |
void Update() | Unity вызывает метод ~60 раз в секунду (зависит от FPS) |
transform | Ссылка на Transform этого Cube — позиция, поворот, масштаб |
Vector3.up | Единичный вектор оси Y (0, 1, 0) — «вертикаль» |
Rotate(ось, угол) | Поворачивает объект на угол градусов вокруг оси |
* Time.deltaTime | Делает скорость независимой от FPS — на 30 FPS и 144 FPS оборот одинаковый |
Разбор по смыслу:
- Без
Time.deltaTimeна слабом ПК куб крутится медленнее, на мощном — быстрее. transform.Rotateкрутит локально (относительно текущего поворота объекта).- Поле
degreesPerSecondможно менять в Inspector без перекомпиляции — удобно на демонстрации урока.
Что попробовать:
Vector3.right— вращение вокруг оси X (куб «крутится на бок»).degreesPerSecond = 180f— в два раза быстрее.- Добавьте
transform.Rotate(Vector3.up, 45f * Time.deltaTime);иVector3.forward— двойное вращение.
Движение по WASD
Типичный запрос: unity player movement script c#, wasd movement unity 3d.
Задача: капсула ездит по плоскости стрелками или WASD. Физики нет — объект может проходить сквозь стены (для прототипа это нормально).
Настройка сцены:
- Plane — пол (уже есть в 3D-шаблоне).
- Capsule — переименуйте в
Player, поставьте чуть выше Plane. - Скрипт
MoveWASD.csна Player → Play, двигайте WASD.
using UnityEngine;
public class MoveWASD : MonoBehaviour
{
[SerializeField] private float moveSpeed = 6f;
void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 move = new Vector3(h, 0f, v);
if (move.sqrMagnitude > 1f)
move.Normalize();
transform.Translate(move * moveSpeed * Time.deltaTime, Space.World);
}
}
Разбор построчно:
| Строка | Что происходит |
|---|---|
GetAxis("Horizontal") | A/D или ←/→ → значение от −1 до 1 (плавно) |
GetAxis("Vertical") | W/S или ↑/↓ → то же по оси «вперёд-назад» |
new Vector3(h, 0f, v) | Направление на плоскости XZ; Y = 0 — не летим |
sqrMagnitude > 1f | При одновременном W+D длина вектора ≈ 1.41 — быстрее, чем по одной оси |
Normalize() | Длина вектора = 1 — диагональ не быстрее прямой |
Translate(..., Space.World) | Сдвиг в мировых осях; Space.Self — «вперёд» относительно поворота модели |
moveSpeed * Time.deltaTime | Скорость в метрах в секунду, а не «метрах за кадр» |
Разбор по смыслу:
GetAxisдаёт плавный ввод (можно подключить геймпад).GetKey(KeyCode.W)— только «включено/выключено», без промежуточных значений.- Этот скрипт обходит физику — для финальной игры с коллизиями добавьте
Rigidbody(см. прыжок).
Что попробовать: moveSpeed = 12f — в два раза быстрее; поверните Player на 45° и сравните Space.World и Space.Self.
Прыжок и ходьба с Rigidbody
Типичный запрос: unity jump script rigidbody, how to jump in unity c#.
Задача: персонаж ходит по полу с физикой, прыгает по Space один раз, пока стоит на земле.
Настройка сцены:
- Capsule →
Player. - Add Component → Rigidbody (Mass = 1, Use Gravity ✓).
- Rigidbody → Constraints → Freeze Rotation X и Z (капсула не заваливается).
- Plane → в Inspector сверху выберите Layer Ground (создайте в Tags and Layers, если нет).
- На Player — скрипт
PlayerJump.cs; в поле Ground Mask отметьте только слой Ground.
using UnityEngine;
public class PlayerJump : MonoBehaviour
{
[SerializeField] private float moveSpeed = 6f;
[SerializeField] private float jumpForce = 6f;
[SerializeField] private LayerMask groundMask;
[SerializeField] private float groundCheckDistance = 0.2f;
private Rigidbody rb;
void Awake()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && IsGrounded())
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
void FixedUpdate()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 input = new Vector3(h, 0f, v);
if (input.sqrMagnitude > 1f) input.Normalize();
Vector3 velocity = input * moveSpeed;
#if UNITY_6000_0_OR_NEWER
rb.linearVelocity = new Vector3(velocity.x, rb.linearVelocity.y, velocity.z);
#else
rb.velocity = new Vector3(velocity.x, rb.velocity.y, velocity.z);
#endif
}
bool IsGrounded()
{
return Physics.Raycast(
transform.position,
Vector3.down,
groundCheckDistance + 0.05f,
groundMask);
}
}
Разбор — почему два метода:
| Метод | Что делаем | Почему не в другом |
|---|---|---|
Update | GetKeyDown(Space) + прыжок | Ввод разовый — ловим нажатие один раз |
FixedUpdate | Задаём горизонтальную скорость | Физика Unity считается фиксированным шагом (~0.02 с) |
Awake | GetComponent<Rigidbody>() | Ссылку берём один раз, не каждый кадр |
Разбор физики:
| Строка | Смысл |
|---|---|
AddForce(..., ForceMode.Impulse) | Мгновенный «толчок» вверх — классический прыжок |
rb.linearVelocity / rb.velocity | Сохраняем Y (падение/прыжок), меняем только X и Z |
#if UNITY_6000_0_OR_NEWER | В Unity 6 свойство переименовали в linearVelocity |
Physics.Raycast вниз | Невидимый луч: если до пола ≤ distance — «на земле» |
groundMask | Луч игнорирует монетки, врагов, UI — только слой Ground |
Частая ошибка: прыжок бесконечный в воздухе — нет IsGrounded() или groundMask не включает слой пола.
Что попробовать: jumpForce = 10f — выше прыжок; в Scene View включите Gizmos и смотрите, упирается ли луч в Plane.
Монетка и счёт (OnTriggerEnter)
Типичный запрос: unity collect coin script, ontriggerenter not working unity.
Задача: игрок касается сферы — она исчезает, счёт +1, в Console печатается результат.
Настройка сцены:
- Sphere → имя
Coin; Add Component → скриптCoinPickup.cs. - На Sphere Collider включите Is Trigger ✓.
- Edit → Project Settings → Tags and Layers → тег Player и Coin.
- Player (Capsule + Rigidbody) → Tag Player.
- Пустой объект
GameSystems→ скриптScoreManager.cs(один на сцену).
CoinPickup.cs:
using UnityEngine;
public class CoinPickup : MonoBehaviour
{
[SerializeField] private int value = 1;
void OnTriggerEnter(Collider other)
{
if (!other.CompareTag("Player")) return;
ScoreManager.Instance?.AddScore(value);
Destroy(gameObject);
}
}
ScoreManager.cs:
using UnityEngine;
public class ScoreManager : MonoBehaviour
{
public static ScoreManager Instance { get; private set; }
public int Score { get; private set; }
void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
}
public void AddScore(int amount)
{
Score += amount;
Debug.Log($"Счёт: {Score}");
}
}
Разбор CoinPickup построчно:
| Строка | Смысл |
|---|---|
OnTriggerEnter(Collider other) | Unity вызывает, когда триггер и другой collider пересеклись |
other | Collider чужого объекта (капсула игрока) |
CompareTag("Player") | Быстрая проверка тега; не путать с tag == (лишние аллокации) |
return | Если задел не игрок — выходим, монетка не исчезает |
Instance?.AddScore | ?. — если менеджера нет, не упадём с NullReference |
Destroy(gameObject) | Удаляет этот GameObject (монетку) из сцены |
Разбор ScoreManager — учебный singleton:
| Строка | Смысл |
|---|---|
static Instance | Одна «глобальная» ссылка — любой скрипт может вызвать ScoreManager.Instance |
if (Instance != null && Instance != this) | Второй менеджер на сцене — уничтожаем дубликат |
Score { get; private set; } | Читать счёт можно откуда угодно, писать — только через AddScore |
Чек-лист, если триггер молчит:
| Проверка | |
|---|---|
| На монетке Is Trigger ✓ | |
| Хотя бы у одного из объектов есть Rigidbody | Обычно на Player |
| Тег Player назначен капсуле, не камере | |
ScoreManager есть на сцене |
Что попробуйте: поставьте 5 монеток — счёт должен дойти до 5; измените value = 10 — +10 за штуку.
Спавн префаба по клавише
Типичный запрос: unity instantiate prefab example, spawn bullet unity.
Задача: по нажатию E в точке FirePoint появляется клон префаба (снаряд, яблоко, враг).
Настройка:
- Sphere → настройте → перетащите в папку
Prefabs/(синий куб в Project = префаб). - На Player создайте пустой дочерний объект FirePoint (чуть впереди капсулы).
- Скрипт
SpawnerOnKey.csна Player; в Inspector: Prefab ← префаб, Spawn Point ← FirePoint.
using UnityEngine;
public class SpawnerOnKey : MonoBehaviour
{
[SerializeField] private GameObject prefab;
[SerializeField] private Transform spawnPoint;
[SerializeField] private KeyCode key = KeyCode.E;
void Update()
{
if (Input.GetKeyDown(key) && prefab != null && spawnPoint != null)
{
Instantiate(prefab, spawnPoint.position, spawnPoint.rotation);
}
}
}
Разбор построчно:
| Строка | Смысл |
|---|---|
GameObject prefab | Ссылка на ассет в Project, не на объект в Hierarchy |
Transform spawnPoint | Откуда брать позицию и поворот (дочерний объект на модели) |
KeyCode key = KeyCode.E | Клавиша по умолчанию — меняется в Inspector |
GetKeyDown | Один спавн за нажатие; GetKey — каждый кадр, пока держите |
prefab != null | Защита от NullReferenceException, если забыли перетащить префаб |
Instantiate(...) | Создаёт копию в сцене; оригинал-префаб в Project не исчезает |
spawnPoint.rotation | Клон «смотрит» туда же, куда FirePoint |
Что попробуйте: добавьте на префаб DestroyAfterDelay (ниже) — снаряды исчезают через 3 с и не засоряют сцену.
Камера следует за игроком
Типичный запрос: unity third person camera script, camera follow player c#.
Задача: Main Camera плавно едет за капсулой и смотрит на неё — вид от третьего лица.
Настройка: скрипт на Main Camera; поле Target ← перетащите Player.
using UnityEngine;
public class SimpleCameraFollow : MonoBehaviour
{
[SerializeField] private Transform target;
[SerializeField] private Vector3 offset = new Vector3(0f, 2f, -5f);
[SerializeField] private float smooth = 8f;
void LateUpdate()
{
if (target == null) return;
Vector3 desired = target.position + offset;
transform.position = Vector3.Lerp(
transform.position,
desired,
smooth * Time.deltaTime);
transform.LookAt(target);
}
}
Разбор построчно:
| Строка | Смысл |
|---|---|
LateUpdate | После всех Update — игрок уже сдвинулся, камера не «отстаёт на кадр» |
offset = (0, 2, -5) | Камера выше на 2 м и сзади на 5 м от центра игрока |
target.position + offset | Желаемая точка в мировых координатах |
Vector3.Lerp(a, b, t) | Плавное приближение от a к b; t = 0..1 за кадр |
smooth * Time.deltaTime | Чем больше smooth, тем быстрее камера догоняет |
LookAt(target) | Поворот камеры лицом к игроку |
Что попробуйте: offset = (3, 4, -6) — камера сбоку-сверху; smooth = 2f — более «ленивое» следование.
UI — текст счёта и кнопка
Типичный запрос: unity ui text update script, button onclick c#.
Задача: на экране надпись «Монеты: N» обновляется при сборе; кнопка Restart пишет в Console (или перезагружает сцену).
Настройка:
GameObject→UI→ Canvas (режим Screen Space Overlay).- ПКМ на Canvas →
UI→ Text (или TextMeshPro). - ПКМ на Canvas →
UI→ Button — подпись «Restart». - На Canvas —
GameUI.cs; перетащите Score Label и Restart Button.
using UnityEngine;
using UnityEngine.UI;
public class GameUI : MonoBehaviour
{
[SerializeField] private Text scoreLabel;
[SerializeField] private Button restartButton;
void OnEnable()
{
if (restartButton != null)
restartButton.onClick.AddListener(OnRestartClicked);
}
void OnDisable()
{
if (restartButton != null)
restartButton.onClick.RemoveListener(OnRestartClicked);
}
void Update()
{
if (scoreLabel != null && ScoreManager.Instance != null)
scoreLabel.text = $"Монеты: {ScoreManager.Instance.Score}";
}
void OnRestartClicked()
{
Debug.Log("Restart — подключите LevelRestart.ReloadCurrentScene");
}
}
Разбор построчно:
| Строка | Смысл |
|---|---|
using UnityEngine.UI | Пространство имён для Text, Button, Slider |
OnEnable / OnDisable | Подписка при включении объекта; отписка при выключении |
onClick.AddListener | При клике вызовется OnRestartClicked без public-метода в Inspector |
RemoveListener | Иначе при перезагрузке сцены останутся «висячие» обработчики |
$"Монеты: {Score}" | Интерполяция строк C# — подставляет число в текст |
Update для текста | Для учебного UI достаточно; в больших проектах — событие OnScoreChanged |
Связка с монетками: работает вместе с ScoreManager — соберите монетку, цифра на экране вырастет.
Примеры посложнее
Смена цвета по клавише C
Запрос: unity change object color script.
using UnityEngine;
public class ColorChanger : MonoBehaviour
{
[SerializeField] private Color[] palette =
{
Color.red, Color.green, Color.blue, Color.yellow
};
private Renderer rend;
private int index;
void Awake()
{
rend = GetComponent<Renderer>();
}
void Update()
{
if (!Input.GetKeyDown(KeyCode.C)) return;
index = (index + 1) % palette.Length;
rend.material.color = palette[index];
}
}
Разбор:
| Строка | Смысл |
|---|---|
GetComponent<Renderer>() | Компонент, который рисует меш (Mesh Renderer) |
Кеш в Awake | GetComponent в Update каждый кадр — лишняя работа |
(index + 1) % palette.Length | Циклический перебор: после жёлтого снова красный |
material.color | Меняет экземпляр материала на этом объекте |
Исчезновение через время
using UnityEngine;
public class DestroyAfterDelay : MonoBehaviour
{
[SerializeField] private float lifetimeSeconds = 3f;
void Start()
{
Destroy(gameObject, lifetimeSeconds);
}
}
| Строка | Смысл |
|---|---|
Destroy(gameObject, delay) | Unity сам удалит объект через N секунд — без Update и таймеров |
Start | Таймер запускается один раз при появлении объекта |
Прикрепите к снаряду из спавнера — след от выстрелов не копится бесконечно.
Патруль и преследование игрока
Патруль — враг ездит между двумя точками:
using UnityEngine;
public class PatrolBetweenPoints : MonoBehaviour
{
[SerializeField] private Transform pointA;
[SerializeField] private Transform pointB;
[SerializeField] private float speed = 3f;
private Transform currentTarget;
void Start() => currentTarget = pointB;
void Update()
{
if (pointA == null || pointB == null) return;
transform.position = Vector3.MoveTowards(
transform.position,
currentTarget.position,
speed * Time.deltaTime);
if (Vector3.Distance(transform.position, currentTarget.position) < 0.05f)
currentTarget = currentTarget == pointA ? pointB : pointA;
}
}
Преследование — враг бежит к игроку, но останавливается в stopDistance:
using UnityEngine;
public class ChasePlayer : MonoBehaviour
{
[SerializeField] private Transform player;
[SerializeField] private float speed = 4f;
[SerializeField] private float stopDistance = 1.5f;
void Update()
{
if (player == null) return;
Vector3 toPlayer = player.position - transform.position;
toPlayer.y = 0f;
if (toPlayer.magnitude <= stopDistance) return;
transform.position += toPlayer.normalized * speed * Time.deltaTime;
transform.rotation = Quaternion.LookRotation(toPlayer);
}
}
Разбор патруля:
MoveTowards— не «перепрыгивает» цель, если FPS просел (в отличие отposition = target).0.05f— порог «дошли»; иначе объект дёргается на месте.- Тернарный оператор
A ? B : C— переключение цели A ↔ B.
Разбор преследования:
toPlayer.y = 0— враг не «летит» к голове игрока, только по полу.normalized— единичный вектор направления; длина шага задаётсяspeed * deltaTime.LookRotation— модель поворачивается лицом к игроку.
Перезагрузка сцены
Запрос: unity restart level script.
Сцена должна быть в File → Build Settings → Scenes In Build.
using UnityEngine;
using UnityEngine.SceneManagement;
public class LevelRestart : MonoBehaviour
{
public void ReloadCurrentScene()
{
Scene scene = SceneManager.GetActiveScene();
SceneManager.LoadScene(scene.buildIndex);
}
}
| Строка | Смысл |
|---|---|
SceneManagement | Пространство имён для загрузки сцен |
GetActiveScene() | Текущая открытая сцена |
buildIndex | Номер сцены в списке Build Settings |
public void | Метод можно привязать к Button → On Click () в Inspector |
В GameUI.OnRestartClicked добавьте вызов FindObjectOfType<LevelRestart>()?.ReloadCurrentScene() или ссылку на компонент через [SerializeField].
Частые ошибки новичка
| Симптом | Причина | Решение |
|---|---|---|
NullReferenceException | Пустое поле в Inspector | Перетащите объект / префаб в [SerializeField] |
| Скрипт серый, не добавляется | Ошибка компиляции | Откройте Console, исправьте красные строки |
| «Script class cannot be found» | Имя файла ≠ имя класса | PlayerMove.cs → class PlayerMove |
| Ничего не происходит | Не нажали Play | Код работает только в Play Mode |
OnTriggerEnter не вызывается | Нет Rigidbody или не Trigger | Is Trigger на монетке; Rigidbody на Player |
| Персонаж проваливается | Нет Collider | Collider на поле и на персонаже |
| Прыжок бесконечный | Нет проверки земли | Raycast + правильный LayerMask |
| Движение «рывками» / зависит от FPS | Нет Time.deltaTime | Умножайте скорость на deltaTime в Update |
| Движение сквозь стены | Только transform.Translate | Добавьте Rigidbody + Collider или Character Controller |
Tag ... is not defined | Тег не создан | Tags and Layers → добавьте Player, Coin |
Красная строка содержит файл:строка — двойной клик открывает IDE. Debug.Log — белый текст для отладки; LogWarning — жёлтый; LogError — красный. На зачёте преподаватель часто просит показать Console при Play.
Мини-проект из этой статьи — соберите за один вечер
Свяжите примеры в одну сцену:
- Player — MoveWASD или PlayerJump.
- 5× Coin — CoinPickup +
ScoreManagerнаGameSystems. - Main Camera — SimpleCameraFollow.
- Canvas — GameUI показывает счёт.
- Cube-враг — ChasePlayer с ссылкой на Player.
Так вы получите бегать → собирать → видеть счёт → убегать от врага — достаточно для доклада или слайдов курсовой.
Куда дальше
- Разработка на Unity — white-box, стрельба, NavMesh, UI подробнее.
- Unity + C# — учебный маршрут — порядок глав.
- Справочник по Unity — lifecycle, слои, API.
- 200 вопросов по Unity — самопроверка.
- Pygame — мини-игры — тот же игровой цикл на Python.
- Roblox / Luau — скрипты — те же механики в Roblox Studio.
См. также
Другие статьи этого же раздела в боковом меню (как на странице "О разделе"). Практическая карта типовых IT-задач: термины, пошаговое внедрение, проверка качества и типичные ошибки. Простой консольный чат на C# — учебное приложение с сокетами: TCP между клиентом и сервером, многопоточность и обмен сообщениями в консоли. Примеры вёрстки на HTML и CSS с разбором: центрирование, Flexbox, Grid, формы, шапка, подвал и адаптив для учебы и портфолио. Перед началом работы обязательно изучите главу Turtle . Галерея 3D-фигур на Panda3D — карточки, куб, пирамида, сфера, сетки и составные сцены; код для локального запуска. Готовые docker-compose.yml с разбором каждой строки — nginx, PostgreSQL, Redis, WordPress, MongoDB. Примеры для школьников и студентов: postgres example, поднять базу локально, app + db. Примеры nginx.conf для статики, reverse proxy, React/Vue SPA, PHP, SSL и балансировки — построчный разбор директив, проверка curl и типичные ошибки для лабораторных и VPS. dockerfile example — 10 готовых Dockerfile с построчным разбором: node, python, golang, react nginx, spring boot, php, dotnet. Для студентов, лабораторных и docker build с нуля. PromQL example — готовые запросы Prometheus и Grafana с построчным разбором: up, rate, node_exporter cpu, memory, disk, http_requests_total, histogram_quantile p99, алерты. Для студентов, лабораторных и devops docker compose. Готовые манифесты Kubernetes с разбором каждой строки — Pod, Deployment, Service, ConfigMap, Secret, Ingress. Примеры для Minikube, kind и kubectl apply. Примеры графиков Matplotlib на Python для школьников и студентов — sin, cos, парабола, столбцы, scatter, гистограмма, подграфики; код с подробным разбором. Примеры pandas на Python для школьников и студентов — DataFrame, фильтрация, groupby, очистка, merge, сводные таблицы и экспорт; код с подробным разбором каждой строки.Готовые решения
Простой консольный чат на CSharp
HTML + CSS — готовые макеты
Примеры фигур Turtle на Python
Примеры фигур Panda3D на Python
Docker Compose — готовые стеки
Nginx — конфиги под задачу
Dockerfile — 10 типовых образов
Prometheus + Grafana — запросы
Kubernetes YAML — минимальные манифесты
Matplotlib — графики
Pandas — типовые операции