MRDesignLab の Button で MMD のモーションを制御したい
※ これは 2017/10/21 MixedRealityToolkit-Unity for Unity 2017.2.0f3 時点の情報です
最新版では動作が異なる可能性がありますのでご注意ください
BoundingBox の次は Button を配置してみたい
MRDesiginLab に含まれる CompoundButton でサーバルちゃんのモーションの再生と停止を制御してみます
まずはモーション制御の仕組みを作るため、Surval オブジェクトにアタッチしていた Animation Controller をダブルクリックし Animator ビューを開きます
Unity の Animator ビューでは状態遷移図のような設定画面でアニメーションの遷移を設定できるのでこちらを利用します
Animation Controller を開くとアニメーションが再生される nekomimi_lat_vmd のステートが Entry ステートから直接遷移していました
ここに待機状態のステートを追加して間にはさみ、条件によって nekomimi_lat_vmd のステートを行き来するように変更します
適当な箇所を右クリックして [Create State]-[Empty] のコンテキストメニューを選びます
新しいステートが追加されるので、名前を Idle に変更
できた Idle ステートを選択し、コンテキストメニューから Set as Layer Default State を選び、初期ステートを nekomimi_lat_vmd から Idle に変更します
さらに Idle のコンテキストメニューから Make Transition を選び、表示される矢印を nekomimi_lat_vmd につなぎます
同様に nekomimi_lat_vmd からも Make Transition で Idle に矢印をつなぎ双方向に遷移を設定してます
ここでモーション再生/停止の切り替えるための条件フラグを追加するため、Animator ビューの左上のほうにある Parameters タブを選択、+ ボタンから新しく Bool の変数を追加し名前を「Playing」としておきます
次に Idle → nekomimi_lat_vmd の遷移矢印を選択し、Conditions のエリアの右下 + ボタンで条件を追加、先ほど追加した Playing を選択し、値を true の場合に指定します
同様に nekomimi_lat_vmd → Idle の遷移矢印を選択し、Conditions のエリアの右下 + ボタンで条件を追加、先ほど追加した Playing を選択し、値を false の場合に指定します
モーション再生途中でも切り替わるように Has Exit Time のチェックは外しておきます
モーション制御の準備はできたので、今度は CompoundButton を追加します
Project ビューの MRDesignLab/HUX/Prefab/Buttons/CircleButton の Prefab を選択し、Hierarchy ビュー上にドラッグドロップで配置します
名前は PlayButton に変更し、サーバルちゃんの前あたりに表示座標を調整
さらにこの PlayButton を選択し、Inspector ビュー上の Icon として「!」マークを選択します
この PlayButton を Duplicate のコンテキストメニューで複製し、名前を StopButton に変更
こちらも Icon を × のマークに設定しました
また、PlayButton、StopButton の入力を制御するため、Hierarchy ビューのコンテキストメニューから Create Empty を選んで空の GameObject を作成し、名前を Reciever とします
この Reciever の Inspector ビューから Add Component ボタンで New Script を選び、SurvalInteractionReceiver という名前で C# のスクリプトファイルを作成しアタッチします
この SurvalInteractionReceiver .cs の記述は下記の通り
using HUX.Interaction; using HUX.Receivers; using UnityEngine; public class SurvalInteractionReceiver : InteractionReceiver { /// <summary> /// アニメーションコントローラー /// </summary> [SerializeField] private Animator animator = null; /// <summary> /// Play ボタン /// </summary> public GameObject PlayButton { get { return this.Interactibles[0]; } } /// <summary> /// Stop ボタン /// </summary> public GameObject StopButton { get { return this.Interactibles[1]; } } /// <summary> /// 初期処理 /// </summary> public void Awake() { this.PlayButton.SetActive(true); this.StopButton.SetActive(false); } /// <summary> /// タップイベントハンドラ /// </summary> /// <param name="obj">イベント発行者</param> /// <param name="eventArgs">イベント引数</param> protected override void OnTapped(GameObject obj, InteractionManager.InteractionEventArgs eventArgs) { switch (obj.name) { case "PlayButton": this.PlayButton.SetActive(false); this.StopButton.SetActive(true); this.animator.SetBool("Playing", true); break; case "StopButton": this.animator.SetBool("Playing", false); this.StopButton.SetActive(false); this.PlayButton.SetActive(true); break; } } }
MRDesignLab の InteractionReceiver を継承し、OnTaped イベントハンドラだけ override して Animator の Playing フラグによって PlayButton と StopButton によるモーション制御、各ボタンの表示切替を行うようにしました
最後にこの SurvalInteractionReceiver に対し、Surval オブジェクトにアタッチされた Animator、ドラッグドロップで設定し、さらに Interactibles の Size を 2 に増やし、Element 0 に PlayButton、Element 1 に StopButton をドラッグドロップでアタッチします
これで UnityEditor 上でとりあえず動かしてみました
! ボタンをタップするとモーション再生が開始、× ボタンで停止するようになりました