/** * 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 } }