Created
October 18, 2018 22:38
-
-
Save elringus/58fb1395b3158d4975c5330765ee78a2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if LIVE2D_AVAILABLE | |
using Live2D.Cubism.Core; | |
using Live2D.Cubism.Framework; | |
using System.Collections.Generic; | |
using System.Linq; | |
using UnityCommon; | |
using UnityEngine; | |
namespace Naninovel | |
{ | |
[RequireComponent(typeof(CubismModel))] | |
public class Live2DAppearanceController : MonoBehaviour | |
{ | |
[System.Serializable] | |
public class ParametersMap : SerializableMap<string, float> { } | |
[System.Serializable] | |
public class AppearanceData | |
{ | |
[Tooltip("Appearance to bind parameters for.")] | |
public string Appearance = string.Empty; | |
[Tooltip("List of parameters' name and value to bind.")] | |
public ParametersMap Params = default; | |
} | |
private struct ModifyRequest | |
{ | |
public float SmoothedValue => Mathf.SmoothStep(startValue, targetValue, (Time.time - startTime) / normalizedDuration); | |
private readonly float targetValue; | |
private readonly float startValue; | |
private readonly float startTime; | |
private readonly float normalizedDuration; | |
public ModifyRequest (CubismParameter param, float targetValue, float duration) | |
{ | |
this.targetValue = targetValue; | |
startValue = param.Value; | |
startTime = Time.time; | |
// In case we're starting the animation when the param is not at default value: reduce the duration accordingly. | |
var curValueProgress = 1f - ((targetValue - param.Value) / (targetValue - param.DefaultValue)); | |
var curTimeProgress = InversedSmoothStep(curValueProgress); | |
normalizedDuration = duration * (1f - curTimeProgress); | |
print(normalizedDuration); | |
} | |
private static float InversedSmoothStep (float v) => v + (v - (v * v * (3f - 2f * v))); | |
} | |
[SerializeField] private List<AppearanceData> appearanceMap = default; | |
[SerializeField] private CubismParameterBlendMode blendMode = CubismParameterBlendMode.Override; | |
[SerializeField] private string headXAngleParamId = "PARAM_ANGLE_X"; | |
private const float headXAngleDelta = 30f; | |
private static CubismParameter headXParam; | |
private CubismModel cubismModel; | |
private Dictionary<string, ModifyRequest> appearanceRequests = new Dictionary<string, ModifyRequest>(); | |
private ModifyRequest lookDirRequest; | |
public void SetAppearance (string appearance, float duration) | |
{ | |
appearanceRequests.Clear(); | |
var appearanceData = appearanceMap?.FirstOrDefault(a => a.Appearance == appearance); | |
if (appearanceData is null) return; | |
foreach (var kv in appearanceData.Params) | |
appearanceRequests[kv.Key] = new ModifyRequest(cubismModel.Parameters.FindById(kv.Key), kv.Value, duration); | |
} | |
public void SetLookDirection (CharacterLookDirection lookDirection, float duration) | |
{ | |
if (headXParam is null) return; | |
var targetValue = default(float); | |
switch (lookDirection) | |
{ | |
case CharacterLookDirection.Center: | |
targetValue = 0f; | |
break; | |
case CharacterLookDirection.Left: | |
targetValue = -headXAngleDelta; | |
break; | |
case CharacterLookDirection.Right: | |
targetValue = headXAngleDelta; | |
break; | |
} | |
lookDirRequest = new ModifyRequest(headXParam, targetValue, duration); | |
} | |
private void Start () | |
{ | |
cubismModel = this.FindCubismModel(); | |
headXParam = cubismModel.Parameters.FindById(headXAngleParamId); | |
} | |
private void LateUpdate () | |
{ | |
for (int i = 0; i < cubismModel.Parameters.Length; i++) | |
{ | |
var param = cubismModel.Parameters[i]; | |
var value = !appearanceRequests.ContainsKey(param.Id) ? param.DefaultValue : appearanceRequests[param.Id].SmoothedValue; | |
if (Mathf.Approximately(param.Value, value)) continue; | |
param.BlendToValue(blendMode, value); | |
} | |
if (headXParam != null) headXParam.BlendToValue(blendMode, lookDirRequest.SmoothedValue); | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment