live2D (sdk가 6.5 미지원으로 sprite로 대응)
This commit is contained in:
274
Assets/Live2D/Cubism/Framework/Pose/CubismPoseController.cs
Normal file
274
Assets/Live2D/Cubism/Framework/Pose/CubismPoseController.cs
Normal file
@@ -0,0 +1,274 @@
|
||||
/**
|
||||
* 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 System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Live2D.Cubism.Framework.Pose
|
||||
{
|
||||
/// <summary>
|
||||
/// Cubism pose controller.
|
||||
/// </summary>
|
||||
public sealed class CubismPoseController : MonoBehaviour, ICubismUpdatable
|
||||
{
|
||||
#region variable
|
||||
|
||||
/// <summary>
|
||||
/// Default visible pose index.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public int defaultPoseIndex = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Back opacity threshold.
|
||||
/// </summary>
|
||||
private const float BackOpacityThreshold = 0.15f;
|
||||
|
||||
/// <summary>
|
||||
/// Cubism model cache.
|
||||
/// </summary>
|
||||
private CubismModel _model;
|
||||
|
||||
/// <summary>
|
||||
/// Model has update controller component.
|
||||
/// </summary>
|
||||
[HideInInspector]
|
||||
public bool HasUpdateController { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pose data.
|
||||
/// </summary>
|
||||
private CubismPoseData[][] _poseData;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Function
|
||||
|
||||
/// <summary>
|
||||
/// update hidden part opacity.
|
||||
/// </summary>
|
||||
public void Refresh()
|
||||
{
|
||||
_model = this.FindCubismModel();
|
||||
|
||||
// Fail silently...
|
||||
if (_model == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var tags = _model
|
||||
.Parts
|
||||
.GetComponentsMany<CubismPosePart>();
|
||||
|
||||
for(var i = 0; i < tags.Length; ++i)
|
||||
{
|
||||
var groupIndex = tags[i].GroupIndex;
|
||||
var partIndex = tags[i].PartIndex;
|
||||
|
||||
if(_poseData == null || _poseData.Length <= groupIndex)
|
||||
{
|
||||
Array.Resize(ref _poseData, groupIndex + 1);
|
||||
}
|
||||
|
||||
if(_poseData[groupIndex] == null || _poseData[groupIndex].Length <= partIndex)
|
||||
{
|
||||
Array.Resize(ref _poseData[groupIndex], partIndex + 1);
|
||||
}
|
||||
|
||||
_poseData[groupIndex][partIndex].PosePart = tags[i];
|
||||
_poseData[groupIndex][partIndex].Part= tags[i].GetComponent<CubismPart>();
|
||||
|
||||
defaultPoseIndex = (defaultPoseIndex < 0) ? 0 : defaultPoseIndex;
|
||||
if (partIndex != defaultPoseIndex)
|
||||
{
|
||||
_poseData[groupIndex][partIndex].Part.Opacity = 0.0f;
|
||||
}
|
||||
|
||||
_poseData[groupIndex][partIndex].Opacity = _poseData[groupIndex][partIndex].Part.Opacity;
|
||||
|
||||
if(tags[i].Link == null || tags[i].Link.Length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_poseData[groupIndex][partIndex].LinkParts = new CubismPart[tags[i].Link.Length];
|
||||
|
||||
for(var j = 0; j < tags[i].Link.Length; ++j)
|
||||
{
|
||||
var linkId = tags[i].Link[j];
|
||||
_poseData[groupIndex][partIndex].LinkParts[j] = _model.Parts.FindById(linkId);
|
||||
}
|
||||
}
|
||||
|
||||
// Get cubism update controller.
|
||||
HasUpdateController = (GetComponent<CubismUpdateController>() != null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// update hidden part opacity.
|
||||
/// </summary>
|
||||
private void DoFade()
|
||||
{
|
||||
for(var groupIndex = 0; groupIndex < _poseData.Length; ++groupIndex)
|
||||
{
|
||||
var appearPartsGroupIndex = -1;
|
||||
var appearPartsGroupOpacity = 1.0f;
|
||||
|
||||
// Find appear parts group index and opacity.
|
||||
for (var i = 0; i < _poseData[groupIndex].Length; ++i)
|
||||
{
|
||||
var part = _poseData[groupIndex][i].Part;
|
||||
|
||||
if(part.Opacity > _poseData[groupIndex][i].Opacity)
|
||||
{
|
||||
appearPartsGroupIndex = i;
|
||||
appearPartsGroupOpacity = part.Opacity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Fail silently...
|
||||
if(appearPartsGroupIndex < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Delay disappearing parts groups disappear.
|
||||
for (var i = 0; i < _poseData[groupIndex].Length; ++i)
|
||||
{
|
||||
// Fail silently...
|
||||
if(i == appearPartsGroupIndex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var part = _poseData[groupIndex][i].Part;
|
||||
var delayedOpacity = part.Opacity;
|
||||
var backOpacity = (1.0f - delayedOpacity) * (1.0f - appearPartsGroupOpacity);
|
||||
|
||||
// When restricting the visible proportion of the background
|
||||
if (backOpacity > BackOpacityThreshold)
|
||||
{
|
||||
delayedOpacity = 1.0f - BackOpacityThreshold / (1.0f - appearPartsGroupOpacity);
|
||||
}
|
||||
|
||||
// Overwrite the opacity if it's greater than the delayed opacity.
|
||||
if (part.Opacity > delayedOpacity)
|
||||
{
|
||||
part.Opacity = delayedOpacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy opacity to linked parts.
|
||||
/// </summary>
|
||||
private void CopyPartOpacities()
|
||||
{
|
||||
for(var groupIndex = 0; groupIndex < _poseData.Length; ++groupIndex)
|
||||
{
|
||||
for (var partIndex = 0; partIndex < _poseData[groupIndex].Length; ++partIndex)
|
||||
{
|
||||
var linkParts = _poseData[groupIndex][partIndex].LinkParts;
|
||||
|
||||
if(linkParts == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var opacity = _poseData[groupIndex][partIndex].Part.Opacity;
|
||||
|
||||
for (var linkIndex = 0; linkIndex < linkParts.Length; ++linkIndex)
|
||||
{
|
||||
var linkPart = linkParts[linkIndex];
|
||||
|
||||
if(linkPart != null)
|
||||
{
|
||||
linkPart.Opacity = opacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save parts opacity.
|
||||
/// </summary>
|
||||
private void SavePartOpacities()
|
||||
{
|
||||
for(var groupIndex = 0; groupIndex < _poseData.Length; ++groupIndex)
|
||||
{
|
||||
for (var partIndex = 0; partIndex < _poseData[groupIndex].Length; ++partIndex)
|
||||
{
|
||||
_poseData[groupIndex][partIndex].Opacity = _poseData[groupIndex][partIndex].Part.Opacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by cubism update controller. Order to invoke OnLateUpdate.
|
||||
/// </summary>
|
||||
public int ExecutionOrder
|
||||
{
|
||||
get { return CubismUpdateExecutionOrder.CubismPoseController; }
|
||||
}
|
||||
|
||||
/// <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. Updates controller.
|
||||
/// </summary>
|
||||
public void OnLateUpdate()
|
||||
{
|
||||
// Fail silently...
|
||||
if (!enabled || _model == null || _poseData == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DoFade();
|
||||
CopyPartOpacities();
|
||||
SavePartOpacities();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity Event Handling
|
||||
|
||||
/// <summary>
|
||||
/// Called by Unity. Makes sure cache is initialized.
|
||||
/// </summary>
|
||||
private void OnEnable()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by Unity.
|
||||
/// </summary>
|
||||
private void LateUpdate()
|
||||
{
|
||||
if(!HasUpdateController)
|
||||
{
|
||||
OnLateUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user