Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #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
Add Comment
Please, Sign In to add comment