38
33

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 2018-11-26

Unityでは以下のように、テクスチャー(画像ファイル)のインポート設定があります。これを上手く設定しないと画像がぼやける、容量が無駄に増える、そもそも表示されないなどの問題が生じます。
インポート設定

見ての通り、設定すべき項目が多いです。
問題はこれをインポートする度に行わなくてはならない事であり、画像毎に設定に差異が生じる場合があります。複数人で開発を行っている場合は差異が生じる可能性が大きく上昇するでしょう。
しかし、差異を無くすために画像をインポートする度にCtrl+Aで全選択し、設定するのも時間が掛かってしまいます。

そこで、この記事ではUnityのエディター拡張を行い、画像のインポート時に設定を自動で行うようにします。

画像のインポート設定を自動で設定する

エディター拡張用ファイルを作る

画像のインポート時とインポート設定を変えた時に呼ばれる関数である、AssetPostprocessorクラスのOnPreprocessTextureメソッドと画像のインポート設定を変更するTextureImporterクラスを使用します。
この記事では特に設定すべきであろう物だけ紹介します。他の設定も見たい場合はTextureImporterのスクリプトリファレンスも参照してください。

使用例

Assetフォルダ以下にEditorフォルダを作成し、そこにImportManager.csファイルを作ってみましょう。
4つのフォルダが登場しますが、フォルダの説明は以下の通りです。

  • BackGround:背景画像のフォルダ。長辺サイズが1500前後のjpgファイルが入っている。
  • Character:キャラクターの立ち絵のフォルダ。長辺サイズが600前後の透過pngファイルが入っている。
  • Dot:ドット絵のフォルダ。長辺サイズが16または24の透過pngまたはgifファイルが入っている。
  • Effect:エフェクトアニメーションのフォルダ。長辺サイズが800前後の透過pngファイルが入っている。
ImportManager.cs
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Reflection; // MethodInfoやBindingFlagsで必要

public class ImportProcess : AssetPostprocessor
{
    private readonly object [] TextureSize = new object [2] { 0, 0 };
    private readonly MethodInfo GetSizeMethod = typeof (TextureImporter).GetMethod ("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);

	// 画像のインポート時、インポート設定変更時に実行される関数
	void OnPreprocessTexture ()
	{
		// assetImporterにインポートするオブジェクトが入る。それをテクスチャ型にキャスト
		TextureImporter ti = assetImporter as TextureImporter;

        // 各種Packageの画像や、TextureTypeがSingleChannelの画像は変えたらエラーが出る可能性があるのでここで終了
        if (ti.assetPath.StartsWith ("Packages/") || ti.textureType == TextureImporterType.SingleChannel)
        {
	        return;
        }

		//今回は全てスプライト扱いにする
		ti.textureType = TextureImporterType.Sprite;
        ti.mipmapEnabled = false;
        ti.textureCompression = TextureImporterCompression.Compressed;

		//ここからはインポートするテクスチャがどのフォルダ内にあるかで処理を変える
		if (ti.assetPath.Contains ("Assets/Resources/Pictures/BackGround"))
		{
			ti.spriteImportMode = SpriteImportMode.Single;
			ti.filterMode = FilterMode.Bilinear;
		}
		else if (ti.assetPath.Contains ("Assets/Resources/Pictures/Character"))
		{
			ti.spriteImportMode = SpriteImportMode.Single;
			ti.filterMode = FilterMode.Bilinear;
		}
		else if (ti.assetPath.Contains ("Assets/Resources/Pictures/Dot"))
		{
			ti.spriteImportMode = SpriteImportMode.Single;
			ti.filterMode = FilterMode.Point; // Bilinearにすると変にぼやけてドット絵の良さが失われるので、これだけPoint
		}
		else if (ti.assetPath.Contains ("Assets/Resources/Pictures/Effect"))
		{
			ti.spriteImportMode = SpriteImportMode.Multiple; // スプライトエディターで画像を切り分けるので、これだけMultiple
			ti.filterMode = FilterMode.Bilinear;
		}

        int textureWidth;
        int textureHeight;
        int maxTextureSize;
        
        // 画像のサイズを取得
        GetSizeMethod.Invoke (ti, TextureSize);
        textureWidth = (int)TextureSize [0];
        textureHeight = (int)TextureSize [1];
        // 画像のサイズに応じてmaxTextureSizeを変える
        if (textureWidth <= 32 && textureHeight <= 32)
        {
	        maxTextureSize = 32;
        }
        else if (textureWidth <= 64 && textureHeight <= 64)
        {
	        maxTextureSize = 64;
        }
        else if (textureWidth <= 128 && textureHeight <= 128)
        {
	        maxTextureSize = 128;
        }
        else if (textureWidth <= 256 && textureHeight <= 256)
        {
	        maxTextureSize = 256;
        }
        else if (textureWidth <= 512 && textureHeight <= 512)
        {
	        maxTextureSize = 512;
        }
        else if (textureWidth <= 1024 && textureHeight <= 1024)
        {
	        maxTextureSize = 1024;
        }
        else if (textureWidth <= 2048 && textureHeight <= 2048)
        {
	        maxTextureSize = 2048;
        }
        else if (textureWidth <= 4096 && textureHeight <= 4096)
        {
	        maxTextureSize = 4096;
        }
        else
        {
	        maxTextureSize = 8192;
        }
        ti.maxTextureSize = maxTextureSize;

        // 圧縮フォーマットが高品質であるか。今回はDefaultのFormatがRGBA32の画像、Dotディレクトリの画像を高品質にする
        bool isHighQuality = ti.GetDefaultPlatformTextureSettings ().format == TextureImporterFormat.RGBA32 || ti.assetPath.Contains ("Assets/Resources/Pictures/Dot");
        TextureImporterFormat format = isHighQuality ? TextureImporterFormat.RGBA32 : TextureImporterFormat.RGBA16;

        // プラットフォームごとに設定を上書きする
        // メモリとHDDが潤沢なスタンドアロンはテクスチャを綺麗に見せる事を優先し、それ以外のプラットフォームはテクスチャの容量を小さくすることを優先している
        // Standaloneは最高画質限定
        ti.SetPlatformTextureSettings (new TextureImporterPlatformSettings { overridden = true, name = "Standalone", maxTextureSize = maxTextureSize, format = TextureImporterFormat.RGBA64 });
        ti.SetPlatformTextureSettings (new TextureImporterPlatformSettings { overridden = true, name = "iPhone", maxTextureSize = maxTextureSize, format = format });
        ti.SetPlatformTextureSettings (new TextureImporterPlatformSettings { overridden = true, name = "Android", maxTextureSize = maxTextureSize, format = format });
        // WebGLでRGBA16を使おうとするとエラーが出る
        ti.SetPlatformTextureSettings (new TextureImporterPlatformSettings { overridden = true, name = "WebGL", maxTextureSize = maxTextureSize, format = isHighQuality ? TextureImporterFormat.RGBA32 : TextureImporterFormat.ARGB16 });
	}
}

共通設定

Texture Type

Texture Typeは画像が何に使われるのかを設定します。この設定を誤ると最悪画像が表示されません。

ti.textureType = TextureImporterType.Sprite; // スプライト(主に2D用)
ti.textureType = TextureImporterType.GUI; // GUI(主に3D用)

Generate Mip Maps

Generate Mip Mapsはテクスチャのミップマップの生成を設定します。遠くからスプライトを見る場面があればtrueにすれば良い感じだと思います。

ti.mipmapEnabled = true; // ミップマップをtrueに設定する

Asset Path

Asset Pathはテクスチャのパスを取得します。読み取り専用。

Debug.Log (ti.assetPath); // テクスチャの置かれているパスを取得し、ログに表示する
						  // Assets/Resources/Pictures/hogehoge/hugahuga.pngのようなstringが取得可能

Filter Mode

Filter Modeはテクスチャのフィルタリングモードを設定します。ドット絵はPoint、それ以外はBilinearにすれば画像が綺麗になると思います。

ti.filterMode = FilterMode.Bilinear; // Bilinear
ti.filterMode = FilterMode.Point; // Point

Max Size

Max Texture Sizeはテクスチャの最大サイズを設定します。長辺が設定したサイズ以上の場合は設定値へとスケールダウンされます。設定値は32~8192までの2のべき乗限定です。

ti.maxTextureSize = 1024; // 長辺のサイズを1024までに制限する
ti.maxTextureSize = 2048; // 長辺のサイズを2048までに制限する

Compression

Texture Importer Compressionはテクスチャの圧縮タイプを設定します。この設定はプラットフォームごとの設定によっては上書きされます(詳しくは後述)。

ti.textureCompression = TextureImporterCompression.Compressed; // 圧縮タイプをNormal Qualityに設定する
ti.textureCompression = TextureImporterCompression.CompressedHQ; // 圧縮タイプをHigh Qualityに設定する(高品質、メモリ使用増)

Sprite専用設定

Sprite Mode

Sprite Modeはスプライトのインポートモードを設定します。エフェクトなどのアニメーションはMultiple、立ち絵や背景はSingleと言った感じです。

ti.spriteImportMode = SpriteImportMode.Single; // シングル
ti.spriteImportMode = SpriteImportMode.Multiple; // マルチタイプ

プラットフォームごとの設定

ここからはプラットフォームごとの個別設定について解説します。
「スタンドアロンでは容量が大きくなっても良いから画像を綺麗にしたいが、他のプラットフォームでは画像が多少荒くなっても良いから容量を小さくしたい」という感じに設定をこだわりたい人向けの内容です。

SetPlatformTextureSettings()関数の引数にTextureImporterPlatformSettingsクラスを渡して設定を行います。

ti.SetPlatformTextureSettings (new TextureImporterPlatformSettings
{
	overridden = true,
	name = "Android",
	maxTextureSize = 1024,
	format = TextureImporterFormat.RGBA16,
	textureCompression = TextureImporterCompression.Compressed,
	resizeAlgorithm = TextureResizeAlgorithm.Mitchell
});

ここで設定したmaxTextureSizeなどは上書きされ、共通設定で設定した値よりもここで設定した値が優先されます。
この記事では特に設定すべきであろう物だけ紹介します。他の設定も見たい場合はTextureImporterPlatformSettingsのスクリプトリファレンスも参照してください。

overridden

overriddenがtrueならプラットフォームで設定を上書きし、falseならデフォルトの設定を用います。falseにする意味は無いに等しいので実質true一択でしょう。

overridden = true,

name

nameは設定を上書きしたいプラットフォームです。stringで指定してください。

name = "Android",
name = "iPhone",
name = "Standalone", // PCのスタンドアロン
name = "WebGL",

maxTextureSize

maxTextureSizeはテクスチャの最大サイズを設定します。共通設定で説明したのと同じ役割を果たします。

maxTextureSize = 1024,
maxTextureSize = 2048,

format

formatは圧縮するテクスチャの形式を設定します。この設定次第でテクスチャの綺麗さや容量の大きさが変わるので最も重要な設定項目であると言えるでしょう。

format = TextureImporterFormat.RGB24,
format = TextureImporterFormat.RGBA32, // Standaloneなど
format = TextureImporterFormat.RGBA16, // Android、iPhoneなど
format = TextureImporterFormat.ARGB16, // WebGLなど

この設定で厄介なのは、本来は選択不可能なフォーマットもスクリプト上で選択できてしまう点です。例えばAndroidでARGB16、WebGLでRGBA16が選択できてしまいます。もし選択した場合はフォーマットはデフォルトの物(DXT1など)になってしまうので注意が必要です。

textureCompression

textureCompressionはテクスチャの圧縮タイプを設定します。共通設定で説明したのと同じ……はずですが、いざ設定してもエディター上では特に何も表示されないのでこの設定は本当に有効なのかは怪しいです。

textureCompression = TextureImporterCompression.Uncompressed, // 圧縮無し
textureCompression = TextureImporterCompression.Compressed, // 圧縮
textureCompression = TextureImporterCompression.CompressedHQ, // 高品質、低速圧縮
textureCompression = TextureImporterCompression.CompressedLQ, // 高速、低品質圧縮

resizeAlgorithm

resizeAlgorithmはテクスチャのリサイズアルゴリズムを設定します。迷ったらデフォルト設定のMitchellで良いでしょう。

resizeAlgorithm = TextureResizeAlgorithm.Mitchell,
resizeAlgorithm = TextureResizeAlgorithm.Bilinear,

補足

執筆時のUnityのバージョンは2023.2です。

外部リンク

TextureImporterのスクリプトリファレンス
TextureImporterPlatformSettingsのスクリプトリファレンス
テクスチャのマニュアル

38
33
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
38
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?