/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations;
namespace Live2D.Cubism.Framework.MotionFade
{
public class CubismFadeStateObserver : StateMachineBehaviour, ICubismFadeState
{
#region variable
///
/// Cubism fade motion list.
///
private CubismFadeMotionList _cubismFadeMotionList;
///
/// Cubism playing motion list.
///
private List _playingMotions;
///
/// State that attached this is default.
///
private bool _isDefaulState;
///
/// Layer index that attached this.
///
private int _layerIndex;
///
/// Weight of layer that attached this.
///
private float _layerWeight;
///
/// State that attached this is transition finished.
///
private bool _isStateTransitionFinished;
#endregion
#region Fade State Interface
///
/// Get cubism playing motion list.
///
/// Cubism playing motion list.
public List GetPlayingMotions()
{
return _playingMotions;
}
///
/// Is default state.
///
/// State is default; otherwise.
public bool IsDefaultState()
{
return _isDefaulState;
}
///
/// Get layer weight.
///
/// Layer weight.
public float GetLayerWeight()
{
return _layerWeight;
}
///
/// Get state transition finished.
///
/// State transition is finished; otherwise.
public bool GetStateTransitionFinished()
{
return _isStateTransitionFinished;
}
///
/// Set state transition finished.
///
/// State is finished.
public void SetStateTransitionFinished(bool isFinished)
{
_isStateTransitionFinished = isFinished;
}
///
/// Stop animation.
///
/// Playing motion index.
public void StopAnimation(int index)
{
_playingMotions.RemoveAt(index);
}
#endregion
#region Unity Event Handling
///
/// Called by Unity.
///
private void OnEnable()
{
_isStateTransitionFinished = false;
if (_playingMotions == null)
{
_playingMotions = new List();
}
}
///
/// Called by Unity.
///
/// Animator.
/// Animator state info.
/// Index of the layer.
/// Animation controller playable.
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex, AnimatorControllerPlayable controller)
{
if (animator.gameObject.name == "kp_zuochi2")
{
}
var fadeController = animator.gameObject.GetComponent();
// Fail silently...
if (fadeController == null)
{
return;
}
_cubismFadeMotionList = fadeController.CubismFadeMotionList;
_layerIndex = layerIndex;
_layerWeight = (_layerIndex == 0)
? 1.0f
: animator.GetLayerWeight(_layerIndex);
var animatorClipInfo = controller.GetNextAnimatorClipInfo(layerIndex);
_isDefaulState = (animatorClipInfo.Length == 0);
if (_isDefaulState)
{
// Get the motion of Default State only for the first time.
animatorClipInfo = controller.GetCurrentAnimatorClipInfo(layerIndex);
}
// Set playing motions end time.
if ((_playingMotions.Count > 0) && (_playingMotions[_playingMotions.Count - 1].Motion != null))
{
var motion = _playingMotions[_playingMotions.Count - 1];
var time = Time.time;
var newEndTime = time + motion.Motion.FadeOutTime;
motion.EndTime = newEndTime;
while (motion.IsLooping)
{
if ((motion.StartTime + motion.Motion.MotionLength) >= time)
{
break;
}
motion.StartTime += motion.Motion.MotionLength;
}
_playingMotions[_playingMotions.Count - 1] = motion;
}
for (var i = 0; i < animatorClipInfo.Length; ++i)
{
CubismFadePlayingMotion playingMotion;
var instanceId = -1;
var events = animatorClipInfo[i].clip.events;
for (var k = 0; k < events.Length; ++k)
{
if (events[k].functionName != "InstanceId")
{
continue;
}
instanceId = events[k].intParameter;
break;
}
var motionIndex = -1;
for (var j = 0; j < _cubismFadeMotionList.MotionInstanceIds.Length; ++j)
{
if (_cubismFadeMotionList.MotionInstanceIds[j] != instanceId)
{
continue;
}
motionIndex = j;
break;
}
if (animator.gameObject.name == "kp_zuochi2")
{
Debug.Log("zoya000:" + motionIndex);
Debug.Log("zoya111:" + _cubismFadeMotionList.CubismFadeMotionObjects[motionIndex]);
}
playingMotion.Motion = (motionIndex == -1)
? null
: _cubismFadeMotionList.CubismFadeMotionObjects[motionIndex];
Debug.Log("zoya:" + playingMotion.Motion);
playingMotion.Speed = 1.0f;
playingMotion.StartTime = Time.time;
playingMotion.FadeInStartTime = Time.time;
playingMotion.EndTime = (playingMotion.Motion.MotionLength <= 0)
? -1
: playingMotion.StartTime + playingMotion.Motion.MotionLength;
playingMotion.IsLooping = animatorClipInfo[i].clip.isLooping;
playingMotion.Weight = 0.0f;
_playingMotions.Add(playingMotion);
}
}
///
/// Called by Unity.
///
/// Animator.
/// Animator state info.
/// Index of the layer.
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
_isStateTransitionFinished = true;
}
#endregion
}
}