Walperr

Пикабушник
поставил 15 плюсов и 0 минусов
Награды:
5 лет на Пикабу
14 рейтинг 2 подписчика 1 подписка 2 поста 0 в горячем

Диалоги на Unity3D

Здравствуйте, посетители форума, начинающие, а так же продвинутые программисты. Сегодня я хотел поделиться с вами своей простенькой системой диалогов. Сейчас объясню принцип работы, а с самими скриптами, можете ознакомиться на  GitHub https://github.com/Walperr/Dialogs-On-Unity3D

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

Диалоги на Unity3D Unity3D, Программирование, Csharp, Xml, Gamedev, Unity

Выглядит просто, однако основной сложностью было как раз то, что НПС переводил нас на несколько возможных фраз от игрока. Если в XML файле у нас все фразы, от НПС стоят по порядку друг за другом, и вызываются по их порядковому номеру, то с фразами игрока все немного иначе. В файле они находятся так же по порядку, но имеют атрибут, который определяет к какому блоку относится эта фраза. В итоге сам файл, хранящий в себе фразы будет выглядеть примерно с такой структурой.

Диалоги на Unity3D Unity3D, Программирование, Csharp, Xml, Gamedev, Unity

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

Реализовал я это так: я прописал еще пару фраз отдельно и пометил их, у них, как и у фраз НПС только один атрибут, они не идут блоками, а одиночными фразами, хотя можно добавить несколько фраз из одного события. Они будут переводить нас на фразы НПС, которые как и ранее будут переводить нас на  те же блоки с фразами игрока. Это те же ветки диалогов, просто входим мы в них сторонними фразами, которые активируем после какого-то события в мире игры.  Что же, это основной принцип создания системы диалогов для вашей игры. Ознакомиться с исходником вы можете на гитхабе по ссылке https://github.com/Walperr/Dialogs-On-Unity3D
К сожалению не было времени дописать расширение для редактора юнити, чтобы удобнее настраивать сами диалоги, поэтому все делается в ручную в самом файле. Редактирование самого исходника и дополнение приветствуется. Может кто-то и сделает это окошко для редактирования диалоговых деревьев.

Показать полностью 1

Управление временем на Unity.

Всем привет, сегодня я хотел бы поделиться тем, как я реализовал управление временем на Unity 3D. Думаю многие играли в Price of Percia: The sands of time. Мне показалось, что в этой игре не раскрыли весь потенциал, данной задумки. Что ж давайте подумаем, как можно это реализовать. В unity есть такая вещь, как Time. Вы можете его посмотреть настройки в Time Manager во вкладке Edit/ProjectSettings/Time

Управление временем на Unity. Unity3D, Gamedev, Управление временем, Программирование, Длиннопост

Как мы видим, здесь есть настройки Fixed Timestep - этот параметр определяет то, через какое время будет вызываться функция FixedUpdate. В этой функции выполняется обработка физики RigidBody и тому подобное. Maximum Allowed Time - Отвечает за независимый от частоты кадров отсчет времени, здесь он нам не понадобится. Time Scale - это скорость, с которой течет время, так установив этот параметр на 0 вы остановите движение времени в игре, а установив на значение больше или меньше 1 ускорите или замедлите время соответственно. Очень хорошо может применяться для создания SlowMotion или же для паузы в игре, заметим, что параметр Time Scale не может быть меньше 0, это значит, что мы не можем использовать его для наших целей, то есть можем, но не так просто.


Что же с теорией разобрались теперь давайте подумаем как нам реализовать обратную перемотку. На ум сразу же приходит идея записать позиции и поворот всех нужных нам объектов и присваивать их при нажатии на кнопку. Так и поступим.


Создадим C# скрипт и назовем его Time_.  Создадим массив GameObject и назовем его Objects, создадим также двумерный массив типа Vector3 и еще один двумерный массив типа Quaternion, назовем их Positions и Rotations соответственно.

Управление временем на Unity. Unity3D, Gamedev, Управление временем, Программирование, Длиннопост

Создадим сразу переменную Index типа integer, для того чтобы ориентироваться в массиве. Ведь когда мы будем записывать позиции и поворот, мы должны сохранить это в следующем элементе. Так же создадим переменную Scale типа int, которая будет регулировать размер массивов, а следовательно и длину записи, установим ей значение 1000.  


В Старте инициализируем переменные.

Objects мы будем искать все объекты на сцене по тегу "Time", давайте настроим этот тег.

Objects = GameObject.FindObjectsWithTag("Time"), далее инициализируем Positions и Rotations, устанавливая первый размер Objects.Length, а второй Scale.


Получим что-то вроде этого.

Управление временем на Unity. Unity3D, Gamedev, Управление временем, Программирование, Длиннопост

Давайте сразу пропишем в Update вычисления, если Index больше Scale, то обнуляем Index и записываем все по новой. Это будет значить, что мы возвращаем только последние несколько секунд времени, количество которых зависит от Scale. Тоже самое, только наоборот, делаем и с нулем,  таким образом ограничивая Index (0,Scale).

Управление временем на Unity. Unity3D, Gamedev, Управление временем, Программирование, Длиннопост

В начале мы не просто так затронули функцию FixedUpdate, она вызывается через определенное кол-во кадров, в зависимости от TimeScale, и в ней обрабатывается физика.

Нам нет смысла обновлять позиции каждый кадр, если они не меняются. Следовательно прописываем функцию FixedUpdate() и в ней уже пишем цикл for от 0 до Objects.Length, с переменной і и в этом цикле Positions и Rotations[i,Index] присваиваем текущие позиции и повороты. после цикла в функции прибавляем к Index 1.

Управление временем на Unity. Unity3D, Gamedev, Управление временем, Программирование, Длиннопост

Теперь осталось только присвоить эти значения к текущим позиции и повороту, для этого в Update прописываем условие If(Input.GetKey(KeyKode.R)) и в нем значение TimeScale устанавливаем на 0, так мы защищаем себя от воздействия физики на объекты и перестаем записывать позиции еще раз. Теперь используя функцию Lerp присваиваем позиции и поворот нашему трансформу.

Управление временем на Unity. Unity3D, Gamedev, Управление временем, Программирование, Длиннопост

Теперь осталось просто запускать время, когда отпустим клавишу R, для этого все  в том же Update пишем if(Input.GetKeyUp(KeyKode.R)) и в этом условии устанавливаем значение TimeScale на 1

Управление временем на Unity. Unity3D, Gamedev, Управление временем, Программирование, Длиннопост

Что ж, вот мы и написали небольшой код, для управления временем, он оказался довольно простым и наглядно показывает, как обновляется физика и как работает Lerp, так же практическое применение двумерных массивов в Unity. При настройке не забудьте добавить RigidBody на ваши кубики и установить тег.

Показать полностью 6
Отличная работа, все прочитано!