AndroidでStreamingAssetsからファイルをコピーする

2019年3月29日

Unity で、サイズの大き目のファイルをアプリケーション内に含めておきたい場合には、StreamingAssets を使うことになります。
よくあるのは、アプリケーションサイズを落とす目的で最終的にはサーバにファイルは置いておきたいんだけど、まだサーバは用意できないからとりあえずローカルでやろうぜ、ってときに使いたくなります。私は使いたくなりました。

スポンサーリンク

環境

  • Unity 5.1
  • Android 5.0 Lollipop

ただ、Android で StreamingAssets を使うと、root を取らないと参照できないディレクトリにファイルが格納されてしまいます。
これは仕方ないので、アプリケーションから見える位置にファイルをコピーすることになります。

コルーチンでの読み出し

ここでよく使われる方法は、コルーチンで読み出し処理を行う方法です。

IEnumerator initializeFileCopy ()
{
    // StreamingAssets内のパスを指定する.
    string path = Application.streamingAssetsPath + "/MyData/initializeFile";
    
    // StreamingAssets内のファイルを読み出す.
    WWW www = new WWW(path);
    yield return www;
    
    // コピー先のパスを指定する.
    string toPath = Application.persistentDataPath + "/MyData/initializeFile";
    
    // コピー.
    File.WriteAllBytes(toPath, www.bytes);
} 

コルーチンが使えない場合には

初期化のタイミングで必要なファイルがあったりするとコルーチンは使えません。
これだとファイルのコピーが非同期処理になるので、コピーしたいファイルを Awake() や Start() 内で参照したい場合に困ってしまいます。

そこで、以下のようにします。

void initializeFileCopy ()
{
    // StreamingAssets内のパスを指定する.
    string path = Application.streamingAssetsPath + "/MyData/initializeFile";
    
    // StreamingAssets内のファイルを読み出す.
    WWW www = new WWW(path);
    while (!www.isDone)
    {
        // NOP.
    }
    
    // コピー先のパスを指定する.
    string toPath = Application.persistentDataPath + "/MyData/initializeFile";
    
    // コピー.
    File.WriteAllBytes(toPath, www.bytes);
} 

やっていることは yield と同じような感じですが、これは処理が終わるまでひたすら待ちます。
ファイルサイズが大きかったり、数が多かったりすると起動に時間がかかってしまう場合があるので、その辺は使用するデータと相談するしかないですが、本実装でこんなことはしないと思うのでサーバが使えるようになるまで我慢します。
ということで、この方法で StreamingAssets からデータをコピーすることができます。
正攻法ではない気がしますが。。。

おしまい。

スポンサーリンク