/** * 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 UnityEngine; namespace Live2D.Cubism.Framework.HarmonicMotion { /// /// Controller for s. /// public sealed class CubismHarmonicMotionController : MonoBehaviour, ICubismUpdatable { /// /// Default number of channels. /// private const int DefaultChannelCount = 1; /// /// Blend mode. /// [SerializeField] public CubismParameterBlendMode BlendMode = CubismParameterBlendMode.Additive; /// /// The timescales for each channel. /// [SerializeField] public float[] ChannelTimescales; /// /// Sources. /// private CubismHarmonicMotionParameter[] Sources { get; set; } /// /// Destinations. /// private CubismParameter[] Destinations { get; set; } /// /// Model has update controller component. /// [HideInInspector] public bool HasUpdateController { get; set; } /// /// Refreshes the controller. Call this method after adding and/or removing . /// public void Refresh() { var model = this.FindCubismModel(); // Catch sources and destinations. Sources = model .Parameters .GetComponentsMany(); Destinations = new CubismParameter[Sources.Length]; for (var i = 0; i < Sources.Length; ++i) { Destinations[i] = Sources[i].GetComponent(); } // Get cubism update controller. HasUpdateController = (GetComponent() != null); } /// /// Called by cubism update controller. Order to invoke OnLateUpdate. /// public int ExecutionOrder { get { return CubismUpdateExecutionOrder.CubismHarmonicMotionController; } } /// /// Called by cubism update controller. Needs to invoke OnLateUpdate on Editing. /// public bool NeedsUpdateOnEditing { get { return false; } } /// /// Called by cubism update controller. Updates controller. /// public void OnLateUpdate() { // Return if it is not valid or there's nothing to update. if (!enabled || Sources == null) { return; } // Update sources and destinations. for (var i = 0; i < Sources.Length; ++i) { Sources[i].Play(ChannelTimescales); Destinations[i].BlendToValue(BlendMode, Sources[i].Evaluate()); } } #region Unity Events Handling /// /// Called by Unity. Makes sure cache is initialized. /// private void Start() { // Initialize cache. Refresh(); } /// /// Called by Unity. Updates controller. /// private void LateUpdate() { if (!HasUpdateController) { OnLateUpdate(); } } /// /// Called by Unity. Resets channels. /// private void Reset() { // Reset/Initialize channel timescales. ChannelTimescales = new float[DefaultChannelCount]; for (var s = 0; s < DefaultChannelCount; ++s) { ChannelTimescales[s] = 1f; } } #endregion } }