AssetBundlesを使って.fbxモデルをネット上から回収

#文脈
UnityでWWWを使って画像・テキスト・動画ファイルを読み込む
http://qiita.com/gshirato/items/8fb10f768d0ba2c2e365
より

#ねらい
3Dモデルデータ.fbxファイルをプロジェクトに埋め込まない形で使いたい。

#環境
Unity5.6.1f1 Personal

#手法

- [ ] バイナリファイルから読み込み(検証中:http://qiita.com/gshirato/items/87586421de0ec37e46a6)

https://code.blender.org/2013/08/fbx-binary-file-format-specification (Blender Developers Blog)を参考予定

- [x] AssetBundlesを使う！

#AssetBundlesとは
https://docs.unity3d.com/ja/540/Manual/AssetBundlesIntro.html

アセットデータをネット上に置いておくことができる。

##なぜ

− アプリのサイズダウン
− データの追加が容易

例えばダウンロードコンテンツ。アプリストアにおいておくアプリの容量は制限があるため、アプリを導入後にDLコンテンツとして機能を追加する。

##何ができる
サッカーゲームに例えると
３Dモデル(選手)・テクスチャ(ボールの柄)・オーディオ(応援歌)・シーン(チャレンジモードなどでの新ステージ)などを追加できる。

##どのように

###失敗例
1. *fbxファイル*をクラウドに突っ込む
2. Unity上からBundleとして取り出そうとする。

今考えるとできなくて当たり前だよなと思わされるのですが、最初はここで延々とぐるぐる試行錯誤してました。

###成功

1. 使いたいAssetからAssetBundlesを作成する。
2. 出来上がったAssetBundlesをクラウドに置く。
3. `WWW.LoadFromCacheOrDownload()` などを活用してアセットを引き出す。

####1.使いたいAssetからAssetBundlesを作成する。

まずアセットバンドルのビルド(参考：https://docs.unity3d.com/ja/540/Manual/BuildingAssetBundles.html )をします。

1. `Assets/AssetBundles`フォルダを予め作っておく。
2. 下のコードを使って`Assets/Editor`フォルダ内にcsファイルを作る。(リンク内も参考)

3. アセットバンドル化したいAssetのInspector上のAssetLabelを見る。(一番下)
4. AssetBundleは`None`になっているはずなので`New...`から好きな名前をつける
`folder_name/asset_name`のように書くと階層的にファイルを作ることができる。
>この画像では、アセットが environment/desert という名前のアセットバンドルに追加されています。このアセットバンドルは、以前追加された他のアセットを含む場合もあります。アセットバンドルの名前は小文字のみで構成されます。大文字を使うと自動的に小文字に変換されます。名前中にフォワードスラッシュ（/）を使用することで効率良くフォルダーが作成され、画像のように、メニュー中にサブメニューが表示されます。　*-リンクより*

今回は`models/model`という名前を付けたとする。

Unityのメニューバー上に`Assets/Build AssetBundles`が現れる。のでクリックするとAssetBundlesフォルダ内にAssetBundles生成される。


```csharp:CreateAssetBundles.cs
using UnityEditor;

public class CreateAssetBundles
{
    [MenuItem ("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles ()
    {
        //BuildTargetはビルドするものに応じて変更する。
        BuildPipeline.BuildAssetBundles ("Assets/AssetBundles", BuildAssetBundleOptions.None, BuildTarget.WSAPlayer);
    }
}
```

####2. 出来上がったAssetBundlesをクラウドに置く。

#####の前に
- AssetBundles内にできたファイル

"AssetBundles"と名前の付いたファイルとそのmanifstファイルをAssetBundles内に発見。今回はAssetBundles名を`models/model`と階層的にしたためAssetsBundlesにはmodelsフォルダが存在し、その中にmodelファイルとそのmanifstファイルが存在。

manifestファイルはそれぞれ

```:AssetBundles.manifest
ManifestFileVersion:0
CRC: {10桁のint}
AssetBundleManifest:
  AssetBundleInfos:
    Info_0:
      Name: models/model
      Dependencies: {}
```

```:model.manifest
ManifestFileVersion:0
CRC: {10-digit number}
Heshes:略
HashAppended: 0
ClassTypes:
    略
Assets:
- Assets/Prefabs/model.fbx
Dependencies: []
```
AssetBundlesがmodels/modelを参照していることがわかります。

Unite Japan 2013での講演を見るとより理解が深まるかもしれません。(https://vimeopro.com/unity3djp/unite-japan-2013-for-the-public/video/64375290)

#####本題
クラウド上に置く

置きます

http://machin/AssetBundles/models/model
がパスだと仮定します。(`models`フォルダ内に`model`アセットバンドルファイル)

web.configで管理をしている人は

```xml
<mimeMap fileExtension="." mimeType="application/octet-stream" />
```

を追加しておく。参考(http://qiita.com/gshirato/items/7f783784cd5e6827fa0f)

####3. `WWW.LoadFromCacheOrDownload()` などを活用してアセットを引き出す。

参考：https://docs.unity3d.com/jp/540/Manual/DownloadingAssetBundles.html

```csharp:LoadBundleAssets
void Start()
{
//`AssetBundles`と名の付いたファイルではなく前の工程で名前を付けたファイルのパスを指す(models/model)
    string url = "http://machin/AssetBundles/models/model";
    StartCoroutine(DownloadAndCache("model.fbx", url, 0);
}

//assetNameはmodel.manifestのAssets欄にあるファイルから
//VersionはManigestFileVersionと同じでいいはず。

public IEnumerator Download(string assetName, string url, int version)
{
　　// Wait for the Caching system to be ready
   while (!Caching.ready)
       yield return null;
    using(WWW www = WWW.LoadFromCacheOrDownload(url, version))
    {
        yield return www;
        
        if (www.error != null)
        { 
           throw new Exception("Error: + www.error);
        }

        AssetBundle bundle = www. assetBundle;
        if(assetName == "")
        {
            Instantiate(bundle.mainAsset);
        }
        else
        {
            Instantiate(bundle.LoadAsset(assetName));
            bundle.Unload(false);
        }
    }//Disposeは勝手にやってくれるらしいです。
}
```

#結果
WWWを使ってfbxファイルを取り入れることに成功

#HoloLensアプリ開発記事一覧
http://qiita.com/gshirato/items/6c026f2c67dc332f829b から