AvatarをセットアップするEditorを作る(Expression編)｜VRC用の拡張Editorを作ってみよう(4)

この記事は前回の続きになります
[VRC用の拡張Editorを作ってみよう(3)](https://qiita.com/Milcia/items/68491d554fb0fcc9a04c)

#目次
1.準備
2.ExpressionMenuとParameterのメソッドを作る
3.メソッドの中にコードを書く
4.ボタンで追加できるようにする
5.動作確認
6.次回

#1.準備
##Expressionを入れるフォルダーを作る
最初にExpressionを入れるためのフォルダーを作っておきましょう
Editorなどの隣にわかりやすく名前を付けたうえでフォルダーを作成します
今回はExpressionと付けました
![Expression.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286080/091be0f9-c90e-18d9-f71f-aa04f2480c1a.png)
できました
__フォルダーのパスもコピーしておきましょう__

##EditorにExpressionフォルダーの変数を作る
フォルダーを作った時にコピーしたパスを変数に入れていきます
今回も__OnGUIの上__に書いていきます
__private__な__String型__の変数を作ります
名前は分かりやすい名前で付けます
今回は__private string exPath__にでもしましょうか
exPathが宣言できると、その中に先ほどコピーしたパスを代入します
出来るとこのようになります

```c#
private string exPath = "Assets/test/Expression";
```
これで変数ができました

##ExpressionParameterを扱えるようにする
ExpressionParameterを扱えるようにするために__using__を使用します
以下二つを追加してください

```c#
using ExpressionParameters = VRC.SDK3.Avatars.ScriptableObjects.VRCExpressionParameters;
using ExpressionParameter = VRC.SDK3.Avatars.ScriptableObjects.VRCExpressionParameters.Parameter;
```

これで扱えるようになりました(SDK漁ってる時に見つけたから説明できないし知らない)

#2.ExpressionMenuとParameterのメソッドを作る
##ExpressionMenuのメソッドを作る
まずはMenuの方から作っていきましょう
前回作成した__SetupFXLayer()__の下に作ります
__privateな値を返さない__メソッドを作ります
名前は分かりやすいように付けます
今回は__SetupExMenu__にしました
コードはこうなります

```c#
private void SetupExMenu()
{
	
}
```
これでExMenuのメソッドができましたね

##ExpressionParameterのメソッドを作る
次にParameterを作ります
__SetupMenu__の下に書いていきます
__privateな値を返さない__メソッドを作ります
名前は分かりやすいように付けます
今回は__SetupExParam__にしました
コードはこうなります

```c#
private void SetupExParam()
{

}
```
これでExParamのメソッドもできましたね

#3.メソッドの中にコードを書く
##SetupMenuのコードを書く
Menuからコードを書いていきます
まずは__メニューを作成します__
__VRCExpressionsMenu型__の変数を宣言します
名前は分かりやすい名前を付けます
今回はexpressionMenuにしました
宣言ができたら__CreateInstance__を使って__VRCExpressionsMenu__を新しく作成します
使い方はこうです

```c#
CreateInstance<"タイプ">();
```

タイプの中に__VRCExpressionsMenu__を書きます
これでVRCExpressionMenuのインスタンスが新しく作成されます
それを変数expressionMenuに代入します
コードはこうなります

```c#
VRCExpressionsMenu expressionMenu = CreateInstance<VRCExpressionsMenu>();
```

これで新しいVRCExpressionsMenuの代入ができました
新しいインスタンスを__Assetsに.asset__として作っていきます
Assetsにファイルを作成するには__AssetDatabase.CreateAsset__を使います
使い方はこんな感じです

```c#
AssetDatabase.CreateAsset("作るオブジェクト", "フォルダのパス");
```
作るオブジェクトは__VRCExpressionsMenuを代入したexpressionMenu__で、
フォルダのパスは__最初に作ったexPath__を使います
__exPathのままだとファイルを作れないのでアバターの名前を付けて拡張子など指定していきましょう__
言葉で説明するより書いた方が早いですね
コードはこうなります

```c#
AssetDatabase.CreateAsset(expressionMenu, exPath + "/" + avatar.name + "ExMenu.asset");
```
__exPath + "/"__から先は変えても大丈夫ですが__[.asset]__は忘れないでくださいね
これでファイルの作成ができました

最後に今作ったファイルをアバターへ入れます
expressionsMenuにファイルを入れるためには
avatar.GetComponent<VRCAvatarDescriptor>()の後に__.expressionsMenu__と書きます
その中に入れるファイルは前回使用した__AssetDatabase.LoadAssetAtPath__を使って取得します
ファイルパスはファイルを作成した時に書いた物を使います
コードはこうなりました

```c#
avatar.GetComponent<VRCAvatarDescriptor>().expressionsMenu = AssetDatabase.LoadAssetAtPath(exPath + "/" + avatar.name + "ExMenu.asset", typeof(VRCExpressionsMenu)) as VRCExpressionsMenu;
```
__キャスト__は忘れないでくださいね
これでSetupExMenuメソッドは完成しました

##SetupExParamのコードを書く
Paramのコードを書いていきます(やっと)
今さっきと同じようにVRCExpressionParameters型の変数を宣言します
分かりやすく名前を付けます
名前は__expressionParameter__にしました
そのあとも今さっきと一緒で__CreateInstance__を使って__VRCExpressionPatameters__を新しく作って代入します
ここはちょちょいと済ませてしまいましょう
コードはこうなりました

```c#
VRCExpressionParameters expressionParameter = CreateInstance<VRCExpressionParameters>();
```
これで新しいVRCExpressionParametersの代入ができました
次は__ExpressionParameterに初期で追加するためのパラメーター__を作っていきます
最初にいくつ追加するか指定します
追加方法は__変数expressionParameter__に__.parameters__を書き加えて__new ExpressionParameter["要素数"]__を代入することで追加できます
今回は3つ追加するので__要素数を3__にします(最初からVRCのEmoteとか入ってるから...)
コードはこんな感じです

```c#
expressionParameter.parameters = new ExpressionParameter[3];
```
これでPatameterの箱が3つ作られました
ここからは追加するパラメーターなので一気に説明していきます

expressionParameter.parameters["要素数"]にnew ExpressionParameter()を代入してパラメーターを追加
expressionParameter.parameters["総素数"]__.name__に名前を代入
expressionParameter.parameters["総素数"].valueTypeに__ExpressionParameters.ValueType.型__を代入

今説明したものを作っていきます
__要素数0 <- [name = VRCEmote] [valueType = ValueType.Int]
要素数1 <- [name = VRCFaceBlendH] [valueType = ValueType.Float]
要素数2 <- [name = VRCFaceBlendV] [valueType = ValueType.Float]__

コードはこうなります

```c#
expressionParameter.parameters[0] = new ExpressionParameter();
expressionParameter.parameters[0].name = "VRCEmote";
expressionParameter.parameters[0].valueType = ExpressionParameters.ValueType.Int;

expressionParameter.parameters[1] = new ExpressionParameter();
expressionParameter.parameters[1].name = "VRCFaceBlendH";
expressionParameter.parameters[1].valueType = ExpressionParameters.ValueType.Float;

expressionParameter.parameters[2] = new ExpressionParameter();
expressionParameter.parameters[2].name = "VRCFaceBlendV";
expressionParameter.parameters[2].valueType = ExpressionParameters.ValueType.Float;
```
これで追加するパラメーターが完成しました
これを__AssetDatabase.CreateAsset__を使ってファイル作成しましょう
作るオブジェクトはexpressionParameterにして・・・
パスの名前も__exPath + "/" + avatar.name + "ExParameter.asset"__とかにしましょうか
コードはこうなりました

```c#
AssetDatabase.CreateAsset(expressionParameter, exPath + "/" + avatar.name + "ExParameter.asset");
```

これでファイルが作られるようになりましたね
次にアバターへファイルを入れましょう
avatar.GetComponent<VRCAvatarDescriptor>()に__.expressionParameters__を付け足します
これでexpressionParametersにファイルを入れることができます
ファイルは__AssetDatabase.LoadAssetAtPath__を使ってロードしましょう
最後にロードしたものをアバターに入れます
コードはこうなります

```c#
avatar.GetComponent<VRCAvatarDescriptor>().expressionParameters = AssetDatabase.LoadAssetAtPath(exPath + "/" + avatar.name + "ExParameter.asset", typeof(VRCExpressionParameters)) as VRCExpressionParameters;
```
Menuの時と同じくキャストを忘れないように
これでSetupExParamメソッドは完成しました

#4.ボタンで追加できるようにする
##前回の物を修正する
最初に前回書いたSetupFXLayerのボタンを修正します
avatar.GetComponent<VRCAvatarDescriptor>()__.customizeAnimationLayers__を使用して
カスタムアニメーションがオフになっているときだけ表示されるようにします
オフの時に真にしたいので__[!]__を付けます
前回書いたif(GUILayout.Button("アバターのFXLayerをセットアップする"))を__挟むように追加します__
コードはこうなります

```c#
if (avatar.GetComponent<VRCAvatarDescriptor>())
{
	//FXボタンが表示されないように追加
	if (!avatar.GetComponent<VRCAvatarDescriptor>().customizeAnimationLayers)
	{
		if (GUILayout.Button("アバターのFXLayerをセットアップする"))
		{
			SetupFXLayer();
		}
	}
}
else
{
	if (GUILayout.Button("アバターにVRCAvatarDescriptorを入れる"))
	{
		AddDescriptor();
	}
}
```

これでボタンの修正ができました

##Expressionを追加するボタンを作る
まずはif文を使用してアバターの__customEcpressionsがオフになってるか__確認するために
avatar.GetComponent<VRCAvatarDescriptor>()__.customExpressions__を使用します
オフの時に真にしたいので__[!]__を付けます
__その中に__ボタンを追加していきます
if文を使用してGUILayout.Buttonでボタンを作っていきます
ボタンの名前は"アバターのExpressionをセットアップする"と付けておきました
ボタンまで完成したコードがこれです

```c#
if (!avatar.GetComponent<VRCAvatarDescriptor>().customExpressions)
{
	if (GUILayout.Button("アバターのExpressionをセットアップする"))
	{
		
	}
}
```
これでボタンが完成ですね
次はボタンに処理を書いていきましょう
ボタンが押されたらcustomExpressionsをオンにするコードをif文の中に書いていきます
customExpressionsをtrueにするだけなので簡単ですね
コードはこうなりました

```c#
avatar.GetComponent<VRCAvatarDescriptor>().customExpressions = !avatar.GetComponent<VRCAvatarDescriptor>().customExpressions;
```
これでcustomExpressionsをオンにするコードができました
最後はこの下に作ったメソッドを追加していきましょう
SetupExMenu()
SetupExParam()
を追加します
追加するとコードはこうなります

```c#
if (avatar.GetComponent<VRCAvatarDescriptor>())
{
	//FXボタンが表示されないように追加
	if (!avatar.GetComponent<VRCAvatarDescriptor>().customizeAnimationLayers)
	{
		if (GUILayout.Button("アバターのFXLayerをセットアップする"))
		{
			SetupFXLayer();
		}
	}

	//この下に追加する
	if (!avatar.GetComponent<VRCAvatarDescriptor>().customExpressions)
	{
		if (GUILayout.Button("アバターのExpressionをセットアップする"))
		{
			avatar.GetComponent<VRCAvatarDescriptor>().customExpressions = !avatar.GetComponent<VRCAvatarDescriptor>().customExpressions;
			SetupExMenu();
			SetupExParam();
		}
	}
}
else
{
	if (GUILayout.Button("アバターにVRCAvatarDescriptorを入れる"))
	{
		AddDescriptor();
	}
}
```

これでExpressionを追加するEditorが完成しました！(ふぅ・・・)

#5.動作確認
最初にCtrl + Sで__スクリプトを保存__しましょう
保存ができたらUnityに戻りEditorを開きます
![Editor8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286080/5918de65-f130-993f-8ebd-3869c98602ca.png)
Editorの見た目は変わってないですね
VRCAvatarDescriptorは前回の続きであればこうなってると思います
![vad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286080/a2ac05dd-a0fc-3968-1a03-3d3d7e5322c9.png)
上の状態になっていたらEditorを開いてアバターを入れます
![Editor9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286080/14f25007-d799-9ec2-02ae-73c2f90054ec.png)
アバターを入れると作ったボタンが表示されていると思います
押してみましょう
![avd2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286080/5377cb6c-a3b0-92bf-7a39-d1f69de669ec.png)
ちゃんとExpressionsにMenuとParameterが追加されていますね
これで今日は終了です
お疲れさまでした

#6.次回
次回はゲームオブジェクトを出し入れするための__アニメーション__を作るEditorを作ろうと思います

[VRC用の拡張Editorを作ってみよう(5)](https://qiita.com/Milcia/items/ff7d9e1dffa28004efb7)