LoginSignup
10
10

More than 5 years have passed since last update.

Live2DモーションをStateMachineBehaviours制御

Last updated at Posted at 2015-05-11

前に書いたLive2DのモーションをMecanim制御するですが、ちょっとバグってました。
01.png

Mecanimのparameter値を変えた瞬間には、次のモーションファイル名が取得できておらず前のモーションファイル名を取得してた...。

この問題ですが、Unity5から追加されたState Machine Behavioursで解決できました。
State Machine Behavioursは、コードからMecanimのState作成できたり、状態遷移タイミングを細かく取得できるものです。

State Machine Behavioursで制御する手順

今回もLive2D Unity SDKのMotionプロジェクトを使っていきます。
(sample\Motion\Assets\Scene\Sample.unity)

1)Live2DモデルにAnimatorを追加します
02.png

2)[Assets]-[Create]からAnimator Controllerを作成し、アタッチする
03.png

3)HirarchyでLive2DModelを選択した状態で、[Window]-[Animation]を開き[Create New Clip]で新規Animationを2つ作る。
04.png

1つはidle.anim、もう1つはmotion1.animとしておく。

4)Add Propertyボタン押下し、Motion Fileの+ボタン押下する
05.png

5)1:00のキーフレームはDeleteし、0:00の方を選択し、InspectorのMotion Fileを指定します
06.png

07.png

6)もう1つのモーションも同様にする
08.png

09.png

7)MakeTransitionでつないでパラメータを作る
10.png

8)Transitionの矢印を選択し、Motion=1の時はmotion1へ、Motion=0の時はidleへ行くようにする
11.png

12.png

9)AnimatorのBase LayerのInspectorでAdd Behaviourボタン押下し、Scriptを作る
13.png

10)SteteMachineソースを以下のようにする

MotionBehaviour.cs
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)メインのソースも以下のように修正する

SimpleModel.cs
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();
    }
}

12)これで瞬時にモーションが切り替わるようになりました!
motion.gif

参考にしたページ

Unity Document - State Machine Behaviourとは
Unity Document - State Machine Behaviour
Unity5.0の新しいアニメーション機能
Mecanimを使ってユニティちゃんを動かしてみた、で出た疑問点を解消していく
Unity5 MecanimのStateMachineBehaviourと戯れる

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10