Если вы уже перешли по ссылке, указанной сверху и успели поиграть, то вы понимаете, что графики в такой игре - минимум. Нам нужен простой круг, желательно, в большом разрешении, чтоб выглядело нормально (512х512px вполне сойдет).
Вот что вышло у меня спустя 20 минут мучений
У кого не получается круг - даю ссылочку на скачивание своего
Клац* Пришло время создать проект. Запускаем Unity3D, нажимаем Create New Project, после чего появляется окошко, в котором мы можем выбрать, где наш проект будет лежать, какие стандартные ассеты в него загрузятся при создании и, на что нам надо обратить внимание - Пространство (3D/2D). Выбираем 2D, чтобы работать было удобнее и клацаем по кнопке Create.
Отлично! Новый проект создан. В ассетах пусто, на сцене - только камера (У кого нет - нужно создать). Импортируем наш Круг в проект, перетягивая его в окно Unity.
Теперь наш круг в проекте. Кликаем на него и в иерархии выбираем Texture Type - Sprite; Sprite Mode - Single. Жмем Apply
Теперь мы можем перенести этот спрайт на сцену, выбрать позицию так, чтоб он попадал в поле зрения камеры. Жмем Play
Круг отображается, но нам надо уменьшить его до размеров, с которыми он будет создаваться на сцене, чтоб его было едва видно.
Для этого кликаем по спрайту на сцене, в иерархии ищем Transform, в Scale X и Scale Y ставим 0. (На скрине - 0.001, но лучше поставить 0 - так плавнее будет).
Запускаем - спрайта не видно. Не пугайтесь, так и надо. Все нормально
Теперь можем изменить синий цвет фона на любой другой цвет (Синий фон в юни мне никогда не нравился). Для этого выбираем Main Camera на сцене, в иерархии ищем Компонент Camera, кликаем по Backgroung и выбираем любой понравившийся цвет.
Мне серенький пригляделся
Пришло время писать код. Создаем 2 C# скрипта - "GameController" и "CircleScript" (Щелк правой кнопкой мыши по свободной области в иерархии
проекта, Create, C# Script).
Двойным щелчком открываем скрипт GameController и начинаем кодить.
Добавим float переменную
Код
public float Score; //Переменная, содержащая в себе число с плавающей запятой (float). Будем использовать ее для отображения кол-ва очков игрока.
Далее в метод OnGUI пишем строку для отображения текущих очков игрока
Код
GUI.Label(new Rect(15, 15, 100, 30), "Score: " + Score.ToString());
Теперь наш скрипт выглядит так:
Код
using UnityEngine;
using System.Collections;
public class GameContoller : MonoBehaviour {
public float Score;
void Start () {
}
void Update () {
}
void OnGUI(){
GUI.Label(new Rect(15, 15, 100, 30), "Score: " + Score.ToString());
}
}
Сохраняем и весим этот скрипт на любой не удаляющийся во время игры объект (в нашем случае - на камеру), жмем Play.
Как мы видим - слева вверху появилось что-то вроде "Score: 0". Отображается нормально, едем дальше.
Переносим наш спрайт в иерархию проекта, тем самым создав префаб со спрайтом
Спрайт со сцены нужно удалить
Дополняем наш скрипт:
Новая переменная, в которой будет лежать наш круг. Будет использоваться для создания новых копий этого круга во время игры
Код
public Transform CirclePrefab;
Переменная для таймера
Код
void Update () {
Timer += Time.deltaTime;
if (Timer >= 0.75f){
Instantiate(CirclePrefab, new Vector2(Random.Range(-9, 8.5f), Random.Range (-1.5f, 2)), Quaternion.identity);
Timer = 0;
}
}
Каждые 0.75 секунд создаем новый круг в рандомной позиции по Иксу: от -9 до -1.5, По Игреку: от 8.5 до 2. Поиграйте со значениями.
Сохраняем, переносим наш префаб круга в поле CirclePrefab в иехахрии камеры.
Запускаем
Можно заметить, что на сцене создается много копий нашего Круга каждые 0.75 секунд.
Теперь заходим и редактируем скрипт CircleScript:
Код
using UnityEngine;
using System.Collections;
public class CircleScript : MonoBehaviour {
void Update () {
transform.localScale += new Vector3(Time.deltaTime * 0.1f, Time.deltaTime * 0.1f, 0);
}
}
Размер (Scale) круга увеличивается по X и Y. 0.1f - скорость увеличения. Поиграйтесь со значением.
Можно запустить и проверить. PS: скрипт надо повесить на префаб круга.
При клике на круг надо удалять его и прибавлять к очкам число, формулой которого будет: Какой-либо коэффицент / текущее значение Scale (Для того, чтобы за круги разных размеров давали различное кол-во очков).
Дописываем CircleScript
Код
public GameObject CircleDestroyText;//3D Текст, который будет спаунится при удалении нашего круга.
void OnMouseDown(){
//Ищем камеру и берем у нее компонент GameController
var GameController = Camera.main.GetComponent<GameContoller>();//Т.к. камера на сцене у нас всего одна и она главная, мы можем воспользоваться этим
var ScoreAdd = 50 / transform.localScale.x;//Формула
GameController.Score += ScoreAdd;//Прибавляем итоговое значение формулы к нашим общим очкам
Destroy (this.gameObject);//Удаляем круг
}
void OnDestroy(){//OnDestroy вызывается при удалении объекта
var GC = Camera.main.GetComponent<GameContoller>();//опять ищем камеру и ее компонент GameController
var asd = Instantiate(CircleDestroyText, gameObject.transform.position, gameObject.transform.rotation ) as GameObject;// Создаем текст в месте этого круга
asd.GetComponent<TextMesh>().text = 50 / transform.localScale.x + "";//В поле текста вписываем сколько мы получили при удалении круга
}
}
Ах, да! Нам надо создать 3D Text (GameObject - Create - 3D Text). Оставляем его поле text в компоненте TextMesh пустым и переносим в иерархию проекта. Префаб текста создан! Со сцены можно удалить.
Теперь этот префаб нужно закинуть в поле CircleDestroyText у скрипта CircleSript на префабе круга.
Запускаем, тестим
Вроде все работает, однако мешаются неудаляемые заспауненные тексты с очками. Нужно удалять их со временем.
Для этого создадим новый скрипт DestroyTime и впишем туда следующее:
Код
using UnityEngine;
using System.Collections;
public class DestroyTime : MonoBehaviour {
public float TimeToDestroy;
// Use this for initialization
void Start () {
Invoke ("Destroy", TimeToDestroy);
}
// Update is called once per frame
void Update () {
}
void Destroy(){
Destroy(this.gameObject);
}
}
Числовое значение TimeToDestroy означает кол-во секунд до удаления этого текста со сцены после спауна. Я поставил 1.
Запускаем, тестим - все ок
Осталось лишь добавить остановку игры при каких-либо условиях, например, если размер хоть одного из кругов превысил какое-то количество. Так-же нужно добавить вывод значения набранных очков при при проигрыше и возможность перезапустить игру.
Комментировать там уже нечего - вот конечный вариант скриптов:
GameController Код
using UnityEngine;
using System.Collections;
public class GameContoller : MonoBehaviour {
public float Score; //Переменная, содержащая в себе числа с плавающей запятой (float). Будем использовать ее для отображения кол-ва очков игрока.
public bool GameOver;
public Transform CirclePrefab;
float Timer;
void Start () {
}
void Update () {
if (!GameOver)
Timer += Time.deltaTime;
if (Timer >= 0.75f){
Instantiate(CirclePrefab, new Vector2(Random.Range(-9, 8.5f), Random.Range (-1.5f, 2)), Quaternion.identity);
Timer = 0;
}
}
void OnGUI(){
if (!GameOver)
GUI.Label(new Rect(15, 15, 100, 30), "Score: " + Score.ToString());
if (GameOver){
GUI.Label(new Rect(Screen.width / 2- 100, Screen.height / 2- 50, 200, 100), "GameOver! Score: " + Score);
GUI.Label(new Rect(Screen.width / 2- 100, Screen.height / 2 - 25, 200, 100), "Press [R] to restart...");
if(Input.GetKeyDown(KeyCode.R))
Application.LoadLevel(0);
}
}
}
CircleScript Код
using UnityEngine;
using System.Collections;
public class CircleScript : MonoBehaviour {
public GameObject CircleDestroyText;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
var GC = Camera.main.GetComponent<GameContoller>();
if (!GC.GameOver)
transform.localScale += new Vector3(Time.deltaTime * 0.1f, Time.deltaTime * 0.1f, 0);
if(GC.GameOver)
Destroy(gameObject);
if(transform.localScale.x >= 0.40f)
GC.GameOver = true;
}
void OnMouseDown(){
var GameController = Camera.main.GetComponent<GameContoller>();
var ScoreAdd = 50 / transform.localScale.x;
GameController.Score += ScoreAdd;
Destroy (this.gameObject);
}
void OnDestroy(){
var GC = Camera.main.GetComponent<GameContoller>();
if(!GC.GameOver){
var asd = Instantiate(CircleDestroyText, gameObject.transform.position, gameObject.transform.rotation ) as GameObject;
asd.GetComponent<TextMesh>().text = 50 / transform.localScale.x + "";
}
}
}
Ну вот и все!
Спасибо за внимание! Спрашивайте в комментариях, если вам что-то не понятно, обязательно отвечу.