История создания своей первой игры на Unity

Введение

Прежде всего, хочу сразу отметить, что я не являюсь профессиональным разработчиком. Я обычный бакалаврик технического ВУЗа, так что незнание мною некоторых терминов прошу простить, не дорос ещё. Просто однажды летним вечером делать было нечего, как говорится, и я решил попробовать свои силы в создании игОр на всем известном движке Unity.

Начал я свою «разработку» с непосредственной установки Unity и тамошних туториалов aka курсов от самой Unity. Почерпнув оттуда основы основ в виде понимания, что такое объекты и компоненты в Unity, как-куда и на что вешать скрипты и тому подобное, я приступил к созданию своей первой игры. Попытки создания, по крайней мере.

Концепт

За основу я взял классический понг из аркадных игровых автоматов 70-х годов: две движущиеся платформы и скачущий туда-сюда шарик. Механика простая, графики тоже много не требует — в самый раз для своей первой поделки на Unity.

Так как был знаком с Aseprite графику решил реализовывать именно на ней. Никаких особых сложностей у людей, незнакомых с данной программой, я думаю, тоже не возникнет. Она очень простая и интуитивно понятная.

Посидев десяток минут, накалякал вот такую концепт-анимацию того, что бы примерно хотел видеть в игре:

Концепт
Концепт

Процесс пошёл

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

Так как изначально я хотел сделать ещё и мобильную версию, то управление решил реализовать через прозрачные UI-Canvas кнопки. Движение вверх — верхний левый угол, вниз соответственно нижний левый. И для старта/запуска шарика — отключаемая после нажатия кнопка на весь экран. Также на кнопки управления я наложил Event Trigger для отработки долгих нажатий.

А для подсчета очков использовал шрифт, который сделал на bitfontmaker2. Он состоит из пиксельных цифр и символа двоеточия.

Доработка интерфейса и визуала

Дальше мне захотелось добавить кнопку паузы и кнопку сброса очков. Функцию паузы я реализовал через Time.timeScale, а функцию сброса через перезапись соответствующих переменных и возврата платформ и мячика на изначальные позиции.

public void Reset(float x)
{
	ball.GetComponent<Rigidbody2D>().Sleep();
	enemy.position = new Vector2(enemy.position.x, 0f);
	player.position = new Vector2(player.position.x, 0f);
	freezPlayer = player.position;
	freezEnemy = enemy.position;
	ball.position = new Vector2(0, 0);
	begin = false;

	if (x > 0)
	{
		playerScore++;
	}

	else if (x < 0)
	{
		enemyScore++;
	}
}

public void Reset_OnClick()
{
	Reset(0);
	playerScore = 0;
	enemyScore = 0;
}

public void Pause_OnClick()
{
	if (!isPaused)
	{
		Time.timeScale = 0f;
		isPaused = true;
		pause.GetComponent<Image>().sprite = spritePause[1];
	}
	else if (isPaused)
	{
		Time.timeScale = 1f;
		isPaused = false;
		pause.GetComponent<Image>().sprite = spritePause[0];
	}
}

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

Это я смог реализовать через соответствующий скрипт и префабы частиц разного цвета.

Музыка

После визуала я также решил добавить немного музыки в игру. Для этого я взял четыре разных loop’а с этого сайта и прописал их как массив типа AudioSource.

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

public void Music_Pause_OnClick()
{
  if (isMusicPause)
	{
		musicManager[trackNum].Play();
		isMusicPause = !isMusicPause;
		musicPause.GetComponent<Image>().sprite = spriteMusic[0];
	}
  else
  {
		musicManager[trackNum].Pause();
		isMusicPause = !isMusicPause;
		musicPause.GetComponent<Image>().sprite = spriteMusic[1];
	}
}

Названия треков я вывел через UI-Text, также как и кнопки, в Canvas. Шрифт для них одолжил с fonts-online.

Меню

Потом мне захотелось ввести несколько дополнительных режимов: уровни сложности и режим ПвП. Переключая уровни сложности, игрок меняет скорость мячика и скорость платформ. Включая же режим ПвП, пользователи отключают бота и подключают дополнительные «сенсоры» управления второй платформой.

Результат

В конце концов, после трёх недель моего малевания, что-то я всё-таки накалякал и решил куда-нибудь это «что-то» выложить. Первым делом подумал, естественно, о Google Play. На App Store даже не засматривался. Так как хоть я и не интересовался тематикой размещения мобильных игр в сторы, но краем уха слышал, что у Apple с разработчиками особая форма отношений.

Поэтому взгляд мой пал именно на маркет компании добра. Однако с удивлением я обнаружил, что у Гугла тоже с бухты-барахты выложить свою поделку не получиться. Для этого нужно заводить некий аккаунт разработчика и еще что-то регистрировать. Ну и платить, соответственно, тоже.

Так как платить за выкладывание своей своеобразной, скажем так, поделки, я не хотел, то пришлось думать как же осмыслить моё трёх недельное действо. Не удалять же? Можно было бы, конечно. Но «не хочеца».

В итоге я решил оживить свой, приказавший долго жить, аккаунт на GitHub и выложить свою игру там в качестве репозитория. Может быть, кому-нибудь он будет интересен в качестве первой ступеньки к освоению Unity. Быть может. Вряд ли, конечно, но всё-таки.

Ссылка на репозиторий: https://github.com/AlferovKirill/Classic-Pong

В содержимом:

Classic Pong Desktop — сборка для ПК. Внутри .ехе, если осмелитесь запускать, то запускайте в самой этой папке, так как там лежат спрайты/музыка/шрифты и тп.

Classic Pong GIF — папка .gif файлов с отображением работы режимов ПвП/ПвП и функционала.

Classic Pong — сам проект на Unity.

Classic Pong.apk — сборка для Android.


Оффтоп

Так как игру по большей части я писал для себя, то комментарии в коде себя должным оставлять не посчитал. К сожалению. Сейчас они конечно будут постепенно добавляться, но со скоростью столь медленной, что лучше и не надеяться на это.

Поэтому если вдруг у кого-нибудь возникло желание разобраться в том, что я там в этих скриптах натворил, то можете смело писать в личку Хабр’а. Ну или на почту: [email protected].

Источник 📢