/**
* 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;
using Live2D.Cubism.Core;
using Live2D.Cubism.Rendering;
using Live2D.Cubism.Rendering.Masking;
using UnityEngine;
namespace Live2D.Cubism.Framework.Physics
{
///
/// Physics simulation controller.
///
[CubismMoveOnReimportCopyComponentsOnly]
public class CubismPhysicsController : MonoBehaviour, ICubismUpdatable
{
///
/// Simulation target rig.
///
private CubismPhysicsRig Rig
{
get { return _rig; }
set { _rig = value; }
}
[SerializeField]
private CubismPhysicsRig _rig;
///
/// Cubism model parameters for simulation.
///
public CubismParameter[] Parameters { get; private set; }
///
/// Model has update controller component.
///
[HideInInspector]
public bool HasUpdateController { get; set; }
public int ExecutionOrder
{
get { return CubismUpdateExecutionOrder.CubismPhysicsController; }
}
public bool NeedsUpdateOnEditing
{
get { return false; }
}
public void OnLateUpdate()
{
if (!enabled)
{
return;
}
var deltaTime = Time.deltaTime;
// Use fixed delta time if required.
if (CubismPhysics.UseFixedDeltaTime)
{
deltaTime = Time.fixedDeltaTime;
}
// Evaluate rig.
Rig.Evaluate(deltaTime);
}
///
/// Calculate until the physics is stable and update the model information.
///
public void Stabilization()
{
Rig.Stabilization();
var renderController = gameObject.GetComponent();
var maskController = gameObject.GetComponent();
renderController.OnLateUpdate();
if (maskController)
{
maskController.OnLateUpdate();
}
}
///
/// Sets rig and initializes .
///
///
public void Initialize(CubismPhysicsRig rig)
{
Rig = rig;
Awake();
}
///
/// Set to the ratio by the argument to the original value.
///
///
/// Ratio to original value
public void SetPhysicsSubRigOutputAngleScaleRatio(CubismPhysicsSubRig subRig, float ratio)
{
if (subRig == null)
{
return;
}
for (int i = 0; i < subRig.Output.Length; i++)
{
var original = subRig.OriginalOutput[i];
subRig.Output[i].AngleScale = Math.Max(original.AngleScale * ratio, 0);
subRig.Output[i].InitializeGetter();
}
}
///
/// Set whether or not to invert for the original bool value.
///
///
/// Invert the original bool value
public void SetPhysicsSubRigOutputIsInverted(CubismPhysicsSubRig subRig, bool isInvert)
{
if (subRig == null)
{
return;
}
for (int i = 0; i < subRig.Output.Length; i++)
{
var original = subRig.OriginalOutput[i];
subRig.Output[i].IsInverted = isInvert ? !original.IsInverted : original.IsInverted;
subRig.Output[i].InitializeGetter();
}
}
#region Unity Event Handling
///
/// Called by Unity or . Initializes if exists.
///
public void Awake()
{
// Check rig existence.
if (Rig == null)
{
return;
}
// Initialize rig.
Rig.Controller = this;
for (var i = 0; i < Rig.SubRigs.Length; ++i)
{
Rig.SubRigs[i].Rig = Rig;
}
Parameters = this.FindCubismModel().Parameters;
Rig.Initialize();
}
///
/// Called by Unity.
///
public void Start()
{
// Get cubism update controller.
HasUpdateController = (GetComponent() != null);
}
///
/// Called by Unity. Updates controller.
///
/// Must be call after animation update.
private void LateUpdate()
{
if (!HasUpdateController)
{
OnLateUpdate();
}
}
#endregion
}
}