Unreal Tournament: Сохранение игры в UDK

Программирование в UDK.

Обзор

Конфигурация системы Unreal Engine довольно мощная и зачастую требует сохранения многих переменных. Эта статья представляет собой метод создания системы сохранения игр для RPG, созданных на UDK
Система сохранения игры будет использовать систему хранения пользовательского интерфейса (UI DataStore System) и директивы PerObjectConfig.
Предполагается, что читатель знаком с конфигурационными файлами UDK и синтаксисом C#. Если же нет, то почитайте статьи на эту тему.

Sapitu

Sapitu (Savegames Are Possible In The UDK/Возможность сохранения игры в UDK) реализует простую систему для сохранения игр жанра RPG. Он обладает способностью сохранять персонажа и его инвентарь.
Вы можете скачать полный исходный код этого примера здесь
Sapitu делится на 4 класса. Программа также содержит 2 дополнительных класса: SapituGame и SapituPC , используемые только для игр с внедренной системой Sapitu.
Четыре класса Sapitu заключаются в следующем:
Sapitu Это основной класс, который управляет различными частями системы сохранения игр.
SapituCharacter Этот класс хранит информацию о персонаже.
SapituInventory Этот класс предмета инвентаря, который может принадлежать к SapituCharacter
SapituItem Этот класс используется в качестве базы данных для создания записи SapituInventory. Экземпляры этого класса предназначены только для чтения в рамках системы.

Класс Sapitu

Этот класс определяет какой-либо метод для управления, сохранения и загрузки новых символов. Он также содержит методы для создания новых предметов инвентаря и сохраняет ссылку на них в базы данных.

База данных

Метод loadItemDB инициализирует базу данных SapituItem и является частью системы хранения пользовательского интерфейса в Unreal Engine. Эта система также используется для получения информации о типах игры, карты, и оружии в UDK.
Метод getItem предоставляет средство для поиска фактических SapituItem (например, в текущей базе данных имя объекта (свойство Object.name). Это имя (точнее, идентификатор) является лишь программным именем (что-то вроде равкода в Варкрафте).
База данных используется в системе инвентаризации, чтобы найти статичные предметы инвентаря (точнее ссылку на них).

Персонаж

Класс Sapitu является опорной точкой при сохранении и загрузке SapituCharacter.
Метод getCharacters возвращает список всех зарегистрированных на персонаже идентификаторов. Так же, как идентификатор элементов базы данных он относится к свойству Object.name (Еще раз напомню, это не удобное читаемое в игре имя, а внутренний идентификатор!). Этот идентификатор необходим во время загрузки или сохранения персонажей. На ИД есть одно важное ограничение - он не должен содержать пробелов, только буквы в диапозоне [Aa-Zz] и цифры. Могу посоветовать давать им понятные имена, чтобы потом не запутаться.
Загрузка и создание символов, на самом деле похожие процедуры. Обе они используют следующий код:
myChar = new(none, "MyCharId") class'SapituCharacter';
Второй параметр, собственно, определяет название создаваемого/загружаемого объекта.
Для того чтобы провести четкое различие между загрузкой и созданием новых символов в Sapitu мы сначала проверяем, существует ли данный идентификатор, а затем, соответственно, принимаем или возвращаем значение. Если объяснять понятней, то при загрузке мы принимаем при существующем ИД, а при сохранении возвращаем при отсутствующем ИД)
Загрузка персонажа еще не закончена, это только начало. Нам также необходимо инициализировать его инвентарь. SapituCharacter хранит список идентификаторов для SapityInventory items (SapituCharacter.inventoryRecord ).

Инвентарь. Создание предметов

Предметы инвентаря создаются специальным образом. createInventory – это способ создать новый элемент инвентаря на основе данных SapituItem. Он создает уникальный идентификатор для инвентаря, а затем выполняет специальную конструкцию new(none, inventoryId) class'SapituInventory' . После этого будут загружаться различные переменные, которые были не определены SapituItem (например, как уровень, вес и стоимость).

Класс SapituCharacter

Этот класс определяется как
class SapituCharacter extends Object config(Sapitu) perobjectconfig;
Это означает, что некоторые из переменных в классе будут сохранены в файле конфигурации UTSapitu.ini , и что для каждого объекта будет создан отдельный раздел. Последние является результатом работы директивы класса perobjectconfig. Имя объекта имеет важное значение при сохранении, например, потому что оно определяет название раздела.
Этот класс хранит различные конфиги переменных для имени персонажа (уже понятного для человека имени, а не ИД), здоровья и т.д.
Инвентарь персонажа сохраняется иным способом. Добавление и удаление предметов инвентаря должно быть сделано с помощью методов addInventory и removeInventory. Этот способ позволяет обновить массивы inventory и inventoryRecords. Массив inventory не может быть изменен непосредственно. Класс Sapitu запрещает это, но это особый метод. :)
Вы не можете принимать значения из SaveConfig, потому что инвентарь не сохранится должным образом. Метод save перебирает массив инвентаря и принимает значения SaveConfig. Таким образом, все, что относится к персонажу сохраняется правильно.

Класс SapituInventory

Этот класс является фактически самим инвентарем. Он основан на классе SapituItem. Работа с этим классом такая же, как и с SapituCharacter

SapituItem

В отличие от классов SapituCharacter и SapituInventory этот класс является подклассом UTUIResourceDataProvider . Он не объявляется, как config , потому что в родительском классе уже определена его конфигурация (объявлялось при помощи PerObjectconfig).
Также обратите внимание на bSearchAllInis=true в разделе defaultproperties. Эта переменная является частью системы хранения пользовательского интерфейса. Она определяет, что система хранения должна пройти через все файлы конфигурации, чтобы найти объекты.
Загрузка SapituItems не должна быть сделана на основе ранее упомянутой конструкции new(none,id). Чтобы получить все объявленные SapituItem, вы должны использовать следующий код:
class'UTUIDataStore_MenuItems'.static.GetAllResourceDataProviders(class'SapituItem', ProviderList);
SapituItems объявляются вручную, путем добавления строки вроде этой:
[Sword1 SapituItem]
DisplayName = короткий меч Видимое имя
level=(min=1,max=10) Уровень
weight=(base=10,levelMult=0.5) Вес
value=(base=5,levelMult=1) Значение
См. файл UTGame\Config\SapituItemDB.ini для просмотра дополнительных примеров

Примечания

Отметим также, что сохранение игры происходит в виде простого текста. Побеспокойтесь о возможном читерстве. Так что лучше использовать сохранение в бинарный файл (двоичный код). Конечно от «про» это не спасет, но от лишних глаз будет подальше.

Игра с Sapitu

Чтобы играть с этой системой, просто компилируйте исходник и начните игру со следующим параметром:
udk examplemap?game=sapitu.sapitugame
Класс SapituPC определяет команды, вводимые в консоли:
  • createChar <имя>
  • saveChar
  • loadChar <Id чара>
  • printChars
  • showChar
  • createRandomItem
  • createItem <baseItem>
  • pickupItem <Id предмета>
  • pickupAll
  • findItems
  • listItemTypes
Пишем ток без <> :)
Заметим, что система, представленная здесь это лишь один из нескольких способов создать систему сохранения игры.

Просмотров: 8 354

OBowb #1 - 9 лет назад 0
ХА! Надо тока сделать лучше чтоп нэйм не через консоль стучать, а как во всех играх.