UE4 アセットファイルのファイル操作の誤りにより発生する問題と対処法

今回は UE4 アセットファイルのファイル操作の誤りにより発生する問題と、その対処法を書こうと思います。

ちなみに、検証からの憶測が含まれていますので、間違いなどあればご指摘ください。

# ファイル操作は意外と危険！？
ファイル操作は Windows でも行う一般的な操作ですが、UE4 のアセットファイルのファイル操作では誤った操作を行うと、実は知らないうちに大問題に発展している可能性があります。（特に大人数が関わるような大規模開発では致命的にもなりかねません。）

ですので、どんな問題があるかは一度きちんと知っておく必要があるかと思います。

# アセットファイルが他のアセットファイルを参照する仕組み
その前に、まずはアセットファイルの参照の仕組みについて説明します。

UE4 のアセットファイルは、**自身が参照している他のアセットファイルへの参照情報（ファイルパス）を持っています。**

これは、UE4 の「リファレンスビューアー」を使えば視覚的に確認できます。
以下は、AnimStarterPack に含まれている SK_Mannequin をリファレンスビューアーで見たものです。
![AssetFile01.png](https://qiita-image-store.s3.amazonaws.com/0/43814/3f3c06a6-b659-df61-e18a-35dc6c2d729b.png)

吹き出しに書かれているものが、アセットファイルのファイルパスです。
SK_Mannequin を中心として、左は**「SK_Mannequin <Font color="red">を</font>参照しているアセット」**、右は**「SK_Mannequin <Font color="red">が</font>参照しているアセット」**に対して線で繋がっています。

このように、アセットファイル同士は参照する、または参照される関係になっています。

# ファイル操作の誤りにより発生する様々な問題
では、これを踏まえた上で「ファイル操作を間違えたらどのような問題が発生するのか？」を見ていきます。

ちなみに、ここで取り上げる以外にもまだまだ問題はありそうな気がします……。

## メッシュが表示されない！？
では、仮に **SK_Mannequin** をエクスプローラで **SK_Mannequin2** とリネームしてみます。

すると、どういうことになるでしょうか？
まずは、コンテンツブラウザーでの表示を見てみると、リネームしたはずの SK_Mannequin が残ってます。
![AssetFile02.png](https://qiita-image-store.s3.amazonaws.com/0/43814/c26eb5a4-d685-a19a-d383-c22a43afd4a6.png)

この時点では大丈夫そうに見えますが、念のためリファレンスビューアで確認してみます。
すると、きちんとリネーム後の名前になっていました。（紛らわしい……。）
![AssetFile05.png](https://qiita-image-store.s3.amazonaws.com/0/43814/1e172257-526e-d7be-b00c-f44084f9e5b5.png)


では、これを参照していた Showcase を開いてみます。
ちなみに、リネーム前に開くとこんな感じでマネキンが表示されます。
![AssetFile04.png](https://qiita-image-store.s3.amazonaws.com/0/43814/1286a82a-df91-eec4-e567-94038905ed9a.png)

これがリネーム後にどうなるかというと……
![AssetFile03.png](https://qiita-image-store.s3.amazonaws.com/0/43814/f1d86136-ccfd-a917-fc20-1781b25a9a44.png)

**なんと、いるはずのマネキンが一体も表示されていません！！**

それもそのはず。先程エクスプローラ上で SK_Mannequin を SK_Mannequin2 にリネームしましたが、それを参照しているアセットファイル（今回の場合は Showcase）に埋まっている参照情報は **SK_Mannequin** のままだからです。

Showcase をリファレンスビューアで見てみると、以下のように SK_Mannequin になっていました。
![AssetFile06.png](https://qiita-image-store.s3.amazonaws.com/0/43814/815bdafc-312b-27db-9b5f-c3c2e842853b.png)

また、「アウトプットログ」を確認すると、SK_Mannequin が読み込めなかった旨の警告が大量に出力されていることも確認できます。
![AssetFile12.png](https://qiita-image-store.s3.amazonaws.com/0/43814/d5beca40-c1d7-29fd-f5f8-bf61d91e63c3.png)


## クックが出来ない！？
先程の SK_Mannequin のリネームの場合、表示されなくなる問題はあるものの、クックを行っても警告が表示されるだけでクック自体は成功します。

**しかし、アセットファイルによってはそのクックすらも失敗してしまうことがあります。**

試しに今度は **UE4_Mannequin_Skeleton** をエクスプローラで **UE4_Mannequin_Skeleton2** にリネームしてクックしてみます。

**すると、何とクックに失敗してしまいます！！**

この原因となっているエラーログの一つがこれです。

```
MainFrameActions: Cooking (Windows): UE4Editor-Cmd: [2016.10.29-09.19.15:201][  0]LogInit:Display: LogBlueprint:Error: Compiler Error  UE4ASP_HeroTPP_AnimBlueprint  - The skeleton asset for this animation Blueprint is missing, so it cannot be compiled! from Source: /Game/AnimStarterPack/UE4ASP_HeroTPP_AnimBlueprint.UE4ASP_HeroTPP_AnimBlueprint
```

ここで表示されている **UE4ASP_HeroTPP_AnimBlueprint** は AnimStarterPack に含まれているアニメーション BP で、先程リネームした **UE4_Mannequin_Skeleton** を参照しているアセットファイルでもあります。 

アニメーション BP は作る際に必ずスケルトンを指定することになっていて、**スケルトンが存在しないという状態はありえません。**

そのため、クック中にエラーが発生したのではないか？と思われます。

全て調べたわけではないですが、今回みたいに**「存在しないことがありえないアセットファイル」**が存在しなかった場合は、今回と同様にエラーが発生してクックができないのではないか？と思われます。

ちなみに、このクックが出来ない問題はかなり厄介で、**実際にクックしてみないとクックに失敗するかどうかがわかりません。**

このため、

**「提出用のパッケージを作ろうと思ったときに初めてクックが出来ないことが発覚して、大パニック！！」**

といったことも十分考えられます。

## アセットファイルが開けない！？
先程の **UE4_Mannequin_Skeleton** のリネームで実はもう一つ問題が発生しています。それは何かというと、

**「UE4ASP_HeroTPP_AnimBlueprint　が開けない」**

です。

先ほど説明しましたが、**UE4ASP_HeroTPP_AnimBlueprint** にとって **UE4_Mannequin_Skeleton** はなくてはならないアセットファイルのため、これを参照していた UE4ASP_HeroTPP_AnimBlueprint が開けなくなっていると考えられます。

ちなみに、開こうとすると以下のようなダイアログが表示されてスケルトンの再選択を要求されます。
![AssetFile13.png](https://qiita-image-store.s3.amazonaws.com/0/43814/415c2579-ac48-8274-945a-4f217762b194.png)

このように回避策が用意されているアセットもありますが、全てのアセットでこのような回避策が用意されているかどうかはわからないので、もしかすると**「アセットファイルが開けなくなって復旧できなくなる」**なんてことも考えられます。

## リダイレクターを削除したら参照が切れた！？
UE4 の**「コンテンツブラウザー」**では、この参照切れへの対策としてアセットファイルを移動、もしくはリネームした場合に**「リダイレクター」**と呼ばれるアセットファイルを自動的に作る仕組みが入っています。[^1]

このリダイレクターには、**移動、もしくはリネームしたアセットファイルがどこにあるのか？**という情報が記録されていて、ファイル名はリネーム前のアセットファイルと同じ名前になっています。

ちなみに、リダイレクター経由で参照されている場合、リファレンスビューアーで見てみると以下のようになります。
![AssetFile11.png](https://qiita-image-store.s3.amazonaws.com/0/43814/bb79ce6a-b4e3-5833-33f1-ba46a39495d2.png)

このリダイレクターのお陰で、参照しているアセットファイルを書き換えることなく、
アセットファイルの移動やリネームが可能となっています。

ただし、リダイレクターが存在している限りはその名前が使えなくなりますので、できれば早い段階で消したいものです。

そのために必要なのが**「Fix up Redirectors in Folder」**です。
![AssetFile07.png](https://qiita-image-store.s3.amazonaws.com/0/43814/93122f99-10d6-f199-c139-71dec3efd7e7.png)

これを実行することで、リダイレクターを参照していたアセットファイルの参照情報をリネーム後のアセットファイル名に置き換え、リダイレクターそのものも削除します。

だったら、コンテンツブラウザーで移動、リネームすれば大丈夫だろう！！……と思われるかもしれませんが、**ここにも一つ問題があります。**
リダイレクターを削除する際、

**「アセットファイルの参照情報をリネーム後のアセットファイル名に置き換える」**

と言いましたが、そもそもこのアセットファイルの参照の仕組みがわかってない人が居た場合、ソースコントロールを有効にしている状態でリダイレクターを削除した際に**「他の人がチェックアウトしていた」**という理由で

**「チェックアウトできたファイルだけをソースコントロールでサーバーにアップする」**

と言った人が出てきます。

その場合、リダイレクターの削除で参照情報が更新されているにもかかわらず、アップされなかったアセットファイルは参照切れ扱いとなり、

**「リダイレクターを削除したら参照が切れた！？」**

といった問題に発展することになります。

# これらの問題に対処するためには……
## 事前に防ぐ方法
どうすれば、この問題を事前に防げるのか？というと、まずは

**「アセットファイル同士の参照の仕組みと、正しいファイル操作の方法を UE4 を使用するメンバー全員で共有すること」**

です。
これだけでこれらの問題が発生する可能性はかなり減るはずです。

また、先程のリダイレクターの削除により発生する問題に関しては、

**「対象となる全てのアセットファイルがコミットできる出来る状態でリダイレクターを削除する」**

ことを徹底すれば、そういった問題は発生しなくなります。

しかし、それでもこの問題が 100% なくなることはないと思われるので、もし発生してしまった場合に対処できるようにしておく必要があります。

## 参照切れが発生してしまった場合の対処法

もし、参照切れが発生してしまった場合の対処法ですが、基本的に手動で直すしかありません。

ただし、先程の SK_Mannequin の例のように**「SK_Mannequin を参照している場所だけを直せば全て解決する」**ようなの場合はもっと簡単に修正する方法があります。

試しに実践してみます。

まず、**「リネーム前」**の名前のアセットファイルを用意して、**「リネーム前」「リネーム後」**の双方のファイルがある状態にします。
今回の場合、以下のように SK_Mannequin が2つの状態になります。
![AssetFile08.png](https://qiita-image-store.s3.amazonaws.com/0/43814/a6439a37-4914-d5d6-723a-a680bff8e266.png)

次に、**「リネーム前」**の SK_Mannequin をコンテンツブラウザー上で**削除します。**
すると、以下のようなダイアログが表示されますので、左下の「None」をクリックして、**「リネーム後」**の SK_Mannequin を選択します。
![AssetFile09.png](https://qiita-image-store.s3.amazonaws.com/0/43814/582040c1-3ff6-2065-92cd-0f7333315946.png)

その後、その下にある「Replace References」をクリックすると、**「リネーム前」の SK_Mannequin に対するリダイレクター**が作成されます。
（作成した際に「保存しますか？」ダイアログが出るので、「保存」を選択します。）
![AssetFile10.png](https://qiita-image-store.s3.amazonaws.com/0/43814/261a851c-3d32-6828-47b3-536173ab293e.png)


後は従来通りの方法で先ほど作成されたリダイレクターを**「Fix up Redirectors in Folder」**を使って削除すれば、**「リネーム前」**の SK_Mannequin を参照していたアセットが全て**「リネーム後」**の SK_Mannequin2 を参照するように更新されます。


## 見落としている参照切れへの対処法

探し出すのが一番厄介であろう「見落としている」参照切れへの対処法です。

これらはクックして洗い出すのが一番ですので、

**「CI ツールなどを使って、定期的にクックする」**

を行って、早い段階で参照切れが発生していることを検知わかるようにします。

そうすれば、提出時に大量の参照切れを直す必要がなくなりますし、さらに1回で対処するファイルも少なくなり、参照切れの修正がしやすくなります。

ただ、毎回ログを見に行くのも大変なので、

**「クックしたログから参照切れのエラーを抽出して、あった場合は全員にメールで通知する」**

みたいな仕組みがあれば、さらに便利になるのではないかと思います。







[^1]: 必ず作られるというわけではないみたいで、条件は不明です。<br>スケルタルメッシュでは作られて、スケルトンでは作られなかったので、もしかしたら必須アセットか否かで違うのかも？