この記事でのバージョン
Unity 2017.4.0f1
はじめに
Unityではアセット(ファイル)をコピーしたいと思った時に簡単に実装出来る方法が二つあります。
一つはUnityの機能であるAssetDatabase.CopyAsset、もう一つはC#(.NET)の機能であるFile.Copyです。
//using UnityEditor;が必要 AssetDatabase.CopyAsset("Assets/Resources/Corgi.png", "Assets/Resources/Corgi2.png");
//using System.IO;が必要 File.Copy("Assets/Resources/Corgi.png", "Assets/Resources/Corgi2.png");
二つも実装方法があると、どっちを使ったら良いのか気になりますよね?
という事で今回はAssetDatabase.CopyAssetとFile.Copyの比較です!
先に結論だけ言ってしまうと、基本的にAssetDatabase.CopyAssetを使えばOKです。
設定(.meta)のコピー
File.Copyのコピーされるのファイル本体だけで、.metaファイルはコピーされません。
これは、画像等の設定もコピーされないという事でもあります。
それに対してAssetDatabase.CopyAssetは.metaファイルもコピーされるので、設定もコピー可能です。
逆に言うと、
.metaファイル(設定)をコピーしたくない場合にはFile.Copyの方が適してるという事でもあります。
コピー後のリフレッシュ
上記の通りFile.Copyは.metaはコピーしないので、
ファイルコピー直後はProjectウィンドウで見えません。
File.Copy("Assets/Resources/Corgi.png", "Assets/Resources/CorgiCopy.png");
なので、コピー後に.metaファイルを新規作成するために
AssetDatabase.RefreshまたはAssetDatabase.ImportAssetをする必要があります。
//ファイルをコピー File.Copy("Assets/Resources/Corgi.png", "Assets/Resources/CorgiCopy.png"); //リフレッシュして.metaファイルを作成 AssetDatabase.Refresh(); //インポートでも可 //AssetDatabase.ImportAsset("Assets/Resources/CorgiCopy.png");
それに対して、AssetDatabase.CopyAssetはRefreshやImportAssetの必要がありません。
//アセットをコピー(.metaファイルもコピーされる) AssetDatabase.CopyAsset("Assets/Resources/Corgi.png", "Assets/Resources/Corgi2.png");
コピー失敗時の挙動
コピー元のファイルが無かったり、コピー先のディレクトリが無い等の失敗時に
File.Copyはエラーが出ますが、
AssetDatabase.CopyAssetはエラーが出ず、変わりに返り値にfalseが返されます。
if (AssetDatabase.CopyAsset("Assets/Resources/Shiba.png", "Assets/Resources/CorgiCopy.png")) { //コピー成功 } else{ //コピー失敗 }
上書きコピー
コピー先のファイルが既に存在する場合、File.Copyは第三引数をtrueにしていれば上書き出来ます。
(デフォルトはfalse、falseの時は上書きせずにエラーが出る)
File.Copy("Assets/Resources/Corgi.png", "Assets/Resources/CorgiCopy.png", overwrite:true);
それに対して、AssetDatabase.CopyAssetは常に上書きします。
また、AssetDatabase.CopyAssetにはそもそも上書きという機能がなく、
上書き出来てしまうのはバグで、上書き時にはデータベースに不具合が生じていました。
AssetDatabase クラスには CopyAsset 関数がありますが、上書きするという機能はありません。厳密に言うと上書きできてしまうのですが、Unity のデータベースに不具合が生じます。
しかし、今(Unity 2017.4.0)は問題なく上書き出来るようになりました。
ただし、上書き可能に仕様が変わったのかどうかまでは分かりません。
ディレクトリのコピー
File.Copyはディレクトリをコピーしようとするとエラーが出ますが、
//エラー!(Assets/Resourcesがあって、Assets/Resources2がなくても) File.Copy("Assets/Resources", "Assets/Resources2");
AssetDatabase.CopyAssetはディレクトリのコピーも可能です。
AssetDatabase.CopyAsset("Assets/Resources", "Assets/Resources2");
ちなみにDirectoryというクラスはありますが、Directory.Copyというメソッドはありません。
おわりに
最後にAssetDatabase.CopyAsset と File.Copyの違いを表でまとめてみました。
項目 | AssetDatabase.CopyAsset | File.Copy |
---|---|---|
設定(.meta)のコピー | される | されない |
コピー後のリフレッシュ | 不必要 | 必要 |
コピー失敗時の挙動 | falseが返る | エラーが出る |
上書きコピー | 常に上書き | 上書きするか設定可能 |
ディレクトリのコピー | 出来る | 出来ない |
こうして見ると同じような機能でも結構違いがあるので、注意が必要ですね。