Blending Characters At Runtime
Here's a script guide designed to help you blend between multiple characters at runtime.
Blending Between Avatars (at Runtime)
static class LerpHumanoid
{
public static Avatar LerpAvatars(GameObject targetHierarchy, Avatar a, Avatar b, float t)
{
HumanDescription aH = default, bH = default;
#if UNITY_2019_1_OR_NEWER
aH = a.humanDescription;
bH = b.humanDescription;
#else
throw new InvalidOperationException("This function requires Unity 2019.1 or newer.");
#endif
var humanDescription = new HumanDescription
{
armStretch = Mathf.Lerp(aH.armStretch, bH.armStretch, t),
feetSpacing = Mathf.Lerp(aH.feetSpacing, bH.feetSpacing, t),
hasTranslationDoF = t > 0.5f ? bH.hasTranslationDoF : aH.hasTranslationDoF,
legStretch = Mathf.Lerp(aH.legStretch, bH.legStretch, t),
lowerArmTwist = Mathf.Lerp(aH.lowerArmTwist, bH.lowerArmTwist, t),
upperArmTwist = Mathf.Lerp(aH.upperArmTwist, bH.upperArmTwist, t),
lowerLegTwist = Mathf.Lerp(aH.lowerLegTwist, bH.lowerLegTwist, t),
upperLegTwist = Mathf.Lerp(aH.upperLegTwist, bH.upperLegTwist, t)
};
var aHSkeleton = aH.skeleton;
var aHHuman = aH.human;
var bHSkeleton = bH.skeleton;
var bHHuman = bH.human;
var skeletonBones = new SkeletonBone[aHSkeleton.Length];
var humanBones = new HumanBone[aHHuman.Length];
for (int i = 0; i < humanDescription.skeleton.Length; i++)
{
if (aHSkeleton[i].name != bHSkeleton[i].name)
{
throw new InvalidOperationException("Skeleton arrays do not match, were these produced from the same original skeleton?");
}
var skelement = new SkeletonBone();
skelement.rotation = Quaternion.Lerp(aHSkeleton[i].rotation, bHSkeleton[i].rotation, t);
skelement.position = Vector3.Lerp(aHSkeleton[i].position, bHSkeleton[i].position, t);
skelement.scale = Vector3.Lerp(aHSkeleton[i].scale, bHSkeleton[i].scale, t);
skelement.name = aHSkeleton[i].name;
skeletonBones[i] = skelement;
}
for(int i = 0; i < humanDescription.human.Length; i++)
{
if (aHHuman[i].boneName != bHHuman[i].boneName)
{
throw new InvalidOperationException("Skeleton arrays do not match, were these produced from the same original skeleton?");
}
var bone = new HumanBone
{
boneName = aHHuman[i].boneName,
humanName = aHHuman[i].humanName,
limit = new HumanLimit
{
max = Vector3.Lerp(aHHuman[i].limit.max, bHHuman[i].limit.max, t),
axisLength = Mathf.Lerp(aHHuman[i].limit.axisLength, bHHuman[i].limit.axisLength, t),
center = Vector3.Lerp(aHHuman[i].limit.center, bHHuman[i].limit.center, t),
min = Vector3.Lerp(aHHuman[i].limit.min, bHHuman[i].limit.min, t),
useDefaultValues = t > 0.5f ? aHHuman[i].limit.useDefaultValues : bHHuman[i].limit.useDefaultValues
}
};
humanBones[i] = bone;
}
humanDescription.skeleton = skeletonBones;
humanDescription.human = humanBones;
return AvatarBuilder.BuildHumanAvatar(targetHierarchy, humanDescription);
}
}Last updated
Was this helpful?