1. 程式人生 > >Unity3d 讀取配置文字自動生成C#類 (一)

Unity3d 讀取配置文字自動生成C#類 (一)

前幾天做了一個可以通過讀取配置文字自動生成C#類的工程,因此想寫下來分享給大家順便給自己加深一點印象。

首先是獲取到配置檔案的文字路徑,這裡就不多做介紹了,不瞭解的可以查閱Unity3d實現開啟視窗選擇檔案獲取路徑

獲取到路徑後 開始準備讀寫檔案,讀寫檔案的方法也有很多 可參考 C#讀寫檔案的兩種方式

我這裡使用的是StreamReader和StreamWriter的方式進行讀寫。

1.先讀取已經生成好的配置檔案並生成新的.cs指令碼

    //filePath為配置檔案的路徑
    public string ConfigFileToClass(String filePath)
    {
        string strData = "";
        try
        {
            string line;
            // 建立一個 StreamReader 的例項來讀取檔案 ,using 語句也能關閉 StreamReader
            using (System.IO.StreamReader sr = new System.IO.StreamReader(filePath,Encoding.Default))
            {
                //設定生成的C#類目錄,我這裡是直接放到了專案下 
                string CurDir = Application.dataPath+"/Scripts/Configure/";
                //判斷路徑是否存在
                if (!System.IO.Directory.Exists(CurDir))
                {
                    System.IO.Directory.CreateDirectory(CurDir);
                }
                //生成的是c#類   所以需要加上.cs字尾  這裡的Pathname為生成類的名字
                String FilePath = CurDir + Pathname + ".cs";
                //檔案覆蓋方式新增內容
                System.IO.StreamWriter file = new System.IO.StreamWriter(FilePath, false);
                //儲存資料到檔案(將C#類需要的標頭檔案先寫入)
                file.Write("using System.Collections;\n");
                file.Write("using System.Collections.Generic;\n");
                file.Write("using UnityEngine;\n");
                file.Write("\n");
                //寫入類名(與檔名相同)
                file.Write("public class ");
                file.Write(Pathname);

                file.Write("\n{\n");

2.根據配置表的資訊讀取類的屬性並寫入

配置檔案的表頭如下所示:

其中[head]為屬性區域標識 下面每一行4個數據分別對應 屬性名 屬性型別 輸入長度 備註名 之間為\t隔開

注:配置表的資訊是由伺服器那邊生成 C#中不需要輸入長度資料 因此忽略掉第三列的資料 並把char替換成string

                // 從檔案讀取並顯示行,直到檔案的末尾 
                while ((line = sr.ReadLine()) != null)
                {
                    //讀取標頭檔案中的屬性生成第一個類指令碼
                    if (line == "[head]")
                    {
                        continue;
                    }
                    else if (line == "")
                    {
                        break;
                    }
                    string[] vs = line.Split('\t');

                    //將char型別並且長度大於1的資料型別改成string
                    if(vs[1]=="char" && int.Parse(vs[2]) > 1)
                    {
                        vs[1] = "string";
                    }
                    //定義的兩個List<String>變數 用來儲存屬性型別和屬性名 方便以後獲取
                    Types.Add(vs[1]);
                    PropertyName.Add(vs[0]);
                    //將屬性設定為public但是readonly 只讀但是可以訪問
                    file.Write("\tpublic readonly " + vs[1]+" "+vs[0]+";//"+vs[3]);
                    file.Write("\n");
                }
                file.Write("\n\t");

這個時候我們的C#類已經可以完成到如下效果:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Item
{
	public readonly int id;//id
	public readonly string name;//名字
	public readonly string des;//描述
	public readonly string des_extra;//額外描述
	public readonly string des_exchange;//兌換描述
	public readonly string des_produce;//產出描述
	public readonly int type;//型別
	public readonly int quality;//品質
	public readonly int sex;//性別
	public readonly int job;//職業
	public readonly int kingdom;//陣營
	public readonly int level;//使用等級
	public readonly int out_value;//出售價格
	public readonly int overlay;//疊加上限
	public readonly int flag;//標誌位[NL]
	public readonly int expire_type;//過期型別
	public readonly int expire_param;//過期引數
	public readonly int open_gold;//開啟所需元寶
	public readonly string effect;//作用效果
	public readonly int auction_type;//寄售型別
	public readonly string small_icon;//40圖示
	public readonly string large_icon;//56icon
}

此時,我們還需要加入建構函式,回到之前的程式碼繼續 

                //生成類的建構函式
                file.Write("public "+ Pathname +"(");
                //遍歷剛剛儲存的屬性名和屬性型別陣列 寫入對應的函式引數
                for(int i = 0; i < Types.Count; i++)
                {
                    file.Write(Types[i] + " " + PropertyName[i]);
                    if(i< Types.Count - 1)
                    {
                        file.Write(",");
                    }
                    if (i!=0 && i % 5 == 0)
                    {
                        file.Write("\n\t\t\t");
                    }
                }
                file.Write(")\n\t{");
                //再次遍歷寫入函式的方法
                foreach(string temp in PropertyName)
                {
                    file.Write("\n\t\t");
                    file.Write("this." + temp + " = " + temp+";");
                }
                file.Write("\n\t}");

                file.Write("\n}");
                //關閉檔案
                file.Close();
                //釋放物件
                file.Dispose();

完成後。再次生成看一下。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Item
{
	public readonly int id;//id
	public readonly string name;//名字
	public readonly string des;//描述
	public readonly string des_extra;//額外描述
	public readonly string des_exchange;//兌換描述
	public readonly string des_produce;//產出描述
	public readonly int type;//型別
	public readonly int quality;//品質
	public readonly int sex;//性別
	public readonly int job;//職業
	public readonly int kingdom;//陣營
	public readonly int level;//使用等級
	public readonly int out_value;//出售價格
	public readonly int overlay;//疊加上限
	public readonly int flag;//標誌位[NL]
	public readonly int expire_type;//過期型別
	public readonly int expire_param;//過期引數
	public readonly int open_gold;//開啟所需元寶
	public readonly string effect;//作用效果
	public readonly int auction_type;//寄售型別
	public readonly string small_icon;//40圖示
	public readonly string large_icon;//56icon

	public Item(int id,string name,string des,string des_extra,string des_exchange,string des_produce,
			int type,int quality,int sex,int job,int kingdom,
			int level,int out_value,int overlay,int flag,int expire_type,
			int expire_param,int open_gold,string effect,int auction_type,string small_icon,
			string large_icon)
	{
		this.id = id;
		this.name = name;
		this.des = des;
		this.des_extra = des_extra;
		this.des_exchange = des_exchange;
		this.des_produce = des_produce;
		this.type = type;
		this.quality = quality;
		this.sex = sex;
		this.job = job;
		this.kingdom = kingdom;
		this.level = level;
		this.out_value = out_value;
		this.overlay = overlay;
		this.flag = flag;
		this.expire_type = expire_type;
		this.expire_param = expire_param;
		this.open_gold = open_gold;
		this.effect = effect;
		this.auction_type = auction_type;
		this.small_icon = small_icon;
		this.large_icon = large_icon;
	}
}

一個擁有配置檔案屬性的C#的類就完成了!

但是光生成的類還不夠 需要擁有對應的指令碼來呼叫這個類並賦值使用。

之後會介紹如何自動生成相應的指令碼 來使用該類進行新增和呼叫資料。