n-yoda's blog

主にUnity3Dに関するあんまり技術的じゃないメモ的な何かを書いています。

UnityのEditor上でTextureを編集する際にRead/Write Enabledを書き換えたくない

Editor上でちょっとフィルタをかけてみたり自前のPackerでパッキングをしたりする際に、「Read/Write Enabled」を書き換えて「実行時に読み書き可能」な状態にしてしまうのは行儀が悪い感じがするので、以下の様なことをする。

AssetPostprocessor.OnPostprocessTextureで処理してしまう

  • OnPostprocessTextureの時点では設定に依らずreadable。
  • 新たなファイルを作らずにUnity上でのみ編集後の状態になっている。
    • その方が嬉しい場合も多い。
  • 例: keijiro/unity-dither4444 · GitHub

TextureImporter.isReadableを書き換えて戻す

// pathが与えられたとして
var importer = AssetImporter.GetAtPath(path) as TextureImporter;
importer.isReadable = true;  
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport);  
// Texture2D.GetPixelsを使った処理をする
importer.isReadable = false;  
AssetDatabase.ImportAsset(path);

Texture2D.LoadImageする

// pathが与えられたとして
var copy = new Texture2D (0, 0);
copy.LoadImage(File.ReadAllBytes(path));
  • 利用できるのは圧縮の画像。

RenderTextureに焼く

// textureが与えられたとして
var temp = RenderTexture.GetTemporary(texture.width, texture.height);
Graphics.Blit(texture, temp);
// ReadPixelsで直前のレンダリング結果を読み込める
var copy = new Texture2D(texture.width, texture.height);
copy.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);
RenderTexture.ReleaseTemporary(temp);
  • RenderTexture.GetTemporary, Graphics.Blit
  • 利用できるのは圧縮の画像。
  • BlitでMaterialを指定すればShaderを使った処理が一緒に出来て良い。
  • ReadPixels自体はPro Onlyではないので、実は上手く使えばProじゃなくてもこの方法が使えなくはないはず。

おまけ:Textureの保存

1つめの方法以外では編集結果を別ファイルに保存することになると思われるので、その例。

// PNGとして書き出し
System.IO.File.WriteAllBytes(path, texture.EncodeToPNG());
Object.DestroyImmediate(texture);    // 破棄を忘れずに
// assetファイルとして書き出し
AssetDatabase.CreateAsset(texture, path);