Unity5 ShaderVariantCollectionを使用しShaderのPreloadを行う

Shaderはゲーム中に使用する際にロードされ、それが原因でカクつきの原因になる場合があります。それを防ぐために、Unity5から導入されたShaderVariantCollectionの機能を使用し、ShaderのPreloadを行ないます。

公式で説明しているページはこちらになります。
[シェーダロードタイムの最適化](http://docs.unity3d.com/ja/current/Manual/OptimizingShaderLoadTime.html)

## ShaderVariantCollectionの機能
読み込みたいShaderとキーワードのリストを保持しています。
キーワードは"#pragma multi_compile"や、Fogのモードの"Linear"、"Exp"、"Exp2"等の同じShaderでも、異なる機能(Variant)を所持していた場合に、Preloadするものを選択する必要があります。

## ShaderVariantCollectionの作成方法
"Project > Create > ShaderVariantCollection"で作成する事が出来ます。
![スクリーンショット 2016-01-27 21.13.11.png](https://qiita-image-store.s3.amazonaws.com/0/102265/425b0474-ff4e-1259-d402-00a26e5e521f.png)

ShaderVariantCollectionのファイルが作成されたら、
Inspector上から"Add Shader"を押した後、登録したいShaderを選択します。
![スクリーンショット 2016-01-27 21.23.31.png](https://qiita-image-store.s3.amazonaws.com/0/102265/d71df6a2-fa65-2ed7-1045-cca7fc15292c.png)

Shaderが登録されると、次はキーワードを選択していきます。
画像の位置にある"+"ボタンを押すことでキーワードの選択Windowが開きます。
![スクリーンショット 2016-01-27 21.26.51.png](https://qiita-image-store.s3.amazonaws.com/0/102265/a5ffd16f-2aa4-379a-a7d0-5845d5a4a33a.png)

Windowの下部にあるVariantのキーワードを選択し登録します。
![スクリーンショット 2016-01-27 21.26.00.png](https://qiita-image-store.s3.amazonaws.com/0/102265/f2a4d3f9-b7bb-7cdb-976d-9a5885876621.png)

ShaderVariantCollectionへの登録は以上です。
他のShaderに関しても同様の手順で登録していきます。

ただ、Shaderの登録数が多いと一つづつ追加すると手間がかかるため、簡単ですがProject内のShaderを追加するEditorスクリプトを作成しました。ただし、追加できるのはShaderのみで、キーワードも追加できればよかったのですが方法がなさそうでしたので、キーワードに関してはポチポチ選択する必要があります。

```csharp:AddShaderVariantsWindow.cs
using UnityEngine;
using UnityEditor;
using System.Collections;

public class AddShaderVariantsWindow : EditorWindow {

	private ShaderVariantCollection svc;

	[MenuItem ("Window/AddShaderVariantsWindow")]
	public static void  ShowWindow () {
		EditorWindow.GetWindow(typeof(AddShaderVariantsWindow));
	}

	void OnGUI () 
	{
		svc = (ShaderVariantCollection)EditorGUILayout.ObjectField( "ShaderVariantCollection", svc, typeof(ShaderVariantCollection), false );

		if( svc )
		{
			if( GUILayout.Button("Add Select Shader" ) )
			{
				Object[] objs = Selection.objects;
				foreach( Object obj in objs )
				{
					Shader shader = obj as Shader;
					if( shader == null ){ continue; }

					ShaderVariantCollection.ShaderVariant sv = new ShaderVariantCollection.ShaderVariant();
					sv.shader = shader;
					svc.Add(sv);
				}
			}
		}
	}
}
```

使い方はメニューバーの、"Window > AddShaderVariantsWindow"からWindowを開きます。
次に、ShaderVariantCollectionのファイルを設定し、Project内で追加したいShaderを選択後、"Add Select Shader"ボタンを押して下さい。
![スクリーンショット 2016-01-31 18.21.10.png](https://qiita-image-store.s3.amazonaws.com/0/102265/2dcaf606-6d19-39eb-ac64-aa8b9cbf770e.png)

## Preloadの設定を行う
"Graphics Settings"から登録します。"Shader preloading/Preloaded Shaders"の所に、作成したShaderVariantCollectionのファイルを設定して下さい。これでゲームのロード中にpreloadされるようになります。また、スクリプト上から、"ShaderVariantCollection::WarmUp"を使用し手動で行う事もできます。

![スクリーンショット 2016-01-27 21.27.30.png](https://qiita-image-store.s3.amazonaws.com/0/102265/45d7dd7d-ba34-7a54-3a4b-55d4f3a63bc7.png)

ShaderVariantCollectionを作成する際に、Shaderもキーワードは多数あるけど、使わないものもあるので、ゲーム中に使用しているもののみ登録したいといった場合、Unityの機能で、実際に使用したShaderを追跡しており、そこからShaderVariantCollectionを作成する機能があります。
"Shader preloading/Preloaded Shaders"の下に、"Currently tracked:◯shaders ◯total variants"という記述がありますが、この下にある"Save to asset..."ボタンを押すと、実際に使用したものからShaderVariantCollectionを作成する事ができます。
こちらの機能を使用すれば、ゲームの規模にもよりますが、一通りEditor上で実行するだけで、ShaderVariantCollectionのファイルが作成できるので登録の手間が省けて便利です。