Unity3d IO流(3)之XML研究

节主要写的东西是XML。

首先我们要理解一下序列化的概念:序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

要了解详细点就参考百科:http://baike.baidu.com/view/160029.htm

这些东西有点抽象。我和大家分享一下我个人对序列化的理解,大牛们多多赐教^-^

比如:我们有一个类A,

class A{

public int age;

public string name;

};

我们把A序列化为XML,以方便对数据的解析。

<A>

<age>value</age>

<name>value</name>

</A>

很形象吧,呵呵。反序列化就是把下面的序列化成上面的啦

好了,我们步入正题。

我们需要写2个工具类,这个2个类不需要赋给任何物体。

原始代码:请参看官方的http://wiki.unity3d.com/index.php?title=Save_and_Load_from_XML  我这里做了些修改。方便我们大家更好的使用XML对数据的读写操作。

你要保存数据,就save一下,调用方法是PlayerData.SaveFile(),读取数据就load一下,调用方法是PlayerData.LoadFile();

工具类之一:PlayerData类

//author :by taotao
//date:2012/12/24
//purpose:为了共享,一起学习,一起交流,一起进步
using UnityEngine;
using System.Collections;
using System;//for Exception
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Text;
#if UNITY_EDITOR
using UnityEditor;
#endif


public class PlayerData 
{
    //xml的保存路径
    public static string xmlPath = Application.dataPath + "/XMLFile/XMLData/Files.xml";
    //玩家的游戏数据
 public static GameData gameData; 
 
 public static bool SaveFile()
 {
  try
  {
   if(gameData==null)
    throw new Exception("gameData is null");
   CreateXML(SerializeObject(gameData));   
  }
  catch(Exception e)
  {
   Debug.LogError(e.Message);
   return false;
  }
  return true;
   
 }
 
 public static bool LoadFile()
 {
  try
  {
   string data=LoadXML();
   gameData=(GameData)DeserializeObject(data);
  }
  catch(Exception e)
  {
   Debug.LogError(e.Message);
   return false;
  }
  return true;
 
 
 protected static void CreateXML(string data)
 {
     StreamWriter writer;
  FileInfo file=new FileInfo(xmlPath);
  if(file.Exists)
   file.Delete();
  writer=file.CreateText();
  writer.Write(data);
  writer.Close();
  Debug.Log("File Written");
        //更新一下
#if UNITY_EDITOR
        AssetDatabase.Refresh();
#endif

 }
 
 protected static string LoadXML()
 {
  if(!File.Exists(xmlPath))
   throw new Exception("File not exist or no access:"+xmlPath);
  StreamReader reader=File.OpenText(xmlPath);
  string data=reader.ReadToEnd();
  reader.Close();
  if(data==null|| data.Length<1)
   throw new Exception("read error:data"+((data==null)?" null":" length=0"));
  Debug.Log("File Read");
  return data;
 }
 
 protected static string UTF8ByteArrayToString(byte[] characters)
 {
  UTF8Encoding encoding=new UTF8Encoding();
  string constructedString=encoding.GetString(characters);
  return constructedString;
 }
 
 protected static byte[] StringToUTF8ByteArray(string xmlString)
 {
  UTF8Encoding encoding=new UTF8Encoding();
  byte[] byteArray=encoding.GetBytes(xmlString);
  return byteArray;
 }
 
 protected static string SerializeObject(object pObject)
 {
  string xmlizedString=null;
  MemoryStream memoryStream=new MemoryStream();
  XmlSerializer xs=new XmlSerializer(typeof(GameData));
  XmlTextWriter xmlTextWriter=new XmlTextWriter(memoryStream,Encoding.UTF8);
  xs.Serialize(xmlTextWriter,pObject);
  memoryStream=(MemoryStream)xmlTextWriter.BaseStream;
  xmlizedString=UTF8ByteArrayToString(memoryStream.ToArray());
  return xmlizedString;  
 }
 
 protected static object DeserializeObject(string xmlizedString)
 {
  XmlSerializer xs=new XmlSerializer(typeof(GameData));
  MemoryStream memoryStream=new MemoryStream(StringToUTF8ByteArray(xmlizedString));
  return xs.Deserialize(memoryStream);
 
}

工具类之二:PlayerInfo

  这个类是你的游戏里需要保存,读写的数据。

这里只是简单的写了一点点:具体数据要玩家写

using UnityEngine;
using System.Collections;
using System.Collections.Generic;//List要用到这个命名空间
using System;//string要用到这个命名空间
//需要加上这个在类上,好序列化对象
[System.Serializable]
public class GameData
{
 public string m_gameName;
 public List<PlayerInfo> m_playerInfo;
 public GameData()
 {
  m_gameName=null;
  m_playerInfo=new List<PlayerInfo>();
 }
 public GameData(string gameName)
 {
  m_gameName=gameName;
     m_playerInfo=new List<PlayerInfo>();
 }
}
//需要加上这个在类上,好序列化对象
[System.Serializable]
public class PlayerInfo{

     public string m_playerName;
  public int[] m_hp;
  public List<int> m_mp;
 public PlayerInfo()
 {
  m_playerName=null;
  m_hp=new int[0];
  m_mp=new List<int>();
 }
 public PlayerInfo(string playerName)
 {
  m_playerName=playerName;
  m_hp=new int[0];
  m_mp=new List<int>();
 }
}
好了,u3d里xml的读写操作就写完了。呵呵,为了告诉大家如何使用。还需要一步:

我们在u3d里的GUI打印出来,方便大家更好的理解:

这里我们需要写个脚本。我暂且命名:UserDemo

具体脚本如下:

using UnityEngine;
using System.Collections;

public class UserDemo : MonoBehaviour {

 private GameData gameData;
 private PlayerInfo demoInfo;
 
    void Start()
 {
        //我们把游戏的初始化为:DemoGame,这个你可以任意命名啦
  gameData=new GameData("DemoGame");
  demoInfo=new PlayerInfo("subItem1:");
  demoInfo.m_hp=new int[5];
  for(int i=0;i<demoInfo.m_hp.Length;i++)
   demoInfo.m_hp[i]=2*i+1;
  for(int i=0;i<5;i++)
      demoInfo.m_mp.Add(3*i+2);
  gameData.m_playerInfo.Add(demoInfo);
  
  demoInfo=new PlayerInfo("subItem2:");
  demoInfo.m_hp=new int[8];
  for(int i=0;i<demoInfo.m_hp.Length;i++)
   demoInfo.m_hp[i]=Random.Range(1,4)+2*i;
  for(int i=0;i<8;i++)
      demoInfo.m_mp.Add(Random.Range(3,10)+3*i);
  gameData.m_playerInfo.Add(demoInfo);
  
  PlayerData.gameData=gameData;
 }
 
 void OnGUI()
 {
        GUILayout.BeginArea(new Rect(0, 0, Screen.width, Screen.height));
        GUILayout.BeginHorizontal();
        GUILayout.FlexibleSpace();
        GUILayout.BeginVertical();
        GUILayout.FlexibleSpace();

  if(GUILayout.Button("Clear:"))
  {
   PlayerData.gameData=null;
  }
  if(GUILayout.Button("Save:"))
  {
   bool isSave=PlayerData.SaveFile();
   Debug.Log("save:"+isSave);
  }
  if(GUILayout.Button("Load:"))
  {
   bool isLoad=PlayerData.LoadFile();
   Debug.Log("load:"+isLoad);
  }
  GUILayout.Space(20);
  if(PlayerData.gameData!=null)
  {
   GameData data=PlayerData.gameData;
   GUILayout.Label(data.m_gameName+"  have :"+data.m_playerInfo.Count.ToString()+" subItem");
   for(int i=0;i<data.m_playerInfo.Count;i++)
   {
    GUILayout.Label(data.m_playerInfo[i].m_playerName+"  hp:"+data.m_playerInfo[i].m_hp.Length
     +" mp:"+data.m_playerInfo[i].m_mp.Count);
    string hp="";
    for(int j=0;j<data.m_playerInfo[i].m_hp.Length;j++)
    {
     hp+=data.m_playerInfo[i].m_hp[j].ToString()+" ";
    }
    GUILayout.Label(hp);
    string mp="";
    for(int k=0;k<data.m_playerInfo[i].m_mp.Count;k++)
    {
     mp+=data.m_playerInfo[i].m_mp[k].ToString()+" ";
    }
    GUILayout.Label(mp);
   }
  }

        GUILayout.FlexibleSpace();
        GUILayout.EndVertical();
        GUILayout.FlexibleSpace();
        GUILayout.EndHorizontal();
        GUILayout.EndArea();

 }
}

 

好了,我们运行一下u3d

Unity3d <wbr>IO流(3)之XML研究
我们便会看到,蓝色区域里的数据了,这些数据使我们写入的数据
Unity3d <wbr>IO流(3)之XML研究
之后我们保存一下
Unity3d <wbr>IO流(3)之XML研究
在工程面板里便会多出来File.xml文件了;在检测面板里你便能看到我们写的数据了
Unity3d <wbr>IO流(3)之XML研究

为了方便我们大家的阅读,我们定位到Files文件夹里,用IE打开,如下
Unity3d <wbr>IO流(3)之XML研究
以上的数据多清晰啊。^-^.我们点击clear按钮
Unity3d <wbr>IO流(3)之XML研究
数据便清干净了。
Unity3d <wbr>IO流(3)之XML研究
接着,我们点击一下load按钮
Unity3d <wbr>IO流(3)之XML研究
数据又加载进来了。
Unity3d <wbr>IO流(3)之XML研究

这里我们没有对数据进行加密处理,其实加密也不难。我们在PlayerData工具类里加入2个方法就OK了,一个字符串key。

不要忘了加入using System.Security.Cryptography;这个命名空间

    public static string encryptKey = "dtao1357";

    /// 字符串加密
    private static string Encrypt(string str)
    {

        //实例化加密解密对象

        DESCryptoServiceProvider desc = new DESCryptoServiceProvider();

        //定义字节数组、用来存储密钥
        byte[] key = UTF8Encoding.UTF8.GetBytes(encryptKey);

        //定义字节数组、用来存储要解密的字符串
        byte[] data = UTF8Encoding.UTF8.GetBytes(str);

        //实例化内存流对象
        MemoryStream ms = new MemoryStream();

        //使用内存流实例化加密流对象
        CryptoStream cstream = new CryptoStream(ms, desc.CreateEncryptor(key, key),
        CryptoStreamMode.Write);

        //向加密流中写入数据
        cstream.Write(data, 0, data.Length);

        //释放加密流
        cstream.FlushFinalBlock();

        //返回加密后的字符串
        return Convert.ToBase64String(ms.ToArray());
    }

    //解密字符串
    private static  string Decrypt(string str)
    {
        DESCryptoServiceProvider desc = new DESCryptoServiceProvider();
        byte[] key = UTF8Encoding.UTF8.GetBytes(encryptKey);
        byte[] data = Convert.FromBase64String(str);
        MemoryStream mstream = new MemoryStream();
        CryptoStream cstream = new CryptoStream(mstream, desc.CreateDecryptor
        (key, key), CryptoStreamMode.Write);
        cstream.Write(data, 0, data.Length);
        cstream.FlushFinalBlock();
        return UTF8Encoding.UTF8.GetString(mstream.ToArray());
    }
Unity3d <wbr>IO流(3)之XML研究

相应的CreateXML和LoadXML也要修改一下

 protected static void CreateXML(string data)
 {
     StreamWriter writer;
  FileInfo file=new FileInfo(xmlPath);
  if(file.Exists)
   file.Delete();
  writer=file.CreateText();
        //writer.Write(data);//把这里注视掉
        //换成如下*************/
        string xx = Encrypt(data);//加密
        writer.Write(xx);        
  writer.Close();
  Debug.Log("File Written");
        //更新一下
#if UNITY_EDITOR
        AssetDatabase.Refresh();
#endif

 }
 
 protected static string LoadXML()
 {
  if(!File.Exists(xmlPath))
   throw new Exception("File not exist or no access:"+xmlPath);
  StreamReader reader=File.OpenText(xmlPath);
  string data=reader.ReadToEnd();
  reader.Close();
  if(data==null|| data.Length<1)
   throw new Exception("read error:data"+((data==null)?" null":" length=0"));
  Debug.Log("File Read");
        //return data;//注视掉
        //换成如下**********************/
        string xx = Decrypt(data);//解密      
        return xx;   

 }

Unity3d <wbr>IO流(3)之XML研究

 

好了这些弄完之后,我们运行一下u3d并点击save按钮一下:

Unity3d <wbr>IO流(3)之XML研究
我们便能在监视面板里看到一大堆加密字符串了
Unity3d <wbr>IO流(3)之XML研究
为了方便我们大家查看,我也也用ie打开一下,结果如下:究其原因,应该使我们对数据加密了,所以才会这个的
Unity3d <wbr>IO流(3)之XML研究

我们点击一下clear按钮,清除一下数据
Unity3d <wbr>IO流(3)之XML研究
游戏面板变成如下,我们点击一下load按钮,看看我们的数据解密没有
Unity3d <wbr>IO流(3)之XML研究
解密了,因为我们看到的不是乱码。哇咔咔(*^__^*)
Unity3d <wbr>IO流(3)之XML研究
好了,我们对xml的编写完了。不早了,晚安啦!

下次教程我会写一个小游戏,用到我这节写的2个工具类脚本。好更能加深大家的印象。

转载:http://blog.sina.com.cn/s/blog_a4c1823d0101czfd.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Unity 是一种跨平台的游戏引擎,可以用于开发各种类型的游戏和交互应用程序。在 Unity 中,我们可以使用 C# 编程语言来访问 IO 流以及查找 HID 设备。 IO 流是指输入输出流,它允许我们从设备读取数据或将数据写入设备。Unity 提供了一些类和方法,使我们能够以编程方式访问和处理 IO 流。通过使用 IO 流,我们可以读取来自设备的数据,如传感器数据或控制器输入,也可以将数据写入设备,如保存游戏状态或发送指令给外部设备。 HID 设备是指 Human Interface Device,即人机接口设备。它可以是键盘、鼠标、游戏手柄等可用于与计算机进行交互的设备。在 Unity 中,我们可以通过 IO 流来查找 HID 设备。通常,我们可以使用 Unity 提供的 `Input` 类来检测和处理用户输入,如键盘按键或鼠标移动。但是,如果我们需要与其他类型的 HID 设备进行交互,我们就需要使用 IO 流来查找和访问这些设备。 要通过 IO 流找到 HID 设备,我们可以使用 C# 中的 `System.IO` 和 `System.Management` 命名空间中的类和方法。我们可以使用 `ManagementObjectSearcher` 类来搜索系统中的 HID 设备,然后使用 `ManagementObject` 类来获取设备的详细信息。通过分析设备的属性,我们可以确定设备是否是 HID 设备,并进一步与之交互。 总之,Unity 通过 IO 流可以找到并与 HID 设备进行交互。我们可以使用 C# 编程语言以及 `System.IO` 和 `System.Management` 命名空间中的类和方法来实现这一目标。通过搜索和分析设备属性,我们可以确定设备是否是 HID 设备,并以及如何与之进行交互。这样,我们就可以为我们的游戏或应用程序添加更加丰富的交互功能。 ### 回答2: Unity通过使用IO流的方法可以找到HID设备。 在Unity中,可以使用System.IO命名空间来处理输入和输出流。要搜索HID设备,我们可以使用System.IO.Directory类的GetFiles方法,该方法接受一个路径参数,并返回该目录中的文件。 首先,我们需要了解HID设备在计算机中的路径。通常,在Windows系统中,HID设备在设备管理器中以类似于"\\.\HID#VID_XXXX&PID_XXXX"的格式表示,其中VID代表供应商ID,PID代表产品ID。因此,我们需要获取所有类似于该格式的设备路径。 这里我们可以编写一个方法来搜索HID设备: ```csharp using System; using System.IO; public class HidDeviceFinder { public static string[] FindHidDevices() { string[] devicePaths = Directory.GetFiles(@"\\.\HID*"); return devicePaths; } } ``` 在上述代码中,我们使用Directory.GetFiles方法来搜索HID设备路径,并将结果以字符串数组的形式返回。 要在Unity中使用这个方法,我们可以在脚本中调用这个方法并打印返回的路径: ```csharp using UnityEngine; public class ExampleScript : MonoBehaviour { void Start() { string[] devicePaths = HidDeviceFinder.FindHidDevices(); foreach (string path in devicePaths) { Debug.Log(path); } } } ``` 这样,在Unity中运行时,控制台将输出找到的HID设备路径。 需要注意的是,在使用IO流搜索HID设备时,需要相应的权限和底层操作系统的支持。此外,HID设备的路径可能会根据系统的不同而有所差异,因此我们需要根据实际情况对代码进行调整。 ### 回答3: Unity是一种跨平台的游戏引擎,常用于游戏开发。Unity提供了一些用于读取和写入文件的方法,可以通过IO流来访问文件系统。而HID(Human Interface Device)是一种人机接口设备,例如鼠标、键盘和游戏手柄等。 在Unity中,我们可以使用IO流来查找HID设备。具体步骤如下: 1. 首先,我们需要导入System.IO和System.Collections.Generic命名空间,以便使用IO流和集合。 2. 接下来,我们可以使用System.IO.Directory类的静态方法GetFiles来获取指定文件夹中所有的文件路径。我们可以指定特定的文件夹路径,例如"/dev/input"。 3. 然后,我们可以遍历获取到的文件路径,使用System.IO.File类的静态方法ReadAllLines来读取文件内容。这些文件可能包含有关HID设备的信息。 4. 我们可以使用正则表达式或其他解析方法来筛选并提取我们感兴趣的HID设备信息。例如,我们可以搜索包含特定关键字或特定设备类型的文件。 5. 最后,我们可以将找到的HID设备信息保存到一个集合中,以供后续使用。 总之,Unity通过IO流可以找到HID设备的过程是:获取指定文件夹中的文件路径,读取文件内容,筛选和提取HID设备信息,并保存到集合中。这样我们就可以在Unity中获取并使用HID设备了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值