mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-03-06 13:54:56 +08:00
fix: fix issues with nested armature confusion in Easy Setup Outfit
This fixes issues with nested armature confusion by changing the name of the Armature object (only).
This commit is contained in:
parent
56119c0779
commit
cfd25ccd08
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e8745411e14ca634e87ffbf19723aab7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,60 @@
|
||||
using modular_avatar_tests;
|
||||
using nadena.dev.modular_avatar.core.editor;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
public class ArmatureConfusionTest : TestBase
|
||||
{
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
ESOErrorWindow.Suppress = false;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestArmatureConfusionWorkaround()
|
||||
{
|
||||
ESOErrorWindow.Suppress = true;
|
||||
|
||||
// Arrange for a confused armature
|
||||
var outer = CreatePrefab("shapell.fbx");
|
||||
var inner = CreatePrefab("shapell.fbx");
|
||||
|
||||
var outerAnimator = outer.GetComponent<Animator>();
|
||||
outer.AddComponent<VRCAvatarDescriptor>();
|
||||
|
||||
inner.gameObject.name = "inner";
|
||||
inner.transform.parent = outer.transform;
|
||||
|
||||
// Unity seems to determine which armature is the "true" armature by counting the number of bones that match
|
||||
// the humanoid description, and finding the root which has the most matches. Let's confuse it a bit by removing
|
||||
// some non-humanoid bones from the outer armature.
|
||||
var outerTarget = outer.transform.Find("Armature/Hips/Tail");
|
||||
UnityObject.DestroyImmediate(outerTarget.gameObject);
|
||||
|
||||
// Clear animator cache
|
||||
var avatar = outerAnimator.avatar;
|
||||
outerAnimator.avatar = null;
|
||||
// ReSharper disable once Unity.InefficientPropertyAccess
|
||||
outerAnimator.avatar = avatar;
|
||||
|
||||
// Verify that we're well and confused now
|
||||
Assert.AreSame(
|
||||
outerAnimator.GetBoneTransform(HumanBodyBones.Hips),
|
||||
inner.transform.Find("Armature/Hips")
|
||||
);
|
||||
|
||||
// Now do a setup outfit operation
|
||||
Selection.activeGameObject = inner;
|
||||
EasySetupOutfit.SetupOutfit(new MenuCommand(inner));
|
||||
|
||||
// Verify that we're not confused anymore
|
||||
Assert.AreSame(
|
||||
outerAnimator.GetBoneTransform(HumanBodyBones.Hips),
|
||||
outer.transform.Find("Armature/Hips")
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01ff1e86623a409ba5248c5fb6a0b53e
|
||||
timeCreated: 1696244575
|
@ -0,0 +1,2 @@
|
||||
shapell.fbx is from Shapell (https://booth.pm/ja/items/1349366) by lowteq
|
||||
Released under CC0 1.0 Universal (CC0 1.0) (https://creativecommons.org/publicdomain/zero/1.0/deed.ja)
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5e311d0ce414f56afac9ccff53b16c4
|
||||
timeCreated: 1696245763
|
@ -0,0 +1,77 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: material
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14fe6d8ede57a1a45955b9a0181223ae
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,8 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
private static readonly GUIStyle buttonStyle, labelStyle;
|
||||
private const float SeparatorSize = 6f;
|
||||
|
||||
internal static bool Suppress = false;
|
||||
|
||||
static ESOErrorWindow()
|
||||
{
|
||||
buttonStyle = EditorStyles.miniButtonRight;
|
||||
@ -33,6 +35,8 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
string[] messageGroups
|
||||
)
|
||||
{
|
||||
if (Suppress) return;
|
||||
|
||||
var window = CreateInstance<ESOErrorWindow>();
|
||||
window.titleContent = new GUIContent("Setup Outfit");
|
||||
window.header = header;
|
||||
@ -99,14 +103,14 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
}
|
||||
}
|
||||
|
||||
internal class EasySetupOutfit
|
||||
internal static class EasySetupOutfit
|
||||
{
|
||||
private const int PRIORITY = 49;
|
||||
private static string[] errorMessageGroups;
|
||||
private static string errorHeader;
|
||||
|
||||
[MenuItem("GameObject/ModularAvatar/Setup Outfit", false, PRIORITY)]
|
||||
static void SetupOutfit(MenuCommand cmd)
|
||||
internal static void SetupOutfit(MenuCommand cmd)
|
||||
{
|
||||
if (!ValidateSetupOutfit())
|
||||
{
|
||||
@ -130,6 +134,23 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
merge.LockMode = ArmatureLockMode.BaseToMerge;
|
||||
merge.InferPrefixSuffix();
|
||||
HeuristicBoneMapper.RenameBonesByHeuristic(merge);
|
||||
|
||||
var avatarRootMatchingArmature = avatarRoot.transform.Find(outfitArmature.gameObject.name);
|
||||
if (merge.prefix == "" && merge.suffix == "" && avatarRootMatchingArmature != null)
|
||||
{
|
||||
// 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
|
||||
// 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.
|
||||
outfitArmature.name += ".1";
|
||||
|
||||
// Also make sure to refresh the avatar's animator humanoid bone cache.
|
||||
var avatarAnimator = avatarRoot.GetComponent<Animator>();
|
||||
var humanDescription = avatarAnimator.avatar;
|
||||
avatarAnimator.avatar = null;
|
||||
// ReSharper disable once Unity.InefficientPropertyAccess
|
||||
avatarAnimator.avatar = humanDescription;
|
||||
}
|
||||
}
|
||||
|
||||
if (outfitRoot != null
|
||||
@ -298,7 +319,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
avatarHips = avatarAnimator.GetBoneTransform(HumanBodyBones.Hips)?.gameObject;
|
||||
|
||||
if (avatarHips == null)
|
||||
@ -334,7 +355,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
}
|
||||
|
||||
hipsCandidates.Add(avatarHips.name);
|
||||
|
||||
|
||||
// If that doesn't work out, we'll check for heuristic bone mapper mappings.
|
||||
foreach (var hbm in HeuristicBoneMapper.BoneToNameMap[HumanBodyBones.Hips])
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user