Введение
Прежде всего, хочу сразу отметить, что я не являюсь профессиональным разработчиком. В этой статье я постараюсь изложить свой опыт создания игры «Desteroid». Данный материал, скорее всего не будет интересен тем, кто уже имеет большой опыт в разработке игр, но начинающим разработчикам, которые хоть немного работали с Unity думаю, будет интересно.
Дизайн
Концепция игры заключается в том, что звездолет должен уничтожить как можно больше метеоритов при этом не сталкиваясь с ними.
Разработка
Игра состоит из 2-х сцен: главное меню и сама игровая сцена
Где «menu» это главное меню а «1» это игровая сцена
Главное меню
Для создания столь незамысловатого меню нам потребуется элемент управления GUI, который является стандартным в Unity.
В качестве фона я использовал спрайт с именем «space», на нем нарисован космос.
Далее создаем скрипт «menu.cs»(Щелкаем правой кнопкой->выбираем Create-> C# Script) и вешаем его на background. background это спрайт со 100% прозрачностью на котором создаются основные элементы управления (START/EXIT) а space служит просто для декорации.
Содержимое скрипта:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using UnityEngine.SceneManagement;
public class menu : MonoBehaviour {
public GUIStyle mystyle;//объявляется для того чтобы изменять начертание GUI компонентов(шрифт, размер и.т.п.)
string score;
void Start ()
{
StreamReader scoredata = new StreamReader (Application.persistentDataPath + "/score1.gd");//создание файловой переменной
score = scoredata.ReadLine ();//чтение строки
scoredata.Close ();//закрытие файловой переменной
}
// Update is called once per frame
void Update () {
}
void OnGUI(){
GUI.Box (new Rect (Screen.width*0.15f, Screen.height*0.8f, Screen.width*0.7f, Screen.height*0.1f), "MAX DESTROYED:"+score,mystyle);
if (GUI.Button (new Rect (Screen.width*0.15f, Screen.height*0.25f, Screen.width*0.7f, Screen.height*0.1f), "START",mystyle))
{
SceneManager.LoadScene (1);//Загрузка игровой сцены
}
if (GUI.Button (new Rect (Screen.width*0.15f, Screen.height*0.4f, Screen.width*0.7f, Screen.height*0.1f), "EXIT",mystyle))
{
Application.Quit();//Выход из игры
}
}
}
Еще не забываем повесить на «space» скрипт activemenu. Он служит для того чтобы создать анимацию движения фона меню. Потом создаем копию «space» и ставим ее чуть выше
Содержимое скрипта:
using UnityEngine;
using System.Collections;
public class activemenu : MonoBehaviour {
float speed=-0.1f;
void Start () {
}
// Update is called once per frame
void Update () {
transform.Translate (new Vector3 (0f,speed,0f));
if (transform.position.y < -12f)
{
transform.position=new Vector3(0f,13f,0f);
}
}
}
Должно получиться примерно вот так:
Создание игровой сцены
Основными элементами на этой сцене являются: звездолет, дорога(космос) и выстрел.
1.Дорога(Космос)
Ввиду того что игра является бесконечной и останавливается только когда звездолет попадет в метеорит, дорога(космос) является двигающейся. То есть автомобиль может перемещаться влево или вправо, а иллюзию движения по прямой создает дорога(космос).
Кидаем спрайт «space» на игровую сцену и подгоняем по размерам камеры. Затем создаем дубликат и ставим его выше.
Затем добавляем как дочерние объекты внутрь дороги 1 блок с метеоритом и не забываем добавить к ним Polygon Collider 2D.
Теперь создаем скрипт moveroad.cs и вешаем его на нашу дорогу(космос)
Добавляем в него следующий код:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public class moveroad : MonoBehaviour {
int f;
float speed=-0.15f;
public GameObject block;
void Start ()
{
}
void Update ()
{
transform.Translate (new Vector3 (0f,speed,0f));
if (transform.position.y < -19f)
{
transform.position=new Vector3(0f,33.4f,0f);
block.transform.position=new Vector3(10.15f,block.transform.position.y,block.transform.position.z);
f = Random.Range (0, 4);
switch (f)
{
case 0:block.transform.position=new Vector3(2.40f,block.transform.position.y,block.transform.position.z); break;
case 1:block.transform.position=new Vector3(0.90f,block.transform.position.y,block.transform.position.z); break;
case 2:block.transform.position=new Vector3(-0.80f,block.transform.position.y,block.transform.position.z); break;
case 3:block.transform.position=new Vector3(-2.35f,block.transform.position.y,block.transform.position.z); break;
}
}
}
}
2.Звездолет
Кидаем спрайт звездолета на сцену и устанавливаем его в любое место на дороге(космосе). Затем создаем скрипт carcontroller.cs и вешаем его на звездолет.
Содержимое скрипта:
using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
using UnityEngine.SceneManagement;
public class carconroller : MonoBehaviour
{
public GameObject laser,bang;
float speedlaser=0.5f, speedplayer=0.08f;
float x,y,z;
bool fire=false;
void Start ()
{
y = laser.transform.position.y;
z = laser.transform.position.z;
}
public void Update ()
{
if (transform.rotation.z !=0)
{
Handheld.Vibrate ();
bang.transform.position = new Vector3 (transform.position.x,transform.position.y,0);
transform.position = new Vector3 (transform.position.x,transform.position.y,-150f);
SceneManager.LoadScene (0);
}
if (fire==true)
{
laser.transform.Translate (new Vector3 (0, speedlaser, 0f));
if (laser.transform.position.y > 7)
{
fire = false;
laser.transform.position = new Vector3(laser.transform.position.x,y,z);
}
}
}
public void OnGUI()
{
if (GUI.RepeatButton (new Rect (Screen.width*0.1f, Screen.height*0.9f, Screen.width*0.2f, Screen.height*0.08f), "L"))
{
if (transform.position.x > -2.4f)
{
transform.Translate (new Vector3 (-speedplayer, 0f, 0f));
}
}
if (GUI.RepeatButton (new Rect (Screen.width*0.7f, Screen.height*0.9f, Screen.width*0.2f, Screen.height*0.08f), "R"))
{
if (transform.position.x < 2.4f)
{
transform.Translate (new Vector3 (speedplayer, 0f, 0f));
}
}
if (GUI.RepeatButton (new Rect (Screen.width*0.3f, Screen.height*0.9f, Screen.width*0.4f, Screen.height*0.08f), "FIRE"))
{
laser.transform.position = new Vector3(laser.transform.position.x,laser.transform.position.y,-1f);
fire = true;
}
}
}
Теперь звездолет может перемещаться.
3.Лазер
Лазер является дочерним объектом звездолета. Поэтому просто прячем его под ним и вешаем скрипт triger.cs.
Содержимое скрипта:
using UnityEngine;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public class triger : MonoBehaviour {
public GUIStyle mystyle;
public GameObject bang;
public GameObject block;
public GameObject sblock;
int score=0;
float data,timer=0.5f;
void Start ()
{
StreamReader scoredata = new StreamReader (Application.persistentDataPath + "/score1.gd");
data = float.Parse(scoredata.ReadLine ());
scoredata.Close ();
}
void Update ()
{
if(bang.transform.position.z==0)
{
timer = timer - Time.deltaTime;
if (timer < 0)
{
bang.transform.position = new Vector3 (bang.transform.position.x,bang.transform.position.y,7.5f);
timer = 0.5f;
}
}
}
void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.name == "blackcircle" || col.gameObject.name == "sblackcircle")
{
score++;
Handheld.Vibrate ();
switch(col.gameObject.name)
{
case "blackcircle":
bang.transform.position = new Vector3 (block.transform.position.x,block.transform.position.y,0);
block.transform.position = new Vector3 (10.15f, block.transform.position.y, block.transform.position.z);
break;
case "sblackcircle":
bang.transform.position = new Vector3 (sblock.transform.position.x,sblock.transform.position.y,0);
sblock.transform.position = new Vector3 (10.15f, sblock.transform.position.y, sblock.transform.position.z);
break;
}
}
if (score>data)
{
StreamWriter scoredata=new StreamWriter(Application.persistentDataPath + "/score1.gd");
scoredata.WriteLine(score);
scoredata.Close();
}
}
}
Также чуть не забыл добавить за камерой надо спрятать эффект взрыва(bang). Он появляется когда лазер сталкивается с метеоритом или метеорит с звездолетом.
Итог
Ссылка на Google Play.
Поделиться с друзьями
GoldKeeper
А вас не смущает что такой простой проект + аналогов вагон и тележка + примеров таких поделий видео уроками на оф сайте даже полно?
Или тут основная цель это ссылка на Google Play? Но и в этом случае неясно кто будет в это играть.
По поводу самой статьи: есть более интересные примеры скроллигна — ненужно делать дублирование для спрайта, достаточно смещение текстуры указать(на оф сайте примеры есть), а если наложить сверху ещё одну с прозрачностью так ещё и параллакс получится.