Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Вопросы и ответы к экзамену.docx
Скачиваний:
29
Добавлен:
21.06.2022
Размер:
16.83 Mб
Скачать

33. Игра в стиле jetpack joyride в Unity 2d. Добавление монет. Использование тегов для различия в игре монет и лазеров. Обновленный скрипт контроллера персонажа.

Добавление монет

Переместите спрайт монетки в сцену. Установите параметр Sorting Layer в значение Objects. Добавьте компонент CircleCollider2D. Активируйте чекбокс Is Trigger в добавленном компоненте. Установите радиус коллайдера в значение 0.23. Переместите созданный объект в папку Prefabs. Заебись, вы создали префаб монетки!

Если вы запустите сцену сейчас, то мышка будет умирать, если попытается подобрать монетку. Чтобы это исправить, необходимо немного изменить MouseController.

Использование тегов для различия в игре монет и лазеров

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

Выберите префаб монетки на панели Project. Это откроет свойства префаба на панели Инспектора. Откройте раскрывающийся список Tag под названием префаба и выберите Add Tag

Это откроет уже знакомое окно Tags & Layers на панели Инспектора. В секции Tags добавьте новый тэг с названием Coins. Теперь выберите префаб монетки, раскройте список тэгов и выберите тэг с названием Coins.

Конечно, это не решает всю проблему, поэтому придётся ещё немножко покопаться в коде.

Обновленный скрипт контроллера персонажа

Откройте MouseController и добавьте новую переменную подсчёта собранных монеток:

Далее создайте метод CollectCoin():

Этот метод увеличивает счётчик монеток и убирает монетку со сцены, чтобы мышка с ней снова не столкнулась в следующих кадрах.

Наконец, обновите метод OnTriggerEnter2D следующим блоком кода:

При столкновении движок попытается распознать тэг объекта, с которым столкнулась мышка, и если это объект с тэгом Coins, то он активирует метод CollectCoin(), а если нет, то активирует метод HitByLaser().

В этой игре на данный момент существует только два типа объектов (лазеры и монетки), поэтому здесь уместно использование else-кейса для лазера. Но в реальных играх вы должны назначать тэги всем типам объектов и распознавать их явно (как это сделано в условии if-а).

34. Игра в стиле JE.TPACK JOYRIDE в Unity 2D. Создание префаба группы монет, обновленный скрипт для генерации, метод для добавления нового объекта, скрипт для генерирования и удаления объектов в случае необходимости.

Создание префаба монет:

  1. Откройте папку «Sprites» в окне «Project».

  2. Перетащите спрайт на сцену и выберите его в меню Hierarchy.

  3. В Инспекторе установите его Сортировочный слой на Объекты.

  4. Добавьте компонент CircleCollider2D.

  5. Включите свойство Is Trigger для коллайдера.

  6. Установите значение Radius = 0,23.

После создания GameObject для монет перетащите его из меню Hierarchy в папку Prefabs, чтобы создать префаб для монет.

Создаём грауппы монет:

Откройте папку Prefabs в окне Project и перетащите 9 монет на сцену, используя префабы монет.

Выберите любую монету и установите координаты для Position в (0, 0, 0). Это будет центральная монета. Нужно добавить все монеты в Empty GameObject, поэтому потребуется построить свою фигуру вокруг начала координат.

Поместив центральную монету, нарисуйте треугольную фигуру вокруг монеты. Не забывайте, что вы можете использовать инструмент Vertex Snappin, удерживая клавишу V.

Теперь создайте Empty GameObject, выбрав GameObject ⇒ Create Empty

 и переименуйте его в coins_v.

Установите координаты для Position на (0, 0, 0), выберите все монеты в Hierarchy и добавьте их в coins_v. Вот, что получится:

Выберите coins_v в меню Hierarchy и перетащите его в папку «Prefabs» в окне «Project», чтобы создать новый префаб для генерации монет.

Добавление новых параметров в GeneratorScript

Откройте GeneratorScript и добавьте следующие переменные:

public GameObject[] availableObjects;

public List<GameObject> objects;

public float objectsMinDistance = 5.0f;

public float objectsMaxDistance = 10.0f;

public float objectsMinY = -1.4f;

public float objectsMaxY = 1.4f;

public float objectsMinRotation = -45.0f;

public float objectsMaxRotation = 45.0f;

Раздел availableObjects будет содержать все объекты, которые может сгенерировать скрипт (то есть разные фигуры из монет и лазерные поля).

Скрипт для генерации

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class GeneratorScript : MonoBehaviour

{

public GameObject[] availableRooms;

public List<GameObject> currentRooms;

private float screenWidthInPoints;

public GameObject[] availableObjects;

public List<GameObject> objects;

public float objectsMinDistance = 5.0f;

public float objectsMaxDistance = 10.0f;

public float objectsMinY = -0.3f;

public float objectsMaxY = 0.5f;

public float objectsMinRotation = -45.0f;

public float objectsMaxRotation = 45.0f;

void Start()

{

float height = 2.0f * Camera.main.orthographicSize;

screenWidthInPoints = height * Camera.main.aspect;

}

void AddRoom(float farhtestRoomEndX)

{

int randomRoomIndex = Random.Range(0, availableRooms.Length);

GameObject room = (GameObject)Instantiate(availableRooms[randomRoomIndex]);

float roomWidth = room.transform.Find("Floor").localScale.x;

float roomCenter = farhtestRoomEndX + roomWidth * 0.5f - 0.1f;

room.transform.position = new Vector3(roomCenter, 0, 0);

currentRooms.Add(room);

}

void AddObject(float lastObjectX)

{

int randomIndex = Random.Range(0, availableObjects.Length);

GameObject obj = (GameObject)Instantiate(availableObjects[randomIndex]);

float objectPositionX = lastObjectX + Random.Range(objectsMinDistance, objectsMaxDistance);

float randomY = Random.Range(objectsMinY, objectsMaxY);

obj.transform.position = new Vector3(objectPositionX, randomY, 0);

float rotation = Random.Range(objectsMinRotation, objectsMaxRotation);

obj.transform.rotation = Quaternion.Euler(Vector3.forward * rotation);

objects.Add(obj);

}

void GenerateObjectsIfRequired()

{

float playerX = transform.position.x;

float removeObjectsX = playerX - screenWidthInPoints;

float addObjectX = playerX + screenWidthInPoints;

float farthestObjectX = 0;

List<GameObject> objectsToRemove = new List<GameObject>();

foreach (var obj in objects)

{

float objX = obj.transform.position.x;

farthestObjectX = Mathf.Max(farthestObjectX, objX);

if (objX < removeObjectsX)

objectsToRemove.Add(obj);

}

foreach (var obj in objectsToRemove)

{

objects.Remove(obj);

DestroyImmediate(obj, true);

}

if (farthestObjectX < addObjectX)

AddObject(farthestObjectX);

}

void GenerateRoomIfRequired()

{

List<GameObject> roomsToRemove = new List<GameObject>();

bool addRooms = true;

float playerX = transform.position.x;

float removeRoomX = playerX - screenWidthInPoints;

float addRoomX = playerX + screenWidthInPoints;

float farthestRoomEndX = 0;

foreach (var room in currentRooms)

{

float roomWidth = room.transform.Find("Floor").localScale.x;

float roomStartX = room.transform.position.x - (roomWidth * 0.5f);

float roomEndX = roomStartX + roomWidth;

if (roomStartX > addRoomX) addRooms = false;

if (roomEndX < removeRoomX) roomsToRemove.Add(room);

farthestRoomEndX = Mathf.Max(farthestRoomEndX, roomEndX);

}

foreach (var room in roomsToRemove)

{

currentRooms.Remove(room);

DestroyImmediate(room, true);

}

if (addRooms) AddRoom(farthestRoomEndX);

}

void FixedUpdate()

{

GenerateRoomIfRequired();

GenerateObjectsIfRequired();

}

}