Motion
最終更新: 2024年11月28日
概要
Motionを使用することで、UnityのMecanimでステートマシンを組まずにスクリプトからアニメーションを再生することができます。
Motionを使用するにはCubismFadeControllerコンポーネントとUnityのAnimatorが必要です。
AnimatorコンポーネントにAnimatorControllerを設定した場合、Motionは再生されずにAnimatorControllerのアニメーションが再生されます。
該当のチュートリアル記事は スクリプトからモーションを再生させる をご覧ください。
Motionは以下の処理を行っています。
- PlayableGraphを作成
- CubismMotionLayerを作成
- アニメーション再生
- アニメーション停止
PlayableGraphを作成
PlayableGraphはアニメーションなどを出力するためのものです。
こちらの詳細は、Unity公式のドキュメントをご覧ください。
// Animator側のPlayableGraphを無効 var graph = animator.playableGraph; if(graph.IsValid()) { graph.GetOutput(0).SetWeight(0); } // PlayableGraphを作成 _playableGraph = PlayableGraph.Create("Playable Graph : " + this.FindCubismModel().name); _playableGraph.SetTimeUpdateMode(DirectorUpdateMode.GameTime); // 結果出力用のPlayable作成 _playableOutput = AnimationPlayableOutput.Create(_playableGraph, "Animation", animator); _playableOutput.SetWeight(1); // レイヤーを合成するPlayable作成 _layerMixer = AnimationLayerMixerPlayable.Create(_playableGraph, LayerCount); // デフォルト出力先を設定 _playableOutput.SetSourcePlayable(_layerMixer);
この処理はCubismMotionController.OnEnable()で行っています。
CubismMotionLayerを作成
CubismMotionLayerを利用すると、複数のモーションを並列して再生させることができます。
// Create cubism motion layers. _motionLayers = new CubismMotionLayer[LayerCount]; for(var i = 0; i < LayerCount; ++i) { _motionLayers[i] = CubismMotionLayer.CreateCubismMotionLayer(_playableGrap, _cubismFadeMotionList); _motionLayers[i].AnimationEndHandler += OnAnimationEnd; _layerMixer.ConnectInput(i, _motionLayers[i].PlayableOutput, 0); _layerMixer.SetInputWeight(i, 1.0f); }
この処理はCubismMotionController.OnEnable()で行っています。
複数のレイヤーでモーションを同時に再生させたときに、それらが同一のCubismParameter.Valueを操作すると、後に設定される値で上書きされます。
上書きするウェイトは、CubismMotionLayer.SetLayerWeight(float weight)で設定することができます。
CubismMotionLayerにウェイトを設定した場合、AnimationLayerMixerPlayableにも同時にウェイトを設定する必要があります。
AnimationLayerMixerPlayableの詳細は、Unity公式のドキュメントをご覧ください。
_motionLayers[layerIndex].SetLayerWeight(weight); _layerMixer.SetInputWeight(layerIndex, weight);
アニメーション再生
CubismMotionController.PlayAnimation(AnimationClip clip, int layerIndex = 0, int priority = CubismMotionPriority.PriorityNormal, bool isLoop = true, float speed = 1.0f) を使うことで、アニメーションの再生ができます。
- AnimationClip clip:再生するアニメーションクリップ。
- int layerIndex:アニメーション再生レイヤーのインデックス。
- int priority:再生するアニメーションの優先度。現在再生されているアニメーションに差し込んで再生させる場合、そのアニメーションに設定されたpriorityよりも大きな値にする。
- bool isLoop:アニメーションはループ再生かどうか、デフォルトはループ再生。
- float speed:アニメーションの再生速度、範囲は0以上、デフォルトは1(通常の再生速度)。
アニメーション停止
指定インデックスのアニメーションを停止する場合は CubismMotionController.StopAnimation(int animationIndex, int layerIndex = 0) を使います。
- int animationIndex:停止するアニメーションのインデックス。
- int layerIndex:停止するアニメーションのレイヤーインデックス。
すべてのアニメーションを停止する場合は CubismMotionController.StopAllAnimation() を使います。
アニメーション再生時と停止時のコールバック
Cubism SDK for Unity ではアニメーション再生時とアニメーション停止時にコールバックによるイベント取得を行えます。
アニメーション再生時のコールバック
アニメーション再生時にコールバックを受け取るサンプルコードは下記です。モデルが事前にインポートされていることを前提としています。
private CubismMotionController _motionController; private CubismFadeMotionList _cubismFadeMotionList; // Start is called before the first frame update private void Start() { _motionController = GetComponent<CubismMotionController>(); _cubismFadeMotionList = GetComponent<CubismFadeController>().CubismFadeMotionList; _motionController.AnimationBeginHandler += OnAnimationBegin; } private void OnAnimationBegin(int instanceId) { if (!_cubismFadeMotionList) { return; } for (int i = 0; i < _cubismFadeMotionList.MotionInstanceIds.Length; i++) { if (_cubismFadeMotionList.MotionInstanceIds[i] != instanceId) { continue; } Debug.Log("StartedMotion: " + _cubismFadeMotionList.CubismFadeMotionObjects[i].MotionName); break; } }
このコードでは CubismMotionController.AnimationBeginHandler
に自身で作成した OnAnimationBegin()
関数を登録します。
Tips
以下の状態では再生時のコールバックは動作しません。
- コールバックにnullが登録されているとき
アニメーション終了時のコールバック
アニメーション再生時にコールバックを受け取るサンプルコードは下記です。
private CubismMotionController _motionController; private CubismFadeMotionList _cubismFadeMotionList; // Start is called before the first frame update void Start() { _motionController = GetComponent<CubismMotionController>(); _cubismFadeMotionList = GetComponent<CubismFadeController>().CubismFadeMotionList; _motionController.AnimationEndHandler += OnAnimationEnd; } void OnAnimationEnd(int instanceId) { if (!_cubismFadeMotionList) { return; } for (int i = 0; i < _cubismFadeMotionList.MotionInstanceIds.Length; i++) { if (_cubismFadeMotionList.MotionInstanceIds[i] != instanceId) { continue; } Debug.Log("EndedMotion: " + _cubismFadeMotionList.CubismFadeMotionObjects[i].MotionName); break; } }
このコードでは CubismMotionController.AnimationEndHandler
に自身で作成した OnAnimationEnd()
関数を登録します。
アニメーションの再生終了時あるいは停止時にこのコールバックは呼び出されます。
Tips
以下の状態では終了時のコールバックが呼び出せないのでご注意ください
- 再生中のモーションが「ループ」として設定されているとき
- コールバックにnullが登録されているとき