この記事は前回の続きになります
VRC用の拡張Editorを作ってみよう(2)
目次
1.不要なコードを削除する
2.VRCAvatarDescriptorが入ってない場合自動でコンポーネントを追加するようにする
3.FXLayerが入っているか確認して入っていなければ追加するコードを書く
4.ボタンを押すと処理が行われるようにする
5.動作確認をする
6.次回
1.不要なコードを削除する
削除するコード
InsertObjectメソッドはすべて消します
//すべて消す
private void InsertObject()
{
gameObject.transform.SetParent(avatar.transform);
}
if(GUILayout.Button)もすべて消す
if (GUILayout.Button("オブジェクトを入れる"))
{
InsertObject(); //中のInsertObject();も消す
}
前回作成したGameObjectの変数とObjectFieldを削除する
//gameObjectはすべて消す
private GameObject gameObject;
gameObject = EditorGUILayout.ObjectField("gameObject", gameObject, typeof(GameObject), true) as GameObject;
全て消すとこのようになると思います
public class TestEditor : EditorWindow
{
[MenuItem("TestEditor/TestEditor")]
public static void ShowWindow()
{
EditorWindow.GetWindow<TestEditor>(true, "TestEditor");
}
private GameObject avatar;
private void OnGUI()
{
avatar = EditorGUILayout.ObjectField("Avatar", avatar, typeof(GameObject), true) as GameObject;
}
}
これでコードの削除ができました
2.VRCAvatarDescriptorが入ってない場合自動でコンポーネントを追加するようにする
AvatarのObjectFieldをVRCAvatarDescriptorからGameObjectに書き換える
前回書いたVRCAvatarDescriptorタイプの変数AvatarをGameObjectにしていきます
まずは変数から変更してきます
//変更前
private VRCAvatarDescriptor avatar;
//変更後
private GameObject avatar;
VRCAvatarDescriptorをGameObjectに書き換えるだけで変更できると思います
次にObjectFieldを変更していきます
//変更前
avatar = EditorGUILayout.ObjectField("Avatar", avatar, typeof(VRCAvatarDescriptor), true) as VRCAvatarDescriptor;
//変更後
avatar = EditorGUILayout.ObjectField("Avatar", avatar, typeof(GameObject), true) as GameObject;
オブジェクトタイプとキャストをVRCAvatarDescriptorからGameObjectに変更しました
これで書き換えができました
VRCAvatarDescriptorを追加する用のメソッドを作る
前回と同じようにメソッドを作っていきます
今回も値を返さないメソッドを作ります
名前は適当につけて・・・
private void AddDescriptor()
{
}
こんな感じになりました
VRCAvatarDescriptorが入っているかを確認して、入っていなければ追加するコードを書く
コードは先ほど作成したAddDescriptorの中に書いていきます
まずはVRCAvatarDescriptorが入っているかを確認します
if文で真・偽を判定し、Avatar.GetComponentを使ってコンポーネントを取得します
コンポーネントを取得できなければ真を返すようにしたいので、GetComponentの先頭に 否定「!」 を付けます
GetComponentで取得するコンポーネントはVRCAvatarDescriptorです
今回のコードはこうなりました
if (!avatar.GetComponent<VRCAvatarDescriptor>())
{
}
これで確認できるようになりました
次にVRCAvatarDescriptorを追加していきます
Avatar.AddComponentを使ってコンポーネントを追加できるようにします
AddComponentで追加するコンポーネントはVRCAvatarDescriptorです
今回のコードはこうなりました
if (!avatar.GetComponent<VRCAvatarDescriptor>())
{
avatar.AddComponent<VRCAvatarDescriptor>();
}
これでコンポーネントがなければ追加するコードが完成しました
3.FXLayerが入っているか確認して入っていなければ追加するコードを書く
FXLayerを保管するフォルダーを作成する
準備としてFXLayerを保管するフォルダーを作っていきます
フォルダーを作る場所は自由です
名前は分かりやすいようにFxLayerなどつけておきましょう
フォルダーが完成したらフォルダーのパスを取得します
FXLayerフォルダーを右クリックしてパスをコピーします
パスのコピーができたら新しく変数を宣言していきます
今回はOnGUIの上で宣言します
privateなstring型の変数createFXPathを宣言します
宣言したcreateFXPathに、先ほどコピーしたパスを代入します
宣言ができるとこんな感じになると思います
private string createFXPath = "Assets/test/FxLayer";
private void OnGUI()
{
FXLayerを保管するフォルダーができました
FXLayerをコピーするためのパスを取得する
FXLayerをコピーするパスの変数を作っていきます
今回もOnGUIの上で宣言します
privateなstring型の変数copyFXPathを宣言します
宣言したcopyFXPathに、FXLayerが入っている
Assets/VRCSDK/Examples3/Animation/Controllers/vrc_AvatarV3HandsLayer.controller
を代入します
宣言ができるとこんな感じになると思います
private string copyFXPath = "Assets/VRCSDK/Examples3/Animation/Controllers/vrc_AvatarV3HandsLayer.controller";
これで準備はできました
FXLayerを追加する用のメソッドを作る
FXLayerを追加する用のメソッドを作っていきます
今回も値を返さないメソッドを作ります
名前は適当につけて・・・
こんな感じのコードになると思います
private void SetupFXLayer()
{
}
これでメソッドが完成しました
Playeble LayersのCustomizeが有効になっているかを確認して無効になっていた場合有効にする
先ほど作成したSetupFXLayerの中に書いていきます
最初に変数を作る
後から使いやすいように最初に変数を作っていきます
VRCAvatarDescriptorタイプのavatarDescriptor変数を作って・・・
avatarDescriptor変数にavatar.GetComponentで取得したVRCAvatarDescriptorを代入していきます
今回のコードはこうなります
VRCAvatarDescriptor avatarDescriptor = avatar.GetComponent<VRCAvatarDescriptor>();
これで変数はできました
次にPlayeble LayersのCustomizeが有効になっているかを確認する
Playeble LayersのCustomizeが有効になっているかを確認するコードを書いていきます
有効になっているかの確認はVRCAvatarDescriptor.customizeAnimationLayersで確認できます
if文でcustomizeAnimationLayersが偽の場合、真に変更するコードを書いてきます
先ほど作成した変数を使用して・・・
今回のコードはこうなりました
if (!avatarDescriptor.customizeAnimationLayers)
{
avatarDescriptor.customizeAnimationLayers = true; //trueで偽から真に変える
}
これでPlayeble LayersのCustomizeが有効になっているかを確認して、無効になっていた場合有効にするコードが完成しました
FXLayerがデフォルトになっているか確認して、デフォルトになっていたらカスタムできるようにする
SetupFXLayer()の中に書いていきます
FXLayerの取得はVRCAvatarDescriptor.baseAnimationLayers[4]を使用することで取得できます
FXLayer以外にも、配列の番号を変えるとほかのLayerが取得できます
Base | Additive | Gesture | Action | FX |
---|---|---|---|---|
[0] | [1] | [2] | [3] | [4] |
デフォルトの確認はbaseAnimationLayers[].isDefaultを使用して確認できます
今回はデフォルトになっているかの確認をしたいので、if文を使います
確認用のコードが完成したら、if文の中にisDefaultが真のときのコードを書きます
カスタムする場合、isDefaultをfalseに変えてあげるとカスタムできるようになります
今回のコードはこうなりました
if (avatarDescriptor.baseAnimationLayers[4].isDefault) //avatarのFXLayerがデフォルトになってるか判定する
{
avatarDescriptor.baseAnimationLayers[4].isDefault = false; //デフォルトになっていたらデフォルトを真から偽に変える
}
これでFXコントローラーのカスタムができるようになりました
FXコントローラーを追加する
先ほどカスタム状態にしたFXLayerの中にFXコントローラーを追加していきます
コードは先ほど作ったif文の中に書きます
初めにFXコントローラーをコピーする
コピーはAssetDatabase.CopyAssetを使用します
使い方はこの通りです
AssetDatabase.CopyAsset("コピー元のパス" , "コピー後のパス");
これに先ほど準備したパス変数を書いていきます
コピー元のパスはcopyFXLayer
コピー後のパスはcreateFXLayer
ですがコピー後のパスcreateFXLayerはこのままでは使用できないのでアバターごとに作成されるようにアバターの名前を追加して作成するようにします
今回はこのようにします
コピー後のパス + "アバターの名前" + コントローラーの拡張子
createFXPath + "/" + avatar.name + "_HandsLayer.controller"
これを使用してコードを書いていきます
今回のコードはこうなります
AssetDatabase.CopyAsset(copyFXPath, createFXPath + "/" + avatar.name + "_HandsLayer.controller");
これでFxLayerにコントローラーが作成されました
FXコントローラーを追加する
FXLayer.Controllerの取得はavatarDescriptor.baseAnimationLayers[4].animatorControllerを使用して取得できます
取得したFXコントローラーにコントローラーを入れる
取得したFXコントローラーにコントローラーを入れるにはAssetからロードする必要があるので
AssetDatabase.LoadAssetAtPathを使用します
書き方はこの通りです
AssetDatabase.LoadAssetAtPath("ロードするファイルのパス", "オブジェクトのタイプ")
ロードするファイルのパスは先ほど書いた
createFXPath + "/" + avatar.name + "_HandsLayer.controller"
を利用します
オブジェクトタイプはRuntimeAnimatorControllerです
上記のFXコントローラーを追加する、を組み合わせて書いていきます
今回はこのようになりました
avatarDescriptor.baseAnimationLayers[4].animatorController = AssetDatabase.LoadAssetAtPath(createFXPath + "/" + avatar.name + "_HandsLayer.controller", typeof(RuntimeAnimatorController))
前回と同じようにこのままでは変換ができないのでキャストを用意します
コードの末尾にas RuntimeAnimatorControllerを追加します
これでコードが完成しました
4.ボタンを押すと処理が行われるようにする
ボタンに条件を付ける
条件が真・偽であればボタンを表示させるコードをOnGUIの中に書いていきます
今回はまずavatarが入っているかをif文で判定し、真だった場合にVRCAvatarDescriptorが入っているか、いないかをif文で判定してボタンを表示できるようにします
真の場合はSetupFXLayer()を実行
偽の場合はAddDescriptor()を実行します
判定用のif文ができたらボタンの表示名を適当につけてボタンを作ります
ボタンができたらコードはこんな感じになると思います
if (avatar)
{
if (avatar.GetComponent<VRCAvatarDescriptor>())
{
if (GUILayout.Button("アバターのFXLayerをセットアップする"))
{
}
}
else
{
if (GUILayout.Button("アバターにVRCAvatarDescriptorを入れる"))
{
}
}
}
ボタンでメソッドを呼び出すようにする
今回作ったメソッド二つをボタンのif文の中に追加していきます
今回作ったメソッドは
AddDescriptorとSetupFXLayerなので引数なしで呼び出していきます
コードはこうなります
if (avatar)
{
if (avatar.GetComponent<VRCAvatarDescriptor>())
{
if (GUILayout.Button("アバターのFXLayerをセットアップする"))
{
SetupFXLayer();
}
}
else
{
if (GUILayout.Button("アバターにVRCAvatarDescriptorを入れる"))
{
AddDescriptor();
}
}
}
これで呼び出せるようになりました
5.動作確認をする
まずはCtrl + Sを押してスクリプトを保存しましょう
次にUnityに戻って動作確認します
準備
準備として、空のオブジェクトをヒエラルキーに作成します
分かりやすくするために名前はAvatarなどに変更しましょう
これで準備ができました
動作確認
TestEditorを開きます
EditorのAvatarにゲームオブジェクトのAvatarをセットしましょう
セットができたらアバターにVRCAvatarDescriptorを入れるを押してみましょう
押したら一度AvatarのInspectorに移りVRCAavatarDescriptorが入っているのが確認します
VRCAavatarDescriptorが入っているのを確認できたと思います
確認ができたらもう一度Editorに戻りアバターのFXLayerをセットアップするを押します
押したらもう一度AvatarのInspectorに移りFXLayerをセットアップされているか確認します
確認ができたら今回は終了です
※連続で押すとVRCAvatarDescriptorが生成される前に操作してしまいエラーが出ることがあります
6.次回
次回はExMenuとExParameterを自動でセットアップするEditorを作っていこうかなと思います