You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
3.1 KiB
C#

3 years ago
using MalbersAnimations.Scriptables;
using System.Collections;
using UnityEngine;
namespace MalbersAnimations.Utilities
{
[CreateAssetMenu(menuName = "Malbers Animations/Preset/BlendShape", order = 200)]
[HelpURL("https://malbersanimations.gitbook.io/animal-controller/utilities/blend-shapes/blend-shape-preset")]
public class BlendShapePreset : ScriptableCoroutine
{
[Header("Smooth BlendShapes")]
public FloatReference BlendTime = new FloatReference(1.5f);
public AnimationCurve BlendCurve = new AnimationCurve(new Keyframe[] { new Keyframe(0, 0), new Keyframe(1, 1) });
[Space, Header("Blend Shapes Weights")]
public float[] blendShapes;
public void Load(SkinnedMeshRenderer mesh)
{
int Length = Mathf.Min(mesh.sharedMesh.blendShapeCount, blendShapes.Length);
for (int i = 0; i < Length; i++)
{
mesh.SetBlendShapeWeight(i, blendShapes[i]);
}
}
public virtual void SmoothBlend(SkinnedMeshRenderer mesh)
{
StartCoroutine(mesh, C_SmoothBlend(mesh,BlendTime, BlendCurve));
}
internal override void Evaluate(MonoBehaviour mono, Transform target, float time, AnimationCurve curve = null)
{
mono.StartCoroutine(C_SmoothBlend(target.GetComponent<SkinnedMeshRenderer>(), time, curve));
}
protected IEnumerator C_SmoothBlend(SkinnedMeshRenderer mesh, float BlendTime, AnimationCurve BlendCurve)
{
float elapsedTime = 0;
int Length = Mathf.Min(mesh.sharedMesh.blendShapeCount, blendShapes.Length, blendShapes.Length);
float[] StartBlends = new float[mesh.sharedMesh.blendShapeCount];
int SamePreset = 0;
for (int i = 0; i < Length; i++)
{
StartBlends[i] = mesh.GetBlendShapeWeight(i);
if (StartBlends[i] == blendShapes[i]) SamePreset++;
}
if (SamePreset == Length)
{
Debug.Log("Loading same BlendShape preset. Ignore");
yield return null;
Stop(mesh);
}
else
{
while ((BlendTime > 0) && (elapsedTime <= BlendTime))
{
float result = BlendCurve.Evaluate(elapsedTime / BlendTime); //Evaluation of the Pos curve
for (int i = 0; i < Length; i++)
{
var newWeight = Mathf.Lerp(StartBlends[i], blendShapes[i], result);
mesh.SetBlendShapeWeight(i, newWeight);
}
elapsedTime += Time.deltaTime;
yield return null;
}
Load(mesh);
var BSScript = mesh.transform.root.FindComponent<BlendShape>();
if (BSScript)
{
BSScript.LoadPreset(this);
BSScript.SetShapesCount();
}
yield return null;
Stop(mesh);
}
}
}
}