前に書いたLive2DのモーションをMecanim制御するですが、ちょっとバグってました。
Mecanimのparameter値を変えた瞬間には、次のモーションファイル名が取得できておらず前のモーションファイル名を取得してた...。
この問題ですが、Unity5から追加されたState Machine Behavioursで解決できました。
State Machine Behavioursは、コードからMecanimのState作成できたり、状態遷移タイミングを細かく取得できるものです。
State Machine Behavioursで制御する手順
今回もLive2D Unity SDKのMotionプロジェクトを使っていきます。
(sample\Motion\Assets\Scene\Sample.unity)
2)[Assets]-[Create]からAnimator Controllerを作成し、アタッチする
3)HirarchyでLive2DModelを選択した状態で、[Window]-[Animation]を開き[Create New Clip]で新規Animationを2つ作る。
1つはidle.anim、もう1つはmotion1.animとしておく。
4)Add Propertyボタン押下し、Motion Fileの+ボタン押下する
5)1:00のキーフレームはDeleteし、0:00の方を選択し、InspectorのMotion Fileを指定します
8)Transitionの矢印を選択し、Motion=1の時はmotion1へ、Motion=0の時はidleへ行くようにする
9)AnimatorのBase LayerのInspectorでAdd Behaviourボタン押下し、Scriptを作る
10)SteteMachineソースを以下のようにする
using UnityEngine;
using System.Collections;
public class MotionBehaviour : StateMachineBehaviour {
public bool changeflg = false; // モーションチェンジフラグ
// 次のステートに移り変わる直前に実行される
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
changeflg = true;
}
}
11)メインのソースも以下のように修正する
using UnityEngine;
using System;
using System.IO;
using System.Collections;
using live2d;
[ExecuteInEditMode]
public class SimpleModel: MonoBehaviour
{
private Live2DModelUnity live2DModel;
private Live2DMotion motion;
private MotionQueueManager motionMgr;
private Matrix4x4 live2DCanvasPos;
public TextAsset mocFile ;
public Texture2D[] textureFiles ;
public TextAsset motionFile;
private Animator anim; // Animator
private MotionBehaviour mtnBehaviour; // MotionBehaviour
void Start ()
{
Live2D.init();
// Animatorを取得
anim = GetComponent<Animator>();
// State Machine Behavioursを取得
mtnBehaviour = anim.GetBehaviour<MotionBehaviour>();
live2DModel = Live2DModelUnity.loadModel(mocFile.bytes);
for (int i = 0; i < textureFiles.Length; i++)
{
live2DModel.setTexture(i, textureFiles[i]);
}
float modelWidth = live2DModel.getCanvasWidth();
live2DCanvasPos = Matrix4x4.Ortho(0, modelWidth, modelWidth, 0, -50.0f, 50.0f);
motionMgr = new MotionQueueManager();
motion = Live2DMotion.loadMotion(motionFile.bytes);
}
void OnRenderObject()
{
if (live2DModel == null) return;
live2DModel.setMatrix(transform.localToWorldMatrix * live2DCanvasPos);
if ( ! Application.isPlaying)
{
live2DModel.update();
live2DModel.draw();
return;
}
// モーションが終了していたら or フラグが更新されていたら
if (motionMgr.isFinished() || mtnBehaviour.changeflg == true)
{
// モーションのロード
motion = Live2DMotion.loadMotion(motionFile.bytes);
// モーションスタート
motionMgr.startMotion(motion);
// フラグをOFFにする
mtnBehaviour.changeflg = false;
}
motionMgr.updateParam(live2DModel);
live2DModel.update();
live2DModel.draw();
}
}
###参考にしたページ
・Unity Document - State Machine Behaviourとは
・Unity Document - State Machine Behaviour
・Unity5.0の新しいアニメーション機能
・Mecanimを使ってユニティちゃんを動かしてみた、で出た疑問点を解消していく
・Unity5 MecanimのStateMachineBehaviourと戯れる