mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2024-12-29 18:55:06 +08:00
feat: improve behavior when called setup outfit for setuped outfit (#1200)
This commit is contained in:
parent
5bafb0ba9d
commit
26153ea60d
@ -145,25 +145,54 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
out var avatarRoot, out var avatarHips, out var outfitHips)
|
out var avatarRoot, out var avatarHips, out var outfitHips)
|
||||||
) return;
|
) return;
|
||||||
|
|
||||||
|
Undo.SetCurrentGroupName("Setup Outfit");
|
||||||
|
|
||||||
var avatarArmature = avatarHips.transform.parent;
|
var avatarArmature = avatarHips.transform.parent;
|
||||||
var outfitArmature = outfitHips.transform.parent;
|
var outfitArmature = outfitHips.transform.parent;
|
||||||
|
|
||||||
if (outfitArmature.GetComponent<ModularAvatarMergeArmature>() == null)
|
var merge = outfitArmature.GetComponent<ModularAvatarMergeArmature>();
|
||||||
|
if (merge == null)
|
||||||
|
{
|
||||||
|
merge = Undo.AddComponent<ModularAvatarMergeArmature>(outfitArmature.gameObject);
|
||||||
|
} else {
|
||||||
|
Undo.RecordObject(merge, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (merge.mergeTarget == null || merge.mergeTargetObject == null)
|
||||||
{
|
{
|
||||||
var merge = Undo.AddComponent<ModularAvatarMergeArmature>(outfitArmature.gameObject);
|
|
||||||
merge.mergeTarget = new AvatarObjectReference();
|
merge.mergeTarget = new AvatarObjectReference();
|
||||||
merge.mergeTarget.referencePath = RuntimeUtil.RelativePath(avatarRoot, avatarArmature.gameObject);
|
merge.mergeTarget.referencePath = RuntimeUtil.RelativePath(avatarRoot, avatarArmature.gameObject);
|
||||||
merge.LockMode = ArmatureLockMode.BaseToMerge;
|
merge.LockMode = ArmatureLockMode.BaseToMerge;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(merge.prefix) && string.IsNullOrEmpty(merge.suffix))
|
||||||
|
{
|
||||||
merge.InferPrefixSuffix();
|
merge.InferPrefixSuffix();
|
||||||
|
}
|
||||||
|
|
||||||
List<Transform> subRoots = new List<Transform>();
|
PrefabUtility.RecordPrefabInstancePropertyModifications(merge);
|
||||||
HeuristicBoneMapper.RenameBonesByHeuristic(merge, skipped: subRoots);
|
|
||||||
|
|
||||||
// If the outfit has an UpperChest bone but the avatar doesn't, add an additional MergeArmature to
|
List<Transform> subRoots = new List<Transform>();
|
||||||
// help with this
|
HeuristicBoneMapper.RenameBonesByHeuristic(merge, skipped: subRoots);
|
||||||
foreach (var subRoot in subRoots)
|
|
||||||
|
// If the outfit has an UpperChest bone but the avatar doesn't, add an additional MergeArmature to
|
||||||
|
// help with this
|
||||||
|
foreach (var subRoot in subRoots)
|
||||||
|
{
|
||||||
|
var subConfig = subRoot.GetComponent<ModularAvatarMergeArmature>();
|
||||||
|
var subConfigMangleNames = false;
|
||||||
|
if (subConfig == null)
|
||||||
|
{
|
||||||
|
subConfig = Undo.AddComponent<ModularAvatarMergeArmature>(subRoot.gameObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Undo.RecordObject(subConfig, "");
|
||||||
|
subConfigMangleNames = subConfig.mangleNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subConfig.mergeTarget == null || subConfig.mergeTargetObject == null)
|
||||||
{
|
{
|
||||||
var subConfig = Undo.AddComponent<ModularAvatarMergeArmature>(subRoot.gameObject);
|
|
||||||
var parentTransform = subConfig.transform.parent;
|
var parentTransform = subConfig.transform.parent;
|
||||||
var parentConfig = parentTransform.GetComponentInParent<ModularAvatarMergeArmature>();
|
var parentConfig = parentTransform.GetComponentInParent<ModularAvatarMergeArmature>();
|
||||||
var parentMapping = parentConfig.MapBone(parentTransform);
|
var parentMapping = parentConfig.MapBone(parentTransform);
|
||||||
@ -174,34 +203,48 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
subConfig.LockMode = ArmatureLockMode.BaseToMerge;
|
subConfig.LockMode = ArmatureLockMode.BaseToMerge;
|
||||||
subConfig.prefix = merge.prefix;
|
subConfig.prefix = merge.prefix;
|
||||||
subConfig.suffix = merge.suffix;
|
subConfig.suffix = merge.suffix;
|
||||||
subConfig.mangleNames = false;
|
subConfig.mangleNames = subConfigMangleNames;
|
||||||
|
PrefabUtility.RecordPrefabInstancePropertyModifications(subConfig);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var avatarRootMatchingArmature = avatarRoot.transform.Find(outfitArmature.gameObject.name);
|
var avatarRootMatchingArmature = avatarRoot.transform.Find(outfitArmature.gameObject.name);
|
||||||
if (merge.prefix == "" && merge.suffix == "" && avatarRootMatchingArmature != null)
|
if (merge.prefix == "" && merge.suffix == "" && avatarRootMatchingArmature != null)
|
||||||
{
|
{
|
||||||
// We have an armature whose names exactly match the root armature - this can cause some serious
|
// We have an armature whose names exactly match the root armature - this can cause some serious
|
||||||
// confusion in Unity's humanoid armature matching system. Fortunately, we can avoid this by
|
// confusion in Unity's humanoid armature matching system. Fortunately, we can avoid this by
|
||||||
// renaming a bone close to the root; this will ensure the number of matching bones is small, and
|
// renaming a bone close to the root; this will ensure the number of matching bones is small, and
|
||||||
// Unity's heuristics (apparently) will choose the base avatar's armature as the "true" armature.
|
// Unity's heuristics (apparently) will choose the base avatar's armature as the "true" armature.
|
||||||
outfitArmature.name += ".1";
|
outfitArmature.name += ".1";
|
||||||
|
|
||||||
// Also make sure to refresh the avatar's animator humanoid bone cache.
|
// Also make sure to refresh the avatar's animator humanoid bone cache.
|
||||||
var avatarAnimator = avatarRoot.GetComponent<Animator>();
|
var avatarAnimator = avatarRoot.GetComponent<Animator>();
|
||||||
var humanDescription = avatarAnimator.avatar;
|
var humanDescription = avatarAnimator.avatar;
|
||||||
avatarAnimator.avatar = null;
|
avatarAnimator.avatar = null;
|
||||||
// ReSharper disable once Unity.InefficientPropertyAccess
|
// ReSharper disable once Unity.InefficientPropertyAccess
|
||||||
avatarAnimator.avatar = humanDescription;
|
avatarAnimator.avatar = humanDescription;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FixAPose(avatarRoot, outfitArmature);
|
FixAPose(avatarRoot, outfitArmature);
|
||||||
|
|
||||||
|
var meshSettings = outfitRoot.GetComponent<ModularAvatarMeshSettings>();
|
||||||
|
var mSInheritProbeAnchor = ModularAvatarMeshSettings.InheritMode.SetOrInherit;
|
||||||
|
var mSInheritBounds = ModularAvatarMeshSettings.InheritMode.SetOrInherit;
|
||||||
if (outfitRoot != null
|
if (outfitRoot != null
|
||||||
&& outfitRoot.GetComponent<ModularAvatarMeshSettings>() == null
|
&& meshSettings == null
|
||||||
&& outfitRoot.GetComponentInParent<ModularAvatarMeshSettings>() == null)
|
&& outfitRoot.GetComponentInParent<ModularAvatarMeshSettings>() == null)
|
||||||
{
|
{
|
||||||
var meshSettings = Undo.AddComponent<ModularAvatarMeshSettings>(outfitRoot.gameObject);
|
meshSettings = Undo.AddComponent<ModularAvatarMeshSettings>(outfitRoot.gameObject);
|
||||||
|
} else if (outfitRoot != null && meshSettings != null) {
|
||||||
|
Undo.RecordObject(meshSettings, "");
|
||||||
|
mSInheritProbeAnchor = meshSettings.InheritProbeAnchor;
|
||||||
|
mSInheritBounds = meshSettings.InheritBounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meshSettings != null
|
||||||
|
&& (meshSettings.ProbeAnchor == null || meshSettings.ProbeAnchor.Get(meshSettings) == null
|
||||||
|
|| meshSettings.RootBone == null || meshSettings.RootBone.Get(meshSettings) == null))
|
||||||
|
{
|
||||||
Transform rootBone = null, probeAnchor = null;
|
Transform rootBone = null, probeAnchor = null;
|
||||||
Bounds bounds = ModularAvatarMeshSettings.DEFAULT_BOUNDS;
|
Bounds bounds = ModularAvatarMeshSettings.DEFAULT_BOUNDS;
|
||||||
|
|
||||||
@ -217,8 +260,8 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
rootBone = avatarRoot.transform;
|
rootBone = avatarRoot.transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
meshSettings.InheritProbeAnchor = ModularAvatarMeshSettings.InheritMode.SetOrInherit;
|
meshSettings.InheritProbeAnchor = mSInheritProbeAnchor;
|
||||||
meshSettings.InheritBounds = ModularAvatarMeshSettings.InheritMode.SetOrInherit;
|
meshSettings.InheritBounds = mSInheritBounds;
|
||||||
|
|
||||||
meshSettings.ProbeAnchor = new AvatarObjectReference();
|
meshSettings.ProbeAnchor = new AvatarObjectReference();
|
||||||
meshSettings.ProbeAnchor.referencePath = RuntimeUtil.RelativePath(avatarRoot, probeAnchor.gameObject);
|
meshSettings.ProbeAnchor.referencePath = RuntimeUtil.RelativePath(avatarRoot, probeAnchor.gameObject);
|
||||||
@ -226,6 +269,8 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
meshSettings.RootBone = new AvatarObjectReference();
|
meshSettings.RootBone = new AvatarObjectReference();
|
||||||
meshSettings.RootBone.referencePath = RuntimeUtil.RelativePath(avatarRoot, rootBone.gameObject);
|
meshSettings.RootBone.referencePath = RuntimeUtil.RelativePath(avatarRoot, rootBone.gameObject);
|
||||||
meshSettings.Bounds = bounds;
|
meshSettings.Bounds = bounds;
|
||||||
|
|
||||||
|
PrefabUtility.RecordPrefabInstancePropertyModifications(meshSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user