CheckPoint в Unity3d

Всем доброго времени суток, сегодня я буду разбираться как делать CheckPoint в Unity3d с помощью C#. Тема для игр очень важная, и нужная. Играть без CheckPoints конечно можно, однако обычно это бывает достаточно сложно, так как их часто ставят для прохождения труднопроходимых мест. Ведь никому особо не охота, после того как погиб где-то в середине игры начинать играть сначала, я скажу даже один уровень проходить по нескольку раз из-за своей какой-либо глупости обычно обидно.

 

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

 

Для своего эксперимента я взял свой урок не с самодельным танчиком, а там где наш персонаж бегает по пустой платформе, пока с нее не падает, только несколько изменил саму игру, добавил в нее места сохранения, или точки возрождения, для того чтобы было видно добавил их как три круглых диска, разного цвета на нашу сцену. Сделал это достаточно просто, просто сделав префаб цилиндра, назвал его CheckPointPref и увеличил его в четыре раза по осям X и Z и уменьшил его по высоте Y до 0.02. Так же удалил из префаба Capsule Collider в окне Inspector, на даном этапе оно мне не надо, дальше перекидал их на сцену в места которые мне понравились и в том же окне Inspector > Mesh Renderer, в Unity3d добавил материалы к каждому префабу который добавил на сцену. Так чтобы они стали разных цветов, конечно можно просто поменять цвета материалов, ну да это сами разберетесь, мне просто надо различать что я воскрешаюсь в игре в месте в котором сохранился. Вид вышел приблизительно вот такой.

Точки чекпоинтов в Unity
Dante

Как можете видеть я уже пробежался по точкам сохранения проверяя их работу. При этом успел проверить возрождение на каждой из этих точек. Правда я забежал несколько вперед поэтому, постараюсь говорить по порядку. После того как на сцену добавлены точки где будет сохранятся наш персонаж, я изменил самого персонажа, то есть я особо ничего и не менял. Для начала сделал персонажа заново, а то совсем запутался что там сделано у него, а что нет, просто сделал новый префаб с именем playerPraf нашим персонажем, FirstPersonCharacter кто не в курсе что такое префаб читайте статьи раньше. Так же удалил камеру со сцены, на персонаже есть камера, две их не надо, и прикрепил несколько измененный скрипт спаунера на свою платформу, Platform. Скрипт спаунера я изменил подобным образом.

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

Как можете видеть отличия от спаунера который я использовал раньше есть, давайте я немного о них скажу. Прежде всего как можете видеть я подключил библиотеку для работы с файлами SystemIO, так же подключил UnityEngine.SceneManagement, данная библиотека используется для перехода между сценами, после какого-то обновления. Раньше использовался синтаксис Application.LoadLevel, теперь SceneManager.LoadScene который используется с библиотекой UnityEngine.SceneManagement.

 

Следующие отличия мы можем видеть в функции SpawnPlayer, сначала в функции мы как и раньше удаляем персонажа, для того чтобы если мы перед этим куда-то свалились и продолжаем лететь, и конца этому не видно наш клон удалился. Дальше объявляем наш вектор Vector3 pos = new Vector3(0, 1, 0) место где будет появляться наш персонаж. Затем пишем try что запустит функцию следующую в фигурных скобках. То бишь

 

StreamReader sr =new StreamReader(«Position.txt»);

float x = float.Parse(sr.ReadLine());

float z = float.Parse(sr.ReadLine());

sr.Close();

pos=new Vector3(x,1,z);

 

Где снала создается поток считывания информации StreamReader sr который приравнивается новому потоку информации из файла «Position.txt», а затем флотовая переменная x приравнивается одной строке из файла «Position.txt» при помощи float.Parse(sr.ReadLine()); и затем переменная z следующей строке, и мы закрываем поток информации. После чего берем нашу переменную вектора pos и приравниваем её новому вектору pos=new Vector3(x,1,z). Далее если в try выполнится какая-либо ошибка, сразу выполнится catch, которая выведет в консоль «Сохранение не найдено» через Debug.Log(«Сохранение не найдено»). Единственная ошибка которая у нас может быть это может не быть сначала файла «Position.txt» то есть мы еще нигде не сохранились. Следующая строка такая же как была раньше и отвечает за то что персонаж появится по заданным координатам:

 

player = Instantiate (playerPref, pos, Quaternion.identity) as GameObject;

 

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

 

Теперь создаем непосредственно наш скрипт для CheckPoint:

Скрипт CheckPoint в Unity3d
Dante

Сначала подключаем библиотеку для работы с файлами using System.IO, дальше мы создаем файл в функции Start:

 

FileInfo f = new FileInfo («Position.txt»);

if (!f.Exists) f.Create ();

 

Это описывалось в работе с файлами. Затем в функции Update, мы проверяем нажата ли кнопка F и если нажата то вызывается функция FindCheckPoint():

 

if (Input.GetKeyDown(KeyCode.F)) FindCheckPoint();

 

Теперь пишем саму функцию private void FindCheckPoint(){ и в ней объявляем массив игровых объектов GameObject[] checkPoints который равен GameObject.FindGameObjectsWithTag(«CheckPoint») то есть игровые объекты которые имеют Тег «CheckPoint». Давайте покажу на изображении:

Добавление тега CheckPoint
Dante

Как видите у меня есть три объекта на сцене, CheckPointPref, CheckPointPref(1), CheckPointPref(2) на них указывает стрелка в окне Hierarhy, а в окне Inspector, у меня выставлен тег CheckPoint на него тоже указывает стрелка. Для того чтобы добавить этот тег, необходимо нажать в окне Inspector > Add Tag > Tags и ввести название тега то бишь CheckPoint. Теперь в окне Hierarchy выделить один из объектов где будем сохранятся CheckPointPref, затем в окне Inspector > Tag > CheckPoint. То же самое проделываем с CheckPointPref(1), CheckPointPref(2). Так мы получаем массив из этих объектов на сцене с тегом CheckPoint.

 

Дальше по циклу мы объявляем cnt если оно меньше количества массивов элемента cnt<checkPoints.Length то выполняется cnt++:

 

for (int cnt=0; cnt<checkPoints.Length; cnt++) {

 

Дальше мы объявляем флотовую переменную dist равную позиции Vector3.Distance, который задан координатами (transform.position, checkPoints[cnt].transform.position):

 

float dist = Vector3.Distance(transform.position, checkPoints[cnt].transform.position);

 

Ну и если dist меньше 2, if (dist<2) { то в консоль выводится «Сохранение», при помощи Debug.Log («Сохранение»). Теперь запускается функция Saving (checkPoints, cnt). Она у нас написана ниже в скрипте. И дальше пишем break, что сразу же завершает цикл.

 

Теперь давайте перейдем к функции Saving, private void Saving. И в скобках обращаемся к массиву объектов GameObject[] checkPoints и еще отправляем номер элемента int number. Так как данная функция у нас как видим приватная то её можно использовать только в этой функции. Дальше в этой функции создаем поток информации для записи StreamWriter sw = new StreamWriter («Position.txt»); о этом я говорил недавно когда писал о работе с файлами. И записываем в этот файл построчно новые координаты:

 

sw.WriteLine(checkPoints[number].transform.position.x);

sw.WriteLine(checkPoints[number].transform.position.z);

 

Теперь закрываем поток записи. sw.Close();

 

Все скрипт для точки возрождения готов, теперь сохраняем его, и крепим на префаб нашего персонажа

Добавляем скрипт CheckPoint к префабу персонажа
Dante

Файл «Position.txt» находится в папке New Unity Project, если его название вы не меняли, а данная папка там где проект создан.

 

Так же я изменил содержимое скриптов Меню gui и Options их описывать не буду но скрины приложу. Скрипт gui:

Обновленный скрипт gui
Dante

А скрипт Options стал вот такого вида:

Обновленный скрипт для опций
Dante

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

 

Всем спасибо, надеюсь данная статья была полезна не только мне. До следующих статей.

CheckPoint в Unity3d: 2 комментария

  1. Эх, одинокий сайт, аж грустно, не удержусь разбавить его комментарием. Мне кажется наиболее выгодный вариант, это использовать не дистанцию от точки, как бы область, а любой меш-колайдер в виде триггера, наглядно, всегда можно легко изменить размеры и легко прикрепить к динамическому объекту. При этом не придется морочиться с локальными координатами. Многих еще мучает вопрос, как индифицировать чек-поинты, GetInstanceID по ряду причин не уместен, поэтому можно за уникальный номер взять магнитуду такого меша. И просто совет, постарайтесь в тексте меньше употреблять «можете видеть»))) Удачи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *