在作對話系統編譯器(可以在Unity內執行的吉里吉里)時,整理出的Unity讀取外部變數的方法
前言
隨著寫過的專案越來越多,各種稀奇古怪的需求就會冒出來。最近寫的一支角色對話編譯器就是個不錯的例子。
該編譯器的流程如下:
在測試時當然是直接把腳本字串打在code的string
內直接丟進編譯器內,而之後寫的專案則是已經有人弄了個腳本管理系統,能直接抓到腳本的字串。
而新的專案沒有這些方便的工具所以就自己處理吧!
試錯
一開始就是用最傳統的System.IO
大法,先使用Application.dataPath
抓到專案的路徑,然後直接上網Copy讀取檔案的程式碼
using (StreamReader sr = new StreamReader(path+fileName))
{
String line = sr.ReadToEnd();
Console.WriteLine(line);
}
唷西,按下play,居然出人意料的一點問題都沒有。於是該寫的寫該call的call,把東西弄完做輸出測試時,萬惡的NullReferenceException
出現了!!
什麼?東西讀不出來?明明在編輯器裡面一點問題都沒有啊?
沒關係,等我谷哥出來你就死定了。
解答
在谷哥的幫忙下,得知了路徑本身是沒有問題的Application.dataPath
會指向專案路徑,或是Build後的安裝路徑,但問題出在Unity將專案Build出來後會將Assets
內的東西序列化、壓縮、打包,所以在遊戲的安裝路徑內是找不到檔案的,除非你打算在專案輸出後再用其它方式把檔案放進去(不過如果你是Android、iOS專案可能就無解了)。
同時谷哥也提到了Unity提供的另外兩種方式︰
Resources.Load
Application.streamingAssetsPath
Resources.Load
查到Resources.Load
的時候其實有點疑惑,Resources.Load
不是只能讀Unity提供的檔案格式嗎?文字檔要轉型成什麼?Resources.Load<string>(path)
?
上官網查後得知Unity提供了TextAsset
格式用以Load文字文件,但目前僅支援下列副檔名
.txt
.html
.htm
.xml
.bytes
.json
.csv
.yaml
.fnt
真相大白後就能簡單的把東西讀出來了
var str = Resources.Load<TextAsset>(fileName).ToString();
//或是干脆連轉型都懶了
var str = Resources.Load(fileName).ToString();
Build出來測試也沒問題。
Application.streamingAssetsPath
另一個查到的方法是用Application.streamingAssetsPath
,與Resources.Load
很類似,要將檔案放到StreamAssets的系統保留資料夾內,但讀取時需要用WWW來讀取,在網上查到的讀取代碼如下
IEnumerator LoadXML()
{
string sPath= Application.streamingAssetsPath + "/Test.xml";
WWW www = new WWW(sPath);
yield return www;
_result = www.text;
}
讀取時還要開StartCoroutine
異步讀取,以目前的需求來說不太方便,因此先擱置吧,有機會再提。