Unity手遊之路C#版本Protobuf

一個遊戲包含了各種數據,包括本地數據和與服務端通信的數據。今天我們來談談如何存儲數據,以及客戶端和服務端的編碼方式。根據以前的經驗,我們可以用字符串,XML,json...甚至可以直接存儲二進制。各種方式都有各自的優劣,有些性能比較好,但是實現方式比較麻煩。有些數據冗餘太多。
  • 簡介
今天我們來學習一種廣泛使用的數據格式:Protobuf。簡單來說,它就是一種二進制格式,是google發起的,目前廣泛應用在各種開發語言中。具體的介紹可以參見:https://code.google.com/p/protobuf/ 。我們之所以選擇protobuf,是基於它的高效,數據冗餘少,編程簡單等特性。關於C#的protobuf實現,網上有好幾個版本,公認比較好的是Protobuf-net。

  • 實例
先來看一個最簡單的例子:把一個類用Protobuf格式序列化到一個二進制文件。再讀取二進制數據,反序列化出對象數據。

從網上參考了一個例子 http://blog.csdn.net/ddxkjddx/article/details/7239798

//----------------實體類----------------------

  1. using UnityEngine; 
  2. using System.Collections; 
  3. using ProtoBuf; 
  4. using System; 
  5. using System.Collections.Generic; 
  6.  
  7.  
  8. [ProtoContract] 
  9. public class Test { 
  10.  
  11.  
  12.     [ProtoMember(1)] 
  13.     public int Id 
  14.     { 
  15.         get
  16.         set
  17.     } 
  18.  
  19.  
  20.     [ProtoMember(2)] 
  21.     public List<String> data 
  22.     { 
  23.         get
  24.         set
  25.     } 
  26.  
  27.  
  28.     public override string ToString() 
  29.     { 
  30.         String str = Id+":"
  31.         foreach (String d in data) 
  32.         { 
  33.             str += d + ","
  34.         } 
  35.         return str; 
  36.     } 
  37.      
using UnityEngine;
using System.Collections;
using ProtoBuf;
using System;
using System.Collections.Generic;


[ProtoContract]
public class Test {


    [ProtoMember(1)]
    public int Id
    {
        get;
        set;
    }


    [ProtoMember(2)]
    public List<String> data
    {
        get;
        set;
    }


    public override string ToString()
    {
        String str = Id+":";
        foreach (String d in data)
        {
            str += d + ",";
        }
        return str;
    }
	
}

//-----------測試類---------------------------
  1. using UnityEngine; 
  2. using System.Collections; 
  3. using System.Collections.Generic; 
  4. using System.IO; 
  5. using ProtoBuf; 
  6. using System; 
  7.  
  8.  
  9. public class ProtobufNet : MonoBehaviour { 
  10.  
  11.  
  12.     private const String PATH = "c://data.bin"
  13.  
  14.  
  15.     void Start () { 
  16.         //生成數據 
  17.         List<Test> testData = new List<Test>(); 
  18.         for (int i = 0; i < 100; i++) 
  19.         { 
  20.             testData.Add(new Test() { Id = i, data = new List<string>(new string[]{"1","2","3"}) }); 
  21.         } 
  22.         //將數據序列化後存入本地文件 
  23.         using(Stream file = File.Create(PATH)) 
  24.         { 
  25.             Serializer.Serialize<List<Test>>(file, testData); 
  26.             file.Close(); 
  27.         } 
  28.         //將數據從文件中讀取出來,反序列化 
  29.         List<Test> fileData; 
  30.         using (Stream file = File.OpenRead(PATH)) 
  31.         { 
  32.             fileData = Serializer.Deserialize<List<Test>>(file); 
  33.         } 
  34.         //打印數據 
  35.         foreach (Test data in fileData) 
  36.         { 
  37.            Debug.Log(data); 
  38.         } 
  39.     } 
  40.      
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using ProtoBuf;
using System;


public class ProtobufNet : MonoBehaviour {


    private const String PATH = "c://data.bin";


	void Start () {
        //生成數據
        List<Test> testData = new List<Test>();
        for (int i = 0; i < 100; i++)
        {
            testData.Add(new Test() { Id = i, data = new List<string>(new string[]{"1","2","3"}) });
        }
        //將數據序列化後存入本地文件
        using(Stream file = File.Create(PATH))
        {
            Serializer.Serialize<List<Test>>(file, testData);
            file.Close();
        }
        //將數據從文件中讀取出來,反序列化
        List<Test> fileData;
        using (Stream file = File.OpenRead(PATH))
        {
            fileData = Serializer.Deserialize<List<Test>>(file);
        }
        //打印數據
        foreach (Test data in fileData)
        {
           Debug.Log(data);
        }
	}
	
}

  • 總結

Protobuf-net 利用Attributes來實現序列化字段,對程序員的負擔減輕,代碼侵入性也降低。接下來,我將會寫一個簡單的Unity c/s demo,其中的通信編碼就是用到Protobuf,

到時再與大家分享。有任何問題歡迎一起探討[email protected]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章