0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity】ファイルとそのメタファイルをなるべく安全に移動したい

Last updated at Posted at 2024-06-28

スクリプトでファイルと、そのメタファイルを
別のフォルダに移動したい場合は
少し苦戦します。

System.IO.File.Move で移動した場合は
ファイルを先に移動した場合は
メタファイルが移動前に消滅するリスクがありますし
メタファイルを先に移動した場合は
ファイルの移動前にメタファイルが消滅するリスクがあります。

そこで Unity でファイルを移動したい場合は
AssetDatabase.MoveAsset を使用するのが一般的です。

しかしながらこの機能は
個人的に安定しない印象があります。

実行する度に AssetDatabase を更新したとしても
少し遅延させないと安定しない現象が発生しました。

そこで System.IO.File.Move を使用したとしても
安全にファイルと、そのメタファイルを移動できないかと思い
実践する事にしました。

ここではその成果を
報告したいと思います。


使用するソースコード

ファイルを安全に移動するメソッド
private void MyMoveFile(string rootFile, string targetFile)
{
    if (rootFile.StartsWith("Assets"))
    {
        rootFile = UnityEngine.Application.dataPath + rootFile.Substring(6);
    }
    if (targetFile.StartsWith("Assets"))
    {
        targetFile = UnityEngine.Application.dataPath + targetFile.Substring(6);
    }
    if (!System.IO.File.Exists(rootFile))
    {
        return;
    }
    if (System.IO.File.Exists(targetFile))
    {
        System.IO.File.Delete(targetFile);
    }
    if (System.IO.File.Exists(rootFile + ".meta"))
    {
        if (System.IO.File.Exists(targetFile + ".meta"))
        {
            System.IO.File.Delete(targetFile + ".meta");
        }
        System.IO.File.Copy(rootFile, targetFile);
        TryFileMove(rootFile + ".meta", targetFile + ".meta");
        System.IO.File.Delete(rootFile);
        if(System.IO.File.Exists(rootFile + ".meta")) //自動で生成された場合に警告を出さないための if 文
        {
            try
            {
                System.IO.File.Delete(rootFile + ".meta"); //自動で削除される可能性があるため try-catch 必須
            }
            catch
            {
            }
        }
    }
    else
    {
        System.IO.File.Move(rootFile, targetFile);
    }
}

private void TryFileMove(string rootFileMeta, string targetFileMeta)
{
    try
    {
        System.IO.File.Move(rootFileMeta, targetFileMeta);
    }
    catch
    {
        System.IO.File.Delete(targetFileMeta);
        TryFileMove(rootFileMeta, targetFileMeta);
    }
}

この方式では
メタファイルが存在する場合は
ファイルを先にコピーしています。

するとメタファイルが
勝手に生成されるリスクがありますので
TryFileMove メソッドで
メタファイルの移動に失敗した場合は
削除して再度移動を実行しています。

この方式ならば
meta ファイルが勝手に生成されても
安全に meta ファイルを移動する事ができます。

MyMoveFile に入れるパスは
Assets から始まっていてもかまいません。

現時点では
移動先に既にファイルが存在する場合は削除しています。
ファイル名を変えて保存する等の仕組みが必要ならば
ご自身で実装して下さい。

メタファイルが存在しない場合という if 文は
ドットから始まるファイル名等で必要になります。
それらのファイルはメタファイルが存在しないからです。

MyMoveFile(string rootFile, string targetFile)
メソッドを実行して使用します。

rootFile と targetFile は
メタファイルでない方のパスを入れて下さい。

"Assets/Move.cs" と
"Assets/Move.cs.meta" があるならば
前者のみを入れる事になります。


まとめ

以上ファイルと、そのメタファイルを
なるべく安全に移動する仕組みを紹介しました。

個人的に AssetDatabase.MoveAsset が
安定しなかったため記事にする事にしました。

AssetDatabase.MoveAsset が安定している人は
AssetDatabase.MoveAsset を使用して下さい。

この記事を見て
ファイルの移動処理の実装にかかる
無駄な時間を省く事が出来る人が現れたならば
非常に嬉しいです。

皆さんの開発の助けになれますように
閲覧ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?