123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- /**
- * 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 Live2D.Cubism.Core;
- using Live2D.Cubism.Framework.MotionFade;
- using System.Collections.Generic;
- using UnityEngine;
- namespace Live2D.Cubism.Framework.Expression
- {
- /// <summary>
- /// Expression controller.
- /// </summary>
- public class CubismExpressionController : MonoBehaviour, ICubismUpdatable
- {
- #region variable
- /// <summary>
- /// Expressions data list.
- /// </summary>
- [SerializeField]
- public CubismExpressionList ExpressionsList;
- /// <summary>
- /// CubismModel cache.
- /// </summary>
- private CubismModel _model = null;
- /// <summary>
- /// Playing expressions.
- /// </summary>
- private List<CubismPlayingExpression> _playingExpressions = new List<CubismPlayingExpression>();
- /// <summary>
- /// Playing expressions index.
- /// </summary>
- [SerializeField]
- public int CurrentExpressionIndex = -1;
- /// <summary>
- /// Last playing expressions index.
- /// </summary>
- private int _lastExpressionIndex = -1;
- /// <summary>
- /// Model has update controller component.
- /// </summary>
- [HideInInspector]
- public bool HasUpdateController { get; set; }
- #endregion
- /// <summary>
- /// Add new expression to playing expressions.
- /// </summary>
- private void StartExpression()
- {
- // Fail silently...
- if(ExpressionsList == null || ExpressionsList.CubismExpressionObjects == null)
- {
- return;
- }
- // Backup expression.
- _lastExpressionIndex = CurrentExpressionIndex;
- // Set last expression end time
- if(_playingExpressions.Count > 0)
- {
- var playingExpression = _playingExpressions[_playingExpressions.Count - 1];
- playingExpression.ExpressionEndTime = playingExpression.ExpressionUserTime + playingExpression.FadeOutTime;
- _playingExpressions[_playingExpressions.Count - 1] = playingExpression;
- }
- // Fail silently...
- if(CurrentExpressionIndex < 0 || CurrentExpressionIndex >= ExpressionsList.CubismExpressionObjects.Length)
- {
- return;
- }
- var palyingExpression = CubismPlayingExpression.Create(_model, ExpressionsList.CubismExpressionObjects[CurrentExpressionIndex]);
- if(palyingExpression == null)
- {
- return;
- }
- // Add to PlayingExList.
- _playingExpressions.Add(palyingExpression);
- }
- /// <summary>
- /// Called by cubism update controller. Order to invoke OnLateUpdate.
- /// </summary>
- public int ExecutionOrder
- {
- get { return CubismUpdateExecutionOrder.CubismExpressionController; }
- }
- /// <summary>
- /// Called by cubism update controller. Needs to invoke OnLateUpdate on Editing.
- /// </summary>
- public bool NeedsUpdateOnEditing
- {
- get { return false; }
- }
- /// <summary>
- /// Called by cubism update manager.
- /// </summary>
- public void OnLateUpdate()
- {
- // Fail silently...
- if(!enabled || _model == null)
- {
- return;
- }
- // Start expression when current expression changed.
- if(CurrentExpressionIndex != _lastExpressionIndex)
- {
- StartExpression();
- }
- // Update expression
- for(var expressionIndex = 0; expressionIndex < _playingExpressions.Count; ++expressionIndex)
- {
- var playingExpression = _playingExpressions[expressionIndex];
- // Update expression user time.
- playingExpression.ExpressionUserTime += Time.deltaTime;
- // Update weight
- var fadeIn = (Mathf.Abs(playingExpression.FadeInTime) < float.Epsilon)
- ? 1.0f
- : CubismFadeMath.GetEasingSine(playingExpression.ExpressionUserTime / playingExpression.FadeInTime);
- var fadeOut = ((Mathf.Abs(playingExpression.ExpressionEndTime) < float.Epsilon) || (playingExpression.ExpressionEndTime < 0.0f))
- ? 1.0f
- : CubismFadeMath.GetEasingSine(
- (playingExpression.ExpressionEndTime - playingExpression.ExpressionUserTime) / playingExpression.FadeOutTime);
- playingExpression.Weight = fadeIn * fadeOut;
- // Apply value.
- for(var i = 0; i < playingExpression.Destinations.Length; ++i)
- {
- // Fail silently...
- if(playingExpression.Destinations[i] == null)
- {
- continue;
- }
- switch(playingExpression.Blend[i])
- {
- case CubismParameterBlendMode.Additive:
- playingExpression.Destinations[i].AddToValue(playingExpression.Value[i], playingExpression.Weight);
- break;
- case CubismParameterBlendMode.Multiply:
- playingExpression.Destinations[i].MultiplyValueBy(playingExpression.Value[i], playingExpression.Weight);
- break;
- case CubismParameterBlendMode.Override:
- playingExpression.Destinations[i].Value = playingExpression.Destinations[i].Value * (1 - playingExpression.Weight) + (playingExpression.Value[i] * playingExpression.Weight);
- break;
- default:
- // When an unspecified value is set, it is already in addition mode.
- break;
- }
- }
- // Apply update value
- _playingExpressions[expressionIndex] = playingExpression;
- }
- // Remove expression from playing expressions
- for(var expressionIndex = _playingExpressions.Count - 1; expressionIndex >= 0; --expressionIndex)
- {
- if(_playingExpressions[expressionIndex].Weight > 0.0f)
- {
- continue;
- }
- _playingExpressions.RemoveAt(expressionIndex);
- }
- }
- #region Unity Event Handling
- /// <summary>
- /// Called by Unity.
- /// </summary>
- private void OnEnable()
- {
- _model = this.FindCubismModel();
- // Get cubism update controller.
- HasUpdateController = (GetComponent<CubismUpdateController>() != null);
- }
- /// <summary>
- /// Called by Unity.
- /// </summary>
- private void LateUpdate()
- {
- if(!HasUpdateController)
- {
- OnLateUpdate();
- }
- }
- #endregion
- }
- }
|