UnityでのAssetになった画像ファイルのコピーでインポートを避けることは出来ないという結論


概要

Unityに画像ファイルとかモデルファイルを喰わせる際、

importが走る。


んでこれがまあ、数が数千に及ぶファイルだと辛い。

ここでは、対象をpngとかのフォーマットの画像ファイルに限った話をする。


このimportを発生させずに、素材をUnityに喰わせることはできないか?ということを考えていた。

結論から言うと、一つのプロジェクトではimportを避けるのは無理だった。


でも別のテは使えた。

試した手段を並べる。



手法1 CopyAsset

例えばすでに読みこんだリソースならば、importを再度発生させること無くコピーできるのではないか!?


AssetDatabase.CopyAsset


やってみよう。


var result = AssetDatabase.CopyAsset("Assets/Resources/import/main.jpg", "Assets/Resources/prefabricate/main.jpg");

Debug.Log("result:" + result);


で、これはたしかに読み込まれるんだけど、このあとimportが再度走る。

なぜなんだ、、、、っておもったけど、こいつ、画像ファイルとかに対しては、ファイルをコピーするだけの仕様とのこと。ぐぬぬ、、、


読み込まれたものの概念ごと、ファイル(main.jpg)と設定それ自体をコピーしてほしかったんだけど、

importは走ってしまう。


貴様。


手法2 CreateAsset

名前からして作れそう、、、


var basement = Resources.Load("import/main");


if (basement) Debug.Log("basement is alive!");

else Debug.Log("basement is dead.");


var duplicated = UnityEngine.Object.Instantiate(basement);


AssetDatabase.CreateAsset(duplicated, "Assets/Resources/prefabricate/main.jpg");

Could not create texture from Assets/Resources/prefabricate/main.jpg: File could not be read


殴られるなど。


物の本によると、.mat, .anim, .cubemap, .asset のみしか指定できない。

まあUnityで内部的にも扱えるオブジェクトってなると納得。

納得、、、、なんだが、、、

なんだそのエラーは、、、!!!! 読めなくなったよ的なのがでるんだけど、実際にはオメーこれらの拡張子以外つくれねーじゃねーかww

ありがとう物の本、、って絶版なの、、?

Unity4 ライブラリ辞典 エディタ編



手法2.1 なら.assetで

var basement = Resources.Load("import/main");


if (basement) Debug.Log("basement is alive!");

else Debug.Log("basement is dead.");


AssetDatabase.CreateAsset(basement, "Assets/Resources/prefabricate/main.asset");

Couldn't create asset file because the Texture2D 'main' is already an asset at 'Assets/Resources/import/main.jpg'!


読み出した物からいきなりCreateしようとすると、読んだ大本の奴とおんなじじゃんって殴られる。

管理してるidそれ自体からのコピーではない、と。

ハイ。



手法2.2 ならコピーして

var basement = Resources.Load("import/main");


if (basement) Debug.Log("basement is alive!");

else Debug.Log("basement is dead.");


var duplicated = UnityEngine.Object.Instantiate(basement);


AssetDatabase.CreateAsset(duplicated, "Assets/Resources/prefabricate/main.asset");


var loadFromDuplicated = Resources.Load("prefabricate/main") as Texture2D;

if (loadFromDuplicated) Debug.Log("loadFromDuplicated is alive:" + loadFromDuplicated.name);

else Debug.Log("loadFromDuplicated is dead:" + loadFromDuplicated.name);


うん、いけるな。importも発生しない。まあjpgじゃなくなってるからな。

jpgではなくなってしまった。

jpgではなくなってしまった。

jpgではなくなってしまった。

でも出来たしまあリソースとしてはimportしてたときにセットできてるからなまあいいよな(妥協



ということで、画像ファイルのコピーを行って再importを避ける手段は無い。

packageとかを使えば出来ると思うけどお手軽さからは程遠いな、、まあそれをやってるAssetもあるんだけどさ。




あとはおまけ。





番外 AddObjectToAsset

Assetとして出力する方法で別のかんじで試せるのでは!?

// AddObjectToAssetで子オブジェクトを作ることは出来るっちゃあできるけどやっぱりjpgではなくなる

var basement = Resources.Load("import/main");


if (basement) Debug.Log("basement is alive!");

else Debug.LogError("basement is dead.");


var box = ScriptableObject.CreateInstance("Something");

AssetDatabase.CreateAsset(box, "Assets/Resources/prefabricate/main.asset");


var duplicated = UnityEngine.Object.Instantiate(basement);


AssetDatabase.AddObjectToAsset(duplicated, "Assets/Resources/prefabricate/main.asset");

AssetDatabase.SaveAssets();


var loadFromDuplicated = Resources.Load("prefabricate/main") as Texture2D;

if (loadFromDuplicated) Debug.Log("loadFromDuplicated is alive:" + loadFromDuplicated.name);

else Debug.Log("loadFromDuplicated is dead:" + loadFromDuplicated.name);


出来るが嬉しさは無い。



番外 AddObjectToAsset その2

var basement = Resources.Load("import/main");


if (basement) Debug.Log("basement is alive!");

else Debug.LogError("basement is dead.");


AssetDatabase.AddObjectToAsset(basement, "Assets/Resources/prefabricate/main.asset");

You may not change the path if an object is already peristent in another one

ハイ。