Unity进阶技巧 - 从文件读取游戏数据
一、制作CSV文件
一般情況下,制作游戲數據會用到表格軟件,windows下常用Excel,而Mac下常用Numbers,而這兩種軟件都可以導出我們本例所需要的文件——CSV文件。
首先我們打開Numbers,新建一個文件,
?
然后輸入我們需要的內容,如下:
?
這就簡單的制作了一個裝備數據表,每件裝備我們假設它有5個屬性:
?
- id:裝備ID,具有唯一性
- name:裝備的名字
- level:裝備等級
- attack:裝備增加的攻擊
- def:裝備增加的防御
數據填寫完之后,我們就可以選擇文件->導出到->CSV…
?
然后在彈出的對話框,直接點擊下一步:
?
然后在接下來的對話框中,選擇文件名和保存路徑:
?
導出后,我們找到myTest.csv文件,打開可以看到:
?
我們可以看到我們剛剛制作的表格數據都被以文本的方式保存下來了,并且使用了“,”號來進行分割,而CSV的中文翻譯就是逗號分隔值。但是我們會發現一個問題,手機靚號賣號平臺為什么后面會多了那么多逗號呢?那是因為我們導出的時候沒有將空的單元格刪除掉
所以我們導出CSV文件是,記得要刪除掉那些空的單元格,如下圖:
?
刪除空單元格后的表格,
然后我們再導出一次,并打開導出的文件查看,就會發現那些多與的逗號沒有了。
?
二、讀取CSV文件
有了CSV文件后,下一步就是將它放入Unity中,并讓Unity讀取里面的數據,首先我們新建一個Unity工程,然后將我們剛剛創建的CSV文件放入Unity的資源目錄下,本例中我們選擇放入在*Asset->Res文件夾下面(Res文件夾需要大家自己創建)
?
然后我們新建一個名為CSV的腳本,打開進行編輯,輸入一下代碼:
?
首先,如果我們要使用Unity的讀取文件的方法,需要在開頭引入System.IO的命名空間,這樣編輯器才會識別讀取文件的一些方法。
然后我們還需要使用List類型的變量,所以還要引入System.Collections.Generic的命名空間
然后這個CSV類是我們自己定義的一個靜態類,不需要繼承MonoBehaviour類,所以我們把繼承MonoBehaviour類的語句刪除掉。
接著我們定義了csv和m_ArrayData兩個成員變量,第一個用來實現單例模式,第二個用來保存從文件讀取的內容。
然后使用單例模式來生產這個類的實例,以后需要使用這個類的方法我們就通過GetInstance來獲取這個類的實例。
接著我們在構造函數CSV()中,初始化m_ArrayData。
然后我們定義了loadFile方法,有兩個參數,第一個是路徑名,第二個是文件名,通過路徑名+文件名我們就可以指定我需要讀取的文件了。
接著看看loadFile這個方法里面到底做了什么事情?首先每次讀取文件前,我們清空一下m_ArrayData,以免數據沖突。
然后我們定義了一個StreamReader類型的變量sr,用他來保存文件讀取后的最原始的數據。
然后我們使用try{} catch{}語句,來捕獲程序異常,這個邏輯和if語句有點想,如果我們文件讀取不成功,就會運行catch里面的語句,在后他打印一句話來通知我文件沒有找到,在try{}里面使用OpenText方法來打開我們的myTest.csv文件
接著我們定義了一個line,用來臨時保存sr里面的每一行數據
然后使用一個while循環,把sr里面的數據按照一行來切割,全部放入m_ArrayData中
最后使用close和Dispose函數將sr進行關閉和銷毀。
寫完代碼,保存一下,然后我們在創建中新建一個空的GameObject,命名為FileController,并且為掛載一個新的腳本文件FileController,用來控制文件的讀取。
?
然后打開FileController腳本,輸入下面的代碼:
?
首先我們在Start函數中,通過CSV的實例調用loadFile方法來讀取我們的myTest里面的內容,loadFile方法有兩個參數,一個是路徑名,一個是文件名稱,關于路徑名的一些注意事項,會在后面的擴展閱讀里面介紹,這里只要理解我們通過路徑名+文件名就可以指定需要讀取的文件了
然后我通過for循環,將m_ArrayData里所有的內容打印在程序后臺中
寫完代碼,保存一下,然后回到Unity編輯器,運行游戲,可以在后臺打印中看到如下數據:
?
可以看到,現在我們已經可以讀取到文件里面的內容了,并且是可以分解每一行的內容分別是什么,但是這樣的解析程度還遠遠不夠,不能為我們所用,假設我們游戲中需要生成一件裝備布衣,我們需要通過文件獲
得布衣的每一個屬性,如布衣的等級,增加的防御值等屬性,我們就需要將每一個數據單獨提取出來,所以我
們需要可以指定獲得某一個單元格里面的數據才行,下面就來看看怎么實現
三、根據行數和列數來指定獲取數據
現在我們的m_ArrayData里面存放的是一行的數據,也就是說其實m_ArrayData[0]就是取我們第一行的數據
,m_ArrayData[1]就是取我們第二行的數據,那么接下來我們只需要再進行一下解析,將每一行的數據按照列
數來拆解,這樣我們就可以通過行數+列數來確定指定數據了,先直接上代碼:
?
由于這次我們需要將每一行的數據按照列數來拆解,那么m_ArrayData里面裝的元素就不再是string了,而是一個string數值,所以我們這邊需要修改m_ArrayData的類型為List<string[]>。
然后我們新增一個方法getString,它有兩個參數,row是行數,col是列數,方法返回指定行數和列數的數
據,數據類型是string。
同時我們還增加一個方法getInt,它也有兩個參數,row是行數,col是列數,方法返回指定行數和列數的數據,數據類型是int,所以最后調用了int.Parse方法將string轉換成int類型。
最后我們修改while循環中的講數據添加到m_ArrayData的語句,這里我們調用Split方法,將數據以 “,” 作為分隔符,切割數據。
寫完代碼,保存一下,然后我打開FileController腳本,修改代碼如下:
?
首先讀取文件的語句和之前一樣。
接著我們調用getString方法打印行數為1,列數為1的數據。
最后我們調用getInt方法打印行數為1,列數2的數據。
寫完代碼,保存一下,大家可以先思考一下,上面打印的兩個數據分別是上面內容,然后在運行游戲,檢查一下實際結果是否和你想象的一樣
?
擴展閱讀
前面我們提到過,關于文件路徑的存放位置,在本例中我們使用了Application.dataPath來指定路徑位置,關于路徑有4個類型:
Application.dataPath:該路徑指向我們Unity編輯器的Asset文件夾
Application.persistentDataPath:該路徑指向iOS和Android的沙盒路徑
Application.streamingAssetsPath:streamingAsset文件夾路徑,在任何平臺都可以通過這個路徑讀取到文件夾里的內容
Application.temporaryCachePath:臨時數據文件路徑
關于這4種路徑的詳細地址,大家可以試著在Unity里面用Debug.Log語句將其打印出來。
總結
以上是生活随笔為你收集整理的Unity进阶技巧 - 从文件读取游戏数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 总结:一款Loading动画的实现思路
- 下一篇: Unity3D游戏内存瘦身指南: UI优