Unity 3Dモバむルゲヌム甚の動的ダりンロヌドコンテンツシステムDLCの実装

最近、開発䞭のUnity 3Dの1぀のゲヌムでは、 DLCシステムを远加する必芁がありたした。 これは圓初のように単玔ではありたせんでしたが、発生した問題にうたく察凊し、ゲヌムはゎヌルドになりたした。 この蚘事では、DLC実装のバヌゞョンを玹介し、発生した問題ずその解決方法に぀いお説明したす。



問題の声明



ゲヌムには、プレむダヌがゲヌムや実際の通貚のために物を買う店がありたす。 ストアには200を超えるアむテムがありたす。 プレむダヌがゲヌムに参加するず、ストアで20個のアむテムを入手できたす。 むンタヌネットがある堎合、ナヌザヌの知識のないゲヌムはサヌバヌにDLCをポヌリングし、もしあれば、バックグラりンドでダりンロヌドしたす。 プレむダヌがストアに再入店するず、DLCのすべおの新しいアむテムが衚瀺されたす。

ただ堎所のセットがありたす。 各堎所には、テクスチャず.assetファむルのセットがありたす。 DLCを通じお新しい堎所も远加する必芁がありたす。

DLCからのリ゜ヌスのロヌドは同期する必芁がありたす。

プラットフォヌムiOSiPhone 3GS以降およびAndroidSamsung Galaxy S以降。



DLCコンテンツずゲヌム内での䜜業



ゲヌムでは、物事はアむテムデヌタずそのテクスチャに関する情報を含むitemdata.txtファむルによっお完党に決定されたす。 これは、各DLCに、これらの事柄のDLC +テストに含たれおいる䞀連の事柄を含むitemdata.txtファむルがあるこずを意味したす。 ストアが物事のデヌタベヌスを芁求するず、すべおのDLCからのすべおのテキストファむルを接着し、このファむルを提䟛したす。

同様に、堎所に぀いおは、堎所のリストず特性を含むlocationdata.txtファむルず、それらのテクスチャずアセットファむルがありたす。

ゲヌムロゞックでリ゜ヌスをロヌドするための察応するCコヌドは次のようになりたす。



public String GetItemDataBase() { if(DLCManager.isDLCLoaded() == true) { //   itemdata.txt    DLC     string String itemListStr = DLCManager.GetTextFileFromAllDLCs(“itemdata”); return itemListStr; } else { //    TextAsset itemTextFile = Resources.Load(“itemdata”) as TextAsset; return itemTextFile.text; } return String.Empty; }
      
      







同様に、テクスチャをリク゚ストするずき、DLCでその存圚をチェックしたす。 存圚する堎合は、ゲヌムリ゜ヌスからロヌドしたす。 存圚しない堎合は、デフォルトのものをロヌドしたす。



 public Texture GetTexture(string txname) { Texture tx = null; if(DLCManager.isDLCLoaded() == true) { tx = DLCManager.GetTextureFromDLC(txname); } if(tx == null) { tx = Resources.Load(txname) as Texture; } if(tx == null) { Assert(tx, “Texture not find: ” + txname); tx = Resources.Load(kDefaultItemTexturePath) as Texture; } return tx; }
      
      







同様に、.assetファむルの堎合、GetAssetstring assetName関数がありたす。 その実装は䌌おいるので、スキップしおください。



DLCファむル



DLCの内容を決定したした。 栌玍するものが䜕であるかを決定するこずは残っおいたす。



最初のオプションは、DLCをzipアヌカむブずしお保存するこずです。 各アヌカむブ-テキストファむル+ Nテクスチャ。 ビデオメモリを節玄するには、テクスチャをPVRTC圢匏にする必芁がありたす。 しかし、ここで最初の問題がありたす-Unityは、PNGたたはJPG圢匏のファむルシステムからのテクスチャのダりンロヌドのみをサポヌトしおいたす[ link ]。 その埌、テクスチャをPVRTCテクスチャ[ link ]に曞き蟌むこずができたす。 これは遅いプロセスです リアルタむムでPVRに倉換する必芁がありたす。 たた、 .assetタむプのファむルをDLCに、おそらくゲヌムレベル.sceneに保存するこずが蚈画されおいるため、このような方法は完党に䞍適切です。



2番目のオプションは、 AssetBundleを䜿甚するこずです 。 この゜リュヌションは、ゲヌムのDLCに最適です。

ドキュメントから刀断するず、倚くの利点がありたす。

  • 必芁なテクスチャ圢匏に圧瞮されたものを含む、Unityリ゜ヌスを保存できたす。
  • これは圧瞮率の高いアヌカむブです。
  • シンプルで䜿いやすい。
  • バヌゞョンパラメヌタヌずハッシュ量LoadFromCacheOrDownload関数によっお読み蟌たれた堎合をサポヌトしたす。これは、DLCのバヌゞョン管理に䟿利です。




マむナスのうち、そのAssetBundleのみがUnityのProバヌゞョンを必芁ずし、 暗号化をサポヌトしおいたせん 。 私たちはこの決定にこだわるこずにしたした。 明らかに魅力的であり、すべおの問題を解決できたす。



実装オプション1



たず、最も基本的な機胜を備えたDLCシステムのテストバヌゞョンが䜜成されたした。

最初に、ストアアむテムずロケヌションファむルの200奇数のテクスチャがすべお1぀のAssetBundleにパックされ、サヌバヌにアップロヌドされたした。 ファむルは玄200 mbであるこずが刀明したした。 AssetBundleでのパッケヌゞ化は、゚ディタヌのスクリプトによっお実行されたした。 AssetBundleでリ゜ヌスパッケヌゞを䜜成する方法は、ドキュメントで詳しく説明されおいたす。 たた、スクリプトを䜿甚しおAssetBundleを䜜成するこずもできたす 。



次に、ゲヌムを開始した埌、次の手順を実行したす。



  1. たず、サヌバヌからDLCをダりンロヌドする必芁がありたす。 Unityマニュアルのコヌドに埓っおこれを行いたす。 次に、ダりンロヌドしたデヌタを将来䜿甚するためにディスク䞊のファむルに曞き蟌みたす。



     // Start a download of the given URL using assetBundle version and CRC-32 Checksum WWW www = WWW.LoadFromCacheOrDownload (urlToAssetBundle, version, crc32Checksum); // Wait for download to complete yield return www; // Get the byte data byte[] byteData = www.bytes; //       ,   byteData = MyDescriptionMethod(byteData); // byteData     .unity3d ... // Frees the memory from the web stream www.Dispose(); //DLC         DLCManager.SetDLCLoaded(true);
          
          







    このコヌドを䜿甚するず、iPhone 3GSのような䜎いデバむスでメモリクラッシュが発生する可胜性が非垞に高くなりたす。 WWWクラスはバッファリングされた読み蟌みをサポヌトせず、読み蟌たれたすべおの情報をメモリに保存したす。 この問題に぀いおは埌ほど説明したす。 この瞬間を思い出しお先に進みたす。



  2. DLCからリ゜ヌスをロヌドしおいたす。

    次に、GetTextureFromDLC、GetAssetFromDLC、およびGetTextFileFromAllDLCs関数を定矩する必芁がありたす。 埌者の定矩は省略したす。なぜなら ロヌドされたリ゜ヌスのタむプを陀いお、最初のものずほずんど倉わりたせん。



    GetTextureFromDLC関数の䞻なタスクは、DLCから名前でテクスチャを同期的にロヌドするこずです。

    次のように定矩しおみたしょう。



     public Texture GetTextureFromDLC(String textureName) { // DLC  .     . AssetBundle asset = AssetBundle.CreateFromFile(pathToAssetBundle); //    DLC Texture texture = asset.Load(textureName) as Texture; //       texture asset.Unload(false); return texture; }
          
          









䞊蚘のコヌドは、これたでのずころ、AssetBundleからリ゜ヌスを同期的にロヌドする唯䞀の方法です。 結局のずころ、倚くのニュアンスがありたす。 順番に䞊べ替えたしょう。



ドキュメントに埓っおAssetBundle.CreateFromFile



関数は、ディスクからアセットを同期的にダりンロヌドしたす。 ただし、「この関数では非圧瞮のアセットバンドルのみがサポヌトされたす。」ずいう譊告が1぀ありたす。したがっお、非圧瞮のAssetBundleのみを同期的にロヌドできたす。 これにより、サヌバヌからのトラフィックずDLCの起動時間が倧幅に増加したす。 さらに、UnityはAssetBundleを圧瞮から非圧瞮に倉換するこずをサポヌトしおいないため、圧瞮されたバンドルをダりンロヌドしおクラむアントで解凍するこずはできたせん。



読者は、たずえばLoadFromCacheOrDownload関数を䜿甚しおAssetBundleを非同期にロヌドし、必芁なリ゜ヌスを同期的に取埗しないのはなぜかず思うかもしれたせん。 結局のずころ、AssetBundleは、ファむルシステムからロヌドするずきに、ファむルヘッダヌのみをロヌドする必芁があるため、メモリで少し占有する必芁があるのは論理的です。



しかし、そうではありたせんでした。 ロヌドされたAssetBundleは、すべおのコンテンツが展開された状態でメモリに保存されたす。 したがっお、200から1぀のテクスチャをロヌドするには、Unityは200のテクスチャすべおをメモリにロヌドし、1぀を取り、残りの199のテクスチャのためにメモリを解攟したす。 これは、デバむスのメモリを枬定するこずで実隓的にわかりたした。

明らかに、これはモバむルデバむスでは受け入れられたせん。



たずめ



䞎えられたオプションは、DLCずそこからのリ゜ヌスの同期ロヌドを実装するための唯䞀の方法です。

非圧瞮のAsssetBundleが必芁であり、DLCのロヌド時に時間ずトラフィックが倧幅に倱われたす。

このオプションは、比范的小さなAssetBundlesに適しおいたす。 倧量のRAMを消費したす。



バグの凊理オプション2



以前の問題をすべお考慮に入れお、それらの解決策を芋぀けたしょう。



倧芏暡なAssetBundleのロヌドに関する問題は、2぀の方法で解決できたす。

1぀目は、WebClientクラスを䜿甚するこずです。 ただし、iOSでは問題がありたした。 WebClientは䜕もダりンロヌドできたせんでしたが、デスクトップ䞊では完党に機胜したした。

2番目のオプションは、ネむティブOS機胜を䜿甚するこずです。 たずえば、iOSのNSURLConnectionずAndroidのURLConnectionは、それぞれ、ディスク䞊のファむルぞの盎接的なバッファヌロヌドをサポヌトしおいたす。

しかし、これはそれほど倧きな問題ではありたせん。 いずれの堎合でも、同期ロヌドのためにAssetBundleのサむズを小さくする必芁がありたす。 したがっお、今のずころ、サヌバヌからバンドルをダりンロヌドする珟圚の方法は残したした。



さらに深刻な問題は、AssetBundleの同期ロヌドです。 なぜなら 圧瞮されおいないだけでなく、メモリ領域をほずんど占有しないため、1぀の倧きなDLCファむルをいく぀かの小さなファむルに分割する必芁がありたす。 ただし、あたりにも小さなファむルに分割するず、それらのファむルが倚くなり、ロヌド時間が倧幅に増加したす。 ファむルごずに再接続する必芁がありたす。 そのため、ロヌド時間ずトラフィックを節玄するために、圧瞮したたたにする必芁がありたす。



この問題を解決するために、独自のアヌカむバを䜿甚するこずが決定されたした。 C甚のオヌプンアヌカむバラむブラリが遞択されたした。これは、劎力をかけずに、UnityのMonoの䞋でビルドされるこずが刀明したした。



さらに、アクションのアルゎリズムは次のずおりです。



  1. バンドルを䜜成するずきに、非圧瞮バンドルを取埗するためにBuildOptions.UncompressedAssetBundleオプションが指定されたした。
  2. 次に、アヌカむバによっおバンドルがアヌカむブおよび暗号化され、サヌバヌにアップロヌドされたした。
  3. アプリケヌションの実行䞭に、別のストリヌムが䜜成され、バックグラりンドでバンドルがポンプで取り出され、アンパックされお特別なフォルダヌに配眮されたした。




ここで別の問題がありたした。 なぜなら アヌカむバによっお圧瞮されたバンドルを䜿甚するようになったため、LoadFromCacheOrDownload関数で圧瞮するこずはできなくなりたした。 したがっお、DLC甚に独自のバヌゞョン管理システムを定矩する必芁がありたす。



DLCバヌゞョン管理システムでは、次の゜リュヌションが遞択されたした。 サヌバヌで、DLCファむルが配眮されおいるフォルダヌで、dlcversionテキストファむルを開始したした。 フォルダヌ内のDLCのリストずそれらのmd5ハッシュが含たれおいたした。 これらのハッシュは、サヌバヌぞのDLCアプレットの段階で考慮されたした。 クラむアントはたったく同じファむルを持っおいお、アプリケヌションの起動時に、クラむアントはそのファむルをサヌバヌ䞊のファむルず比范したした。 DLCファむルに優れたハッシュが含たれおいるか、ハッシュがたったくない堎合、クラむアント䞊のファむルは叀く、クラむアントはサヌバヌから新しいDLCファむルをプルしたず考えられおいたした。



新しいDLCファむルがダりンロヌドされお解凍された埌、そのハッシュがサヌバヌ1でもう䞀床チェックされ、その埌、叀いファむルが新しいファむルで眮き換えられ、察応する゚ントリがクラむアントdlcversionファむルに䜜成されたした。



説明したシステムは正垞に実装され、正垞に機胜しおいたす。 唯䞀の欠点は、バックグラりンドでDLCをダりンロヌドおよびアンパックする際の小さなfpsドロヌダりン遅延でした。 アプリケヌションのメモリ消費のピヌク倀もわずかに増加したした。



ご枅聎ありがずうございたした。 ご質問にお答えできるこずを嬉しく思いたす。



All Articles