Humanoid.Get_GetBoneTransform を追加

Animator.GetBoneTransform のために GetComponent しているところの Export Error を修正するついでに、
Animator.GetBoneTransform と Humanoid.GetBoneTransform 両対応とした(vrm-0.x と vrm-1.0 両方)。
This commit is contained in:
ousttrue
2024-07-25 14:28:59 +09:00
parent cc6eea567b
commit 7ef4f50558
3 changed files with 69 additions and 43 deletions

View File

@@ -456,5 +456,35 @@ namespace UniHumanoid
bone = default;
return false;
}
public static Func<HumanBodyBones, Transform> Get_GetBoneTransform(GameObject root)
{
if (root.TryGetComponent<UniHumanoid.Humanoid>(out var humanoid))
{
return humanoid.GetBoneTransform;
}
else if (root.TryGetComponent<Animator>(out var animator))
{
// avatar
var avatar = animator.avatar;
if (avatar == null)
{
throw new ArgumentException("no avatar");
}
if (!avatar.isValid)
{
throw new ArgumentException("invalid avatar");
}
if (!avatar.isHuman)
{
throw new ArgumentException("avatar is not humanoid");
}
return animator.GetBoneTransform;
}
else
{
throw new ArgumentException("no animator nor humanoid");
}
}
}
}

View File

@@ -167,14 +167,14 @@ namespace VRM
{
// copy元
var animator = exportRoot.GetComponentOrNull<Animator>();
var getBone = UniHumanoid.Humanoid.Get_GetBoneTransform(exportRoot);
var beforeTransforms = exportRoot.GetComponentsInChildren<Transform>(true);
// copy先
var afterTransforms = target.GetComponentsInChildren<Transform>(true);
// copy先のhumanoidBoneのリストを得る
var humanTransforms = CachedEnum.GetValues<HumanBodyBones>()
.Where(x => x != HumanBodyBones.LastBone)
.Select(x => animator.GetBoneTransform(x))
.Select(x => getBone(x))
.Where(x => x != null)
.Select(x => afterTransforms[Array.IndexOf(beforeTransforms, x)]) // copy 先を得る
.ToArray();

View File

@@ -47,55 +47,51 @@ namespace VRM
public override void ExportExtensions(ITextureSerializer textureSerializer)
{
// avatar
if (Copy.TryGetComponent<Animator>(out var animator))
var getBone = UniHumanoid.Humanoid.Get_GetBoneTransform(Copy);
UniHumanoid.AvatarDescription description = null;
var isCreated = false;
if (Copy.TryGetComponent<VRMHumanoidDescription>(out var humanoid))
{
UniHumanoid.AvatarDescription description = null;
var isCreated = false;
if (Copy.TryGetComponent<VRMHumanoidDescription>(out var humanoid))
if (humanoid != null)
{
if (humanoid != null)
{
description = humanoid.GetDescription(out isCreated);
}
description = humanoid.GetDescription(out isCreated);
}
var nodes = Copy.transform.Traverse().Skip(1).ToList();
}
var nodes = Copy.transform.Traverse().Skip(1).ToList();
{
if (description != null)
{
if (description != null)
{
// use description
VRM.humanoid.Apply(description, nodes);
}
if (isCreated)
{
GameObject.DestroyImmediate(description);
}
// use description
VRM.humanoid.Apply(description, nodes);
}
if (isCreated)
{
// set humanoid bone mapping
var avatar = animator.avatar;
foreach (HumanBodyBones key in CachedEnum.GetValues<HumanBodyBones>())
{
if (key == HumanBodyBones.LastBone)
{
break;
}
GameObject.DestroyImmediate(description);
}
}
var transform = animator.GetBoneTransform(key);
if (transform != null)
{
var nodeIndex = nodes.IndexOf(transform);
if (nodeIndex < 0)
{
Debug.LogError($"ヒューマンボーンが export 対象に含まれていない?", transform);
}
else
{
VRM.humanoid.SetNodeIndex(key, nodeIndex);
}
}
// set humanoid bone mapping
// var avatar = animator.avatar;
foreach (HumanBodyBones key in CachedEnum.GetValues<HumanBodyBones>())
{
if (key == HumanBodyBones.LastBone)
{
break;
}
var transform = getBone(key);
if (transform != null)
{
var nodeIndex = nodes.IndexOf(transform);
if (nodeIndex < 0)
{
Debug.LogError($"ヒューマンボーンが export 対象に含まれていない?", transform);
}
else
{
VRM.humanoid.SetNodeIndex(key, nodeIndex);
}
}
}