C# Unity游戲開發——Excel中的數據是如何到游戲中的 (四)2018.4.3更新


 本帖是延續的:C# Unity游戲開發——Excel中的數據是如何到游戲中的 (三)

 

前言

 

最近項目不算太忙,終於有時間更新博客了。關於數據處理這個主題前面的(一)(二)(三)基本上算是一個完整的靜態數據處理方案了。

不過前幾篇發布的時候是2015年,比較早了,隨着這幾年技術不斷積累和進步,其實已經有更好的方案來處理數據了,不過對於前端存儲的那幾個M的數據,多點少點其實影響也不大。

但是也不能就這樣算了,畢竟技術的變化日新月異,還是要保持持續學習的心態。

 

雖然簡單但卻不易忽視

 

對於游戲中靜態數據的處理,單純的對於整個程序項目來說其實只是很小的一部分。寫個讀寫工具,打個包,壓個縮,加個密其實對於很

多程序來說也不是難事。但是,我又要說但是了。但是,根據博主的個人經驗來說,數據對於游戲的業務邏輯是非常底層的“邏輯”,對於

后期的開發起到了一個基礎的作用。主要體現在兩個方面:

1.業務邏輯角度的數據結構化。

  這點很關鍵,策划想要把自己大腦里的游戲玩法用數據表示出來,而這個表示過程其實是需要程序配合的,因為不可能每個策划

  都那么牛逼,然而現實情況也確實如此。因此,這部分要做的事就是,用數據抽象的思維把策划描述的游戲世界表示出來,最終

  體現就是“表格”。這些數據,其實就是游戲業務邏輯的“骨架”,后續的開發都是圍繞着數據來做的,或者說被數據“支配”的。

2.程序結構的設計。

  第一條說過了,“后續的開發都是圍繞着數據來做的”,那么這些數據的使用頻率必然會很高。那么,問題來了,如何設計這部分的程序結構會使開發效率和運行效率最優?單純的創建一個類,把所有數據查詢的方法都放里面?還是根據第一條抽象出來的“實體類”來組織數據,然后對數據做一些預處理,例如游戲運行先進行分類然后放到內存中等待使用?

  顯然,后者更加高效,這也“靜態數據處理雖然簡單,但是也不容忽視”的理由。

 

最新的方案

  

 前面也說了,技術是不斷在變化的,我們也需要快速適應。之前的方案確實用了很長時間,也沒什么問題。但是自己擼的代碼總有幾個疑問?這是最好的方案嗎?和最好的方案差距有多大?

帶着這幾個問題,在最近2年所做的項目中也對這方面做了一些工作:1,在最近的項目中使用了ScriptableObject的方式。2,開始了一個protobuf方式處理數據的開源項目。

說起來慚愧,其實結果影響並不算很大,下面把這部分總結一下。

 

方案一 : 使用Unity的ScriptableObject。

 

  做法就是每個表格生成的數據類都直接或者間接的繼承自ScriptableObject類,打包的時候直接把所有表數據都生成一個對應類型的.asset文件。然后建一個總的Map類來存放所有asset的引用,當然這個Map類也必須繼承自ScriptableObject,也生成對應的.asset文件。最終打包的時候,只打這個Map類的.asset文件,Unity會自動識別里面的依賴關系,將所有數據打包進bundle。

實體類Hero

using UnityEngine;
public class Hero : ScriptableObject
{
    public string name;
    public string level;
}

 

Map類

using UnityEngine;
using System.Collections.Generic;
public class Map : ScriptableObject
{
    public List<Hero> heroList = new List<Hero>();
}

 

最終在使用的時候也很方便:

                AssetBundle bundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/constance");
                Map m_Constance = bundle.LoadAsset("constance") as Map;

 

這種方式對Unity3D非常友好,使用起來也非常方便,但是缺點也是有的,下面來總結一下:

優點:

  可以和預制產生依賴,prefab如果依賴了asset打包的時候也會打進去,減少了查找操作。

  可以直接用Unity API操作asset。省去了一部分序列化反序列化代碼。

  可以直接用AssetBundle.LoadAsset() as Map;加載,省去了之前的反序列化代碼。

  在Unty中選中asset可以直接在Inpector中看到數據。

缺點:

  生成asset的時候會有大量的文件操作,速度慢。

 

還有兩個指標就是運行速度和存儲空間。由於影響不大,沒有做進一步測試。

存儲空間的話,我這里有個參考:6個Excel文件占用的pc上的磁盤空間是112k,最終打成AssetBundle是31k。

 

 方案二 : 使用protobuf

   

  這種做法主要是通過google提供的protobuf來序列化和反序列化數據,並且使用protoc生成目標語言的代碼。工作流程如下圖所示。

 

 

   把做法分成幾部分來說:

    操作1,讀取excel數據描述信息,通過excel數據描述信息生成.proto文件。

    操作2,使用protoc命令行生成本地代碼,也就是你制作工具使用的語言代碼。

    操作3,創建本地代碼的類的實例。

    操作4,讀取excel數據,並且將內容賦值給“操作3”創建的實例,最終使用protobuf API序列化。

    操作5,生成目標平台的代碼。

  最終生成的二進制文件(.bytes)和目標代碼會和程序一同發布,使用生成的目標代碼解析生成的二進制數據。

  具體代碼就不貼出了,下面是本人對方案二開啟的一個開源項目,用的是java+netbean8.2,目前已經完成大部分內容。

  有興趣的同學可以看一下。我會一直更新。

  https://github.com/superbig/proto-packer

 

最后

 

  如果你在游戲開發的靜態數據處理方面還在猶豫,建議是:如果項目小可是試試ScriptableObject方式,應使用起來確實要方便一些。當然你也需要忍受數據導出時候的頻繁的IO操作(當然其實你也可以開發一個增量導出的工具)。

如果項目大,數據很多還是老老實實用protobuf,空間占用少,速度快。或者自己寫。

 

 

版權聲明:本文為博主原創文章,未經博主允許不得轉載。 http://www.cnblogs.com/fly-100/p/8707749.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM