Вторник, 26 Ноября 2024, 09:43

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Работаем с XML файлами с помощью сериализации/десериализации
SnakeRДата: Пятница, 18 Июля 2014, 19:38 | Сообщение # 1
постоянный участник
Сейчас нет на сайте
Сей краткий урок, я хочу посвятить такой удобной штуке в работе с XML как XmlSerializer,
класс из пространства имен System.Xml.Serialization, который позволяет творить настоящие чудеса)
Ну а если серьезно, то сохранять и загружать ваши данные, а точнее классы в которых они описаны, в формат XML очень и очень просто.
К примеру, я хочу, чтобы все предметы в моей игре хранились в XML файле.
Для начала мы опишем класс с помощью которого будем впоследствии сохранять данные, и сам класс, который будет хранить данные предмета.

Код
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;

//Здесь указываем название корневого эелемента
[XmlRoot("Items")]
public class ItemSetSerialized {
   //Здесь указываем что у нас будет массив из элементов, типа ItemSerialized
   [XmlArray("ItemSet"), XmlArrayItem("Item",typeof(ItemSerialized))]
   //Массив для хранения наших данных, в данном случае List<>
   public List<ItemSerialized> ItemSet;
     
   //Конструктор нашего класса.
   public ItemSetSerialized()
   {
    //В конструкторе создаем новый список.
    ItemSet = new List<ItemSerialized>();
   }

}

//Описание структуры данных для предмета, эта структура в XML будет представлена в виде элемента.
public class ItemSerialized
{
   // [XmlAttribute("ItemType")] - здесь мы задаем название атрибута нашего элемента и тип данных которые он будет хранить.
   [XmlAttribute("ItemType")]
   public ItemType itemType;
     
   [XmlAttribute("ItemName")]
   public string itemName;
     
   [XmlAttribute("ItemCost")]
   public int itemCost;
     
}

public enum ItemType
{
   Weapon = 0,
   Armor = 1,
   Potion = 2
}


Итак, у нас есть структура данных, которая описывает наш предмет. Теперь дело осталось за малым, создать сам предмет и записать его в файл.

Код
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

public class ItemCreator : MonoBehaviour {

   private XmlDocument _doc;
      private string _xmlName = "ItemData.xml";
      private string _fileName = "ItemData";
     
   private ItemSetSerialized _itemSet;
     
   private void Start()
   {
    //Для примера, создадим два предмета, добавим их в наш класс, который мы будем сереализовать и сохраним данные в файл.
      
    //Создаем новый экземпляр нашего класса, который будет хранить все наши предметы.
    _itemSet = new ItemSetSerialized();    
      
    //Создаем новый экземпляр класса, который описывает сам предмет.
    ItemSerialized itemOne = new ItemSerialized();    
    //Первый предмет
    itemOne.itemType = ItemType.Armor;
    itemOne.itemName = "Really cool armor";
    itemOne.itemCost = 50;
      
    //И второй
    ItemSerialized itemTwo = new ItemSerialized();    
    itemTwo.itemType = ItemType.Potion;
    itemTwo.itemName = "Health potion";
    itemTwo.itemCost = 15;
      
    //Добавляем наши предметы в список.
    _itemSet.ItemSet.Add(itemOne);
    _itemSet.ItemSet.Add(itemTwo);
      
    //Сохрянем файл.
    SaveFile();    
   }   
     
   //Сохраняем наши данные в файл
   private void SaveFile()
      {
          //Создаем новый экземпляр класса XmlSerializer с указанием нашего класса с данными, ItemSetSerialized, которые необходимо сериализовать.
    XmlSerializer serializer = new XmlSerializer(typeof(ItemSetSerialized));
    //С помощью класса FileStream записываем наши данные в файл.
          FileStream stream = new FileStream(Application.dataPath + @"/Resources/ItemData.xml", FileMode.Create);
    //Сериализуем данные в поток записи нового файла.
          serializer.Serialize(stream, _itemSet);
    //Заканчиваем запись нового файла.
          stream.Close();                
      }
     
     
   //Если у нас уже есть сохраненный ранее файл, то вот так мы можем его загрузить и далее работать с данными как с обычным классом.
   private void LoadXmlData()
   {    
    //Создаем новый Xml документ
    _doc = new XmlDocument();
    //В TextAsset считываем наш сохраненный файл
          TextAsset text = new TextAsset();
          text = (TextAsset)Resources.Load(_fileName, typeof(TextAsset));
    //Загружаем и преобразуем текст в наш XMl документ
          _doc.LoadXml(text.text);
    //Указываем наш класс с  данными которыеS нужно десериализовать, в нашем случае это ItemSetSerialized.
          XmlSerializer serializer = new XmlSerializer(typeof(ItemSetSerialized));
          XmlReader reader = new XmlNodeReader(_doc.ChildNodes[1]);
    //Здесь рпоходит сама десериализация, в результате мы получаем новый экземпляр класса ItemSetSerialized, в который загрузятся все данные.
          _itemSet = (ItemSetSerialized)serializer.Deserialize(reader);    
   }
}


Вот так будет выглядеть созданный нами XMl файл.

Код
<?xml version="1.0" encoding="windows-1251"?>
<Items xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <ItemSet>
      <Item ItemType="Armor" ItemName="Really cool armor" ItemCost="50" />
      <Item ItemType="Potion" ItemName="Health potion" ItemCost="15" />
    </ItemSet>
</Items>


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


Unity3D Developer
Ваш лучший помощник при разработке в Unity3D


Сообщение отредактировал SnakeR - Пятница, 18 Июля 2014, 19:42
robertonoДата: Пятница, 18 Июля 2014, 19:42 | Сообщение # 2
Чокнутый Кот
Сейчас нет на сайте
У меня есть вторая часть игры где можно строить. Я уже три раза его переделывал, и в третий раз я сделал его за несколько дней (а раньше за полтора месяца). Опыта набрался) Но не в этом суть. Раньше я в xml сохранял, а теперь я сделал типо свой формат biggrin
Хотя это простой текстовой файл. Читать легко, и глазами и через код smile
XML быстрее наверно немного) Я там через split у себя каждую строку прогоняю.
SnakeRДата: Понедельник, 21 Июля 2014, 15:56 | Сообщение # 3
постоянный участник
Сейчас нет на сайте
Более расширенный вариант урока с обещанным продолжением вы сможете найти здесь
Написание расширений для редактора Unity3D.


Unity3D Developer
Ваш лучший помощник при разработке в Unity3D


Сообщение отредактировал SnakeR - Понедельник, 21 Июля 2014, 15:57
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг