mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-01-30 10:12:59 +08:00
fix: avatar masks are not rewritten when merging animators (#1093)
Closes: #228
This commit is contained in:
parent
f9a9f1f1ef
commit
668ab35b46
@ -473,7 +473,7 @@ namespace nadena.dev.modular_avatar.animation
|
||||
var newLayer = new AnimatorControllerLayer()
|
||||
{
|
||||
name = layer.name,
|
||||
avatarMask = layer.avatarMask, // TODO map transforms
|
||||
avatarMask = _deepClone.DoClone(layer.avatarMask, basePath, _cloneMap),
|
||||
blendingMode = layer.blendingMode,
|
||||
defaultWeight = first ? 1 : layer.defaultWeight,
|
||||
syncedLayerIndex = layer.syncedLayerIndex,
|
||||
|
@ -50,6 +50,7 @@ namespace nadena.dev.modular_avatar.animation
|
||||
case AnimatorStateMachine _:
|
||||
case AnimatorTransitionBase _:
|
||||
case StateMachineBehaviour _:
|
||||
case AvatarMask _:
|
||||
break; // We want to clone these types
|
||||
|
||||
case AudioClip _: //Used in VRC Animator Play Audio State Behavior
|
||||
@ -96,6 +97,8 @@ namespace nadena.dev.modular_avatar.animation
|
||||
return (T)obj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
var ctor = original.GetType().GetConstructor(Type.EmptyTypes);
|
||||
if (ctor == null || original is ScriptableObject)
|
||||
{
|
||||
@ -146,8 +149,74 @@ namespace nadena.dev.modular_avatar.animation
|
||||
return (T)obj;
|
||||
}
|
||||
|
||||
// internal for testing
|
||||
internal static AvatarMask CloneAvatarMask(AvatarMask mask, string basePath)
|
||||
{
|
||||
if (basePath.EndsWith("/")) basePath = basePath.Substring(0, basePath.Length - 1);
|
||||
|
||||
var newMask = new AvatarMask();
|
||||
|
||||
// Transfer first the humanoid mask data
|
||||
EditorUtility.CopySerialized(mask, newMask);
|
||||
|
||||
var srcSo = new SerializedObject(mask);
|
||||
var dstSo = new SerializedObject(newMask);
|
||||
var srcElements = srcSo.FindProperty("m_Elements");
|
||||
|
||||
if (basePath == "" || srcElements.arraySize == 0) return newMask; // no changes required
|
||||
|
||||
// We now need to prefix the elements of basePath (with weight zero)
|
||||
|
||||
var newElements = new List<string>();
|
||||
|
||||
var accum = "";
|
||||
foreach (var element in basePath.Split("/"))
|
||||
{
|
||||
if (accum != "") accum += "/";
|
||||
accum += element;
|
||||
|
||||
newElements.Add(accum);
|
||||
}
|
||||
|
||||
var dstElements = dstSo.FindProperty("m_Elements");
|
||||
|
||||
// We'll need to create new array elements by using DuplicateCommand. We'll then rewrite the whole
|
||||
// list to keep things in traversal order.
|
||||
for (var i = 0; i < newElements.Count; i++) dstElements.GetArrayElementAtIndex(0).DuplicateCommand();
|
||||
|
||||
var totalElements = srcElements.arraySize + newElements.Count;
|
||||
for (var i = 0; i < totalElements; i++)
|
||||
{
|
||||
var dstElem = dstElements.GetArrayElementAtIndex(i);
|
||||
var dstPath = dstElem.FindPropertyRelative("m_Path");
|
||||
var dstWeight = dstElem.FindPropertyRelative("m_Weight");
|
||||
|
||||
var srcIndex = i - newElements.Count;
|
||||
if (srcIndex < 0)
|
||||
{
|
||||
dstPath.stringValue = newElements[i];
|
||||
dstWeight.floatValue = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var srcElem = srcElements.GetArrayElementAtIndex(srcIndex);
|
||||
dstPath.stringValue = basePath + "/" + srcElem.FindPropertyRelative("m_Path").stringValue;
|
||||
dstWeight.floatValue = srcElem.FindPropertyRelative("m_Weight").floatValue;
|
||||
}
|
||||
}
|
||||
|
||||
dstSo.ApplyModifiedPropertiesWithoutUndo();
|
||||
|
||||
return newMask;
|
||||
}
|
||||
|
||||
private UnityObject CloneWithPathMapping(UnityObject o, string basePath)
|
||||
{
|
||||
if (o is AvatarMask mask)
|
||||
{
|
||||
return CloneAvatarMask(mask, basePath);
|
||||
}
|
||||
|
||||
if (o is AnimationClip clip)
|
||||
{
|
||||
// We'll always rebase if the asset is non-persistent, because we can't reference a nonpersistent asset
|
||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||
using nadena.dev.ndmf;
|
||||
using nadena.dev.ndmf.util;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Animations;
|
||||
using UnityEngine;
|
||||
#if MA_VRCSDK3_AVATARS_3_5_2_OR_NEWER
|
||||
#endif
|
||||
@ -278,6 +279,62 @@ namespace nadena.dev.modular_avatar.animation
|
||||
return newClip;
|
||||
}
|
||||
|
||||
private void ApplyMappingsToAvatarMask(AvatarMask mask)
|
||||
{
|
||||
if (mask == null) return;
|
||||
|
||||
var maskSo = new SerializedObject(mask);
|
||||
|
||||
var seenTransforms = new Dictionary<string, float>();
|
||||
var transformOrder = new List<string>();
|
||||
var m_Elements = maskSo.FindProperty("m_Elements");
|
||||
var elementCount = m_Elements.arraySize;
|
||||
|
||||
for (var i = 0; i < elementCount; i++)
|
||||
{
|
||||
var element = m_Elements.GetArrayElementAtIndex(i);
|
||||
var path = element.FindPropertyRelative("m_Path").stringValue;
|
||||
var weight = element.FindPropertyRelative("m_Weight").floatValue;
|
||||
|
||||
path = MapPath(path);
|
||||
|
||||
// ensure all parent elements are present
|
||||
EnsureParentsPresent(path);
|
||||
|
||||
if (!seenTransforms.ContainsKey(path)) transformOrder.Add(path);
|
||||
seenTransforms[path] = weight;
|
||||
}
|
||||
|
||||
transformOrder.Sort();
|
||||
m_Elements.arraySize = transformOrder.Count;
|
||||
|
||||
for (var i = 0; i < transformOrder.Count; i++)
|
||||
{
|
||||
var element = m_Elements.GetArrayElementAtIndex(i);
|
||||
var path = transformOrder[i];
|
||||
|
||||
element.FindPropertyRelative("m_Path").stringValue = path;
|
||||
element.FindPropertyRelative("m_Weight").floatValue = seenTransforms[path];
|
||||
}
|
||||
|
||||
maskSo.ApplyModifiedPropertiesWithoutUndo();
|
||||
|
||||
void EnsureParentsPresent(string path)
|
||||
{
|
||||
var nextSlash = -1;
|
||||
|
||||
while ((nextSlash = path.IndexOf('/', nextSlash + 1)) != -1)
|
||||
{
|
||||
var parentPath = path.Substring(0, nextSlash);
|
||||
if (!seenTransforms.ContainsKey(parentPath))
|
||||
{
|
||||
seenTransforms[parentPath] = 0;
|
||||
transformOrder.Add(parentPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnDeactivate(BuildContext context)
|
||||
{
|
||||
Dictionary<AnimationClip, AnimationClip> clipCache = new Dictionary<AnimationClip, AnimationClip>();
|
||||
@ -302,6 +359,20 @@ namespace nadena.dev.modular_avatar.animation
|
||||
{
|
||||
listener.OnCommitObjectRenames(context, this);
|
||||
}
|
||||
|
||||
var layers = context.AvatarDescriptor.baseAnimationLayers
|
||||
.Concat(context.AvatarDescriptor.specialAnimationLayers);
|
||||
|
||||
foreach (var layer in layers)
|
||||
{
|
||||
ApplyMappingsToAvatarMask(layer.mask);
|
||||
|
||||
if (layer.animatorController is AnimatorController ac)
|
||||
// By this point, all AnimationOverrideControllers have been collapsed into an ephemeral
|
||||
// AnimatorController so we can safely modify the controller in-place.
|
||||
foreach (var acLayer in ac.layers)
|
||||
ApplyMappingsToAvatarMask(acLayer.avatarMask);
|
||||
}
|
||||
}
|
||||
|
||||
public GameObject PathToObject(string path)
|
||||
|
59
Editor/nadena.dev.modular-avatar.core.editor.asmdef~
Normal file
59
Editor/nadena.dev.modular-avatar.core.editor.asmdef~
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "nadena.dev.modular-avatar.core.editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"nadena.dev.modular-avatar.core",
|
||||
"VRC.SDK3A",
|
||||
"VRC.SDKBase",
|
||||
"nadena.dev.ndmf",
|
||||
"nadena.dev.ndmf.vrchat",
|
||||
"nadena.dev.ndmf.runtime",
|
||||
"VRC.SDK3A.Editor",
|
||||
"Unity.Burst"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"Newtonsoft.Json.dll",
|
||||
"System.Collections.Immutable.dll",
|
||||
"VRCSDKBase.dll",
|
||||
"VRCSDKBase-Editor.dll",
|
||||
"VRCSDK3A.dll",
|
||||
"VRCSDK3A-Editor.dll",
|
||||
"VRC.Dynamics.dll",
|
||||
"VRC.SDK3.Dynamics.Contact.dll",
|
||||
"VRC.SDK3.Dynamics.Contact.Editor.dll",
|
||||
"VRC.SDK3.Dynamics.PhysBone.dll",
|
||||
"VRC.SDK3.Dynamics.PhysBone.Editor.dll",
|
||||
"VRCCore-Editor.dll"
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.anatawa12.avatar-optimizer",
|
||||
"expression": "(,1.5.0-rc.8)",
|
||||
"define": "LEGACY_AVATAR_OPTIMIZER"
|
||||
},
|
||||
{
|
||||
"name": "com.vrchat.avatars",
|
||||
"expression": "",
|
||||
"define": "MA_VRCSDK3_AVATARS"
|
||||
},
|
||||
{
|
||||
"name": "com.vrchat.avatars",
|
||||
"expression": "3.5.2",
|
||||
"define": "MA_VRCSDK3_AVATARS_3_5_2_OR_NEWER"
|
||||
},
|
||||
{
|
||||
"name": "com.vrchat.avatars",
|
||||
"expression": "3.7.0-beta.2",
|
||||
"define": "MA_VRCSDK3_AVATARS_3_7_0_OR_NEWER"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
8
UnitTests~/Animation/AvatarMask.meta
Normal file
8
UnitTests~/Animation/AvatarMask.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c2f284a674abf64385b28a69a56b1b7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
641
UnitTests~/Animation/AvatarMask/AvatarMaskRewriteTest.prefab
Normal file
641
UnitTests~/Animation/AvatarMask/AvatarMaskRewriteTest.prefab
Normal file
@ -0,0 +1,641 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &331101518860596682
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6576105763171871826}
|
||||
- component: {fileID: 6153053980314603517}
|
||||
- component: {fileID: 8060949548882505714}
|
||||
m_Layer: 0
|
||||
m_Name: anim-root
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &6576105763171871826
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 331101518860596682}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 1051065088277815102}
|
||||
- {fileID: 7719834109032320146}
|
||||
m_Father: {fileID: 4630496911169132430}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &6153053980314603517
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 331101518860596682}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 1bb122659f724ebf85fe095ac02dc339, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
animator: {fileID: 9100000, guid: 0ff8ee7fe6e04b148bcd1b0f04280efb, type: 2}
|
||||
layerType: 5
|
||||
deleteAttachedAnimator: 1
|
||||
pathMode: 0
|
||||
matchAvatarWriteDefaults: 0
|
||||
relativePathRoot:
|
||||
referencePath:
|
||||
targetObject: {fileID: 0}
|
||||
layerPriority: 0
|
||||
--- !u!95 &8060949548882505714
|
||||
Animator:
|
||||
serializedVersion: 5
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 331101518860596682}
|
||||
m_Enabled: 1
|
||||
m_Avatar: {fileID: 0}
|
||||
m_Controller: {fileID: 0}
|
||||
m_CullingMode: 0
|
||||
m_UpdateMode: 0
|
||||
m_ApplyRootMotion: 0
|
||||
m_LinearVelocityBlending: 0
|
||||
m_StabilizeFeet: 0
|
||||
m_WarningMessage:
|
||||
m_HasTransformHierarchy: 1
|
||||
m_AllowConstantClipSamplingOptimization: 1
|
||||
m_KeepAnimatorStateOnDisable: 0
|
||||
m_WriteDefaultValuesOnDisable: 0
|
||||
--- !u!1 &543650974643626063
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 140504302469088812}
|
||||
m_Layer: 0
|
||||
m_Name: UpperLeg.L
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &140504302469088812
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 543650974643626063}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3047197517193367399}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &952105631822741082
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3047197517193367399}
|
||||
- component: {fileID: 9058074000880147469}
|
||||
m_Layer: 0
|
||||
m_Name: Hips
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &3047197517193367399
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 952105631822741082}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 140504302469088812}
|
||||
- {fileID: 6795937180053589467}
|
||||
m_Father: {fileID: 1051065088277815102}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &9058074000880147469
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 952105631822741082}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 42581d8044b64899834d3d515ab3a144, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
boneReference: 55
|
||||
subPath: parent/relocated-to
|
||||
attachmentMode: 1
|
||||
--- !u!1 &1739058348199845828
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1051065088277815102}
|
||||
m_Layer: 0
|
||||
m_Name: Armature
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1051065088277815102
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1739058348199845828}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 3047197517193367399}
|
||||
m_Father: {fileID: 6576105763171871826}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &3718079119007386003
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4148338894295080238}
|
||||
- component: {fileID: 2535491910780027538}
|
||||
- component: {fileID: 2858884839595194667}
|
||||
- component: {fileID: 694213692129131288}
|
||||
m_Layer: 0
|
||||
m_Name: AvatarMaskRewriteTest
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4148338894295080238
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3718079119007386003}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: -0.28403878, y: 0.6166916, z: -0.25877237}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 4630496911169132430}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!95 &2535491910780027538
|
||||
Animator:
|
||||
serializedVersion: 5
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3718079119007386003}
|
||||
m_Enabled: 1
|
||||
m_Avatar: {fileID: 0}
|
||||
m_Controller: {fileID: 0}
|
||||
m_CullingMode: 0
|
||||
m_UpdateMode: 0
|
||||
m_ApplyRootMotion: 0
|
||||
m_LinearVelocityBlending: 0
|
||||
m_StabilizeFeet: 0
|
||||
m_WarningMessage:
|
||||
m_HasTransformHierarchy: 1
|
||||
m_AllowConstantClipSamplingOptimization: 1
|
||||
m_KeepAnimatorStateOnDisable: 0
|
||||
m_WriteDefaultValuesOnDisable: 0
|
||||
--- !u!114 &2858884839595194667
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3718079119007386003}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 542108242, guid: 67cc4cb7839cd3741b63733d5adf0442, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
Name:
|
||||
ViewPosition: {x: 0, y: 1.6, z: 0.2}
|
||||
Animations: 0
|
||||
ScaleIPD: 1
|
||||
lipSync: 0
|
||||
lipSyncJawBone: {fileID: 0}
|
||||
lipSyncJawClosed: {x: 0, y: 0, z: 0, w: 1}
|
||||
lipSyncJawOpen: {x: 0, y: 0, z: 0, w: 1}
|
||||
VisemeSkinnedMesh: {fileID: 0}
|
||||
MouthOpenBlendShapeName: Facial_Blends.Jaw_Down
|
||||
VisemeBlendShapes: []
|
||||
unityVersion:
|
||||
portraitCameraPositionOffset: {x: 0, y: 0, z: 0}
|
||||
portraitCameraRotationOffset: {x: 0, y: 1, z: 0, w: -0.00000004371139}
|
||||
networkIDs: []
|
||||
customExpressions: 0
|
||||
expressionsMenu: {fileID: 0}
|
||||
expressionParameters: {fileID: 0}
|
||||
enableEyeLook: 0
|
||||
customEyeLookSettings:
|
||||
eyeMovement:
|
||||
confidence: 0.5
|
||||
excitement: 0.5
|
||||
leftEye: {fileID: 0}
|
||||
rightEye: {fileID: 0}
|
||||
eyesLookingStraight:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
eyesLookingUp:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
eyesLookingDown:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
eyesLookingLeft:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
eyesLookingRight:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
eyelidType: 0
|
||||
upperLeftEyelid: {fileID: 0}
|
||||
upperRightEyelid: {fileID: 0}
|
||||
lowerLeftEyelid: {fileID: 0}
|
||||
lowerRightEyelid: {fileID: 0}
|
||||
eyelidsDefault:
|
||||
upper:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
lower:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
eyelidsClosed:
|
||||
upper:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
lower:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
eyelidsLookingUp:
|
||||
upper:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
lower:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
eyelidsLookingDown:
|
||||
upper:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
lower:
|
||||
linked: 1
|
||||
left: {x: 0, y: 0, z: 0, w: 0}
|
||||
right: {x: 0, y: 0, z: 0, w: 0}
|
||||
eyelidsSkinnedMesh: {fileID: 0}
|
||||
eyelidsBlendshapes:
|
||||
customizeAnimationLayers: 1
|
||||
baseAnimationLayers:
|
||||
- isEnabled: 0
|
||||
type: 0
|
||||
animatorController: {fileID: 0}
|
||||
mask: {fileID: 0}
|
||||
isDefault: 1
|
||||
- isEnabled: 0
|
||||
type: 4
|
||||
animatorController: {fileID: 0}
|
||||
mask: {fileID: 0}
|
||||
isDefault: 1
|
||||
- isEnabled: 0
|
||||
type: 5
|
||||
animatorController: {fileID: 9100000, guid: ec60d09b25b60f94eb23ece9a8a4483e,
|
||||
type: 2}
|
||||
mask: {fileID: 0}
|
||||
isDefault: 0
|
||||
specialAnimationLayers:
|
||||
- isEnabled: 0
|
||||
type: 6
|
||||
animatorController: {fileID: 0}
|
||||
mask: {fileID: 0}
|
||||
isDefault: 1
|
||||
- isEnabled: 0
|
||||
type: 7
|
||||
animatorController: {fileID: 0}
|
||||
mask: {fileID: 0}
|
||||
isDefault: 1
|
||||
- isEnabled: 0
|
||||
type: 8
|
||||
animatorController: {fileID: 0}
|
||||
mask: {fileID: 0}
|
||||
isDefault: 1
|
||||
AnimationPreset: {fileID: 0}
|
||||
animationHashSet: []
|
||||
autoFootsteps: 1
|
||||
autoLocomotion: 1
|
||||
collider_head:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_torso:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_footR:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_footL:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_handR:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_handL:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_fingerIndexL:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_fingerMiddleL:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_fingerRingL:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_fingerLittleL:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_fingerIndexR:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_fingerMiddleR:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_fingerRingR:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
collider_fingerLittleR:
|
||||
isMirrored: 1
|
||||
state: 0
|
||||
transform: {fileID: 0}
|
||||
radius: 0
|
||||
height: 0
|
||||
position: {x: 0, y: 0, z: 0}
|
||||
rotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
--- !u!114 &694213692129131288
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3718079119007386003}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -1427037861, guid: 4ecd63eff847044b68db9453ce219299, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
launchedFromSDKPipeline: 0
|
||||
completedSDKPipeline: 0
|
||||
blueprintId:
|
||||
contentType: 0
|
||||
assetBundleUnityVersion:
|
||||
fallbackStatus: 0
|
||||
--- !u!1 &4741986706786512382
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6528027234780562867}
|
||||
m_Layer: 0
|
||||
m_Name: relocated-to
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &6528027234780562867
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4741986706786512382}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4630496911169132430}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &6166177242302574734
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7719834109032320146}
|
||||
m_Layer: 0
|
||||
m_Name: Body
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &7719834109032320146
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6166177242302574734}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 6576105763171871826}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &7750111654287810670
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4630496911169132430}
|
||||
m_Layer: 0
|
||||
m_Name: parent
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4630496911169132430
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7750111654287810670}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 6576105763171871826}
|
||||
- {fileID: 6528027234780562867}
|
||||
m_Father: {fileID: 4148338894295080238}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &8268444398319358879
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6795937180053589467}
|
||||
m_Layer: 0
|
||||
m_Name: UpperLeg.R
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &6795937180053589467
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8268444398319358879}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3047197517193367399}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 813e4c7531d0e5d49983b259e8a32e79
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
155
UnitTests~/Animation/AvatarMask/AvatarMaskTest.cs
Normal file
155
UnitTests~/Animation/AvatarMask/AvatarMaskTest.cs
Normal file
@ -0,0 +1,155 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using nadena.dev.ndmf;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace modular_avatar_tests
|
||||
{
|
||||
public class AvatarMaskTest : TestBase
|
||||
{
|
||||
class ExtractedMask {
|
||||
public int[] humanoidMaskElements;
|
||||
public List<(string, float)> transformMaskElements;
|
||||
|
||||
public ExtractedMask(int[] humanoidMaskElements, List<(string, float)> transformMaskElements)
|
||||
{
|
||||
this.humanoidMaskElements = humanoidMaskElements;
|
||||
this.transformMaskElements = transformMaskElements;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this) return true;
|
||||
if (!(obj is ExtractedMask other)) return false;
|
||||
|
||||
if (!humanoidMaskElements.SequenceEqual(other.humanoidMaskElements)) return false;
|
||||
return transformMaskElements.SequenceEqual(other.transformMaskElements);
|
||||
}
|
||||
|
||||
public static ExtractedMask FromAvatarMask(AvatarMask mask)
|
||||
{
|
||||
var so = new SerializedObject(mask);
|
||||
var m_Mask = so.FindProperty("m_Mask");
|
||||
var m_Elements = so.FindProperty("m_Elements");
|
||||
|
||||
var humanoidMaskElements = new int[m_Mask.arraySize];
|
||||
var maskElementCount = m_Mask.arraySize;
|
||||
for (var i = 0; i < maskElementCount; i++)
|
||||
{
|
||||
var element = m_Mask.GetArrayElementAtIndex(i);
|
||||
humanoidMaskElements[i] = element.intValue;
|
||||
}
|
||||
|
||||
var transformMaskElements = new List<(string, float)>();
|
||||
var transformElementCount = m_Elements.arraySize;
|
||||
for (var i = 0; i < transformElementCount; i++)
|
||||
{
|
||||
var element = m_Elements.GetArrayElementAtIndex(i);
|
||||
var path = element.FindPropertyRelative("m_Path").stringValue;
|
||||
var weight = element.FindPropertyRelative("m_Weight").floatValue;
|
||||
|
||||
transformMaskElements.Add((path, weight));
|
||||
}
|
||||
|
||||
return new ExtractedMask(humanoidMaskElements, transformMaskElements);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void whenAvatarMaskIsPresentOnMergedAnimator_originalMaskIsUnchanged()
|
||||
{
|
||||
var prefab = CreatePrefab("AvatarMaskRewriteTest.prefab");
|
||||
var originalMask = LoadAsset<AvatarMask>("test-mask.mask");
|
||||
|
||||
var originalState = ExtractedMask.FromAvatarMask(originalMask);
|
||||
|
||||
AvatarProcessor.ProcessAvatar(prefab);
|
||||
|
||||
var newMask = findFxLayer(prefab, "test").avatarMask;
|
||||
var baseFxMask = findFxLayer(prefab, "base-fx").avatarMask;
|
||||
Assert.AreNotEqual(originalMask, newMask);
|
||||
Assert.AreNotEqual(originalMask, baseFxMask);
|
||||
|
||||
var newState = ExtractedMask.FromAvatarMask(originalMask);
|
||||
|
||||
Assert.AreEqual(originalState, newState);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void whenAvatarMaskIsPresentOnMergedAnimator_rewritesPathsByPrefix()
|
||||
{
|
||||
var prefab = CreatePrefab("AvatarMaskRewriteTest.prefab");
|
||||
|
||||
AvatarProcessor.ProcessAvatar(prefab);
|
||||
|
||||
// Body -> parent/anim-root/Body
|
||||
|
||||
var newMask = findFxLayer(prefab, "test").avatarMask;
|
||||
var state = ExtractedMask.FromAvatarMask(newMask);
|
||||
|
||||
var parentIndex = state.transformMaskElements.FindIndex(e => e.Item1 == "parent");
|
||||
var animRootIndex = state.transformMaskElements.FindIndex(e => e.Item1 == "parent/anim-root");
|
||||
var bodyIndex = state.transformMaskElements.FindIndex(e => e.Item1 == "parent/anim-root/Body");
|
||||
|
||||
Assert.Greater(parentIndex, -1);
|
||||
Assert.Greater(animRootIndex, -1);
|
||||
Assert.Greater(bodyIndex, -1);
|
||||
|
||||
Assert.Greater(animRootIndex, parentIndex);
|
||||
Assert.Greater(bodyIndex, animRootIndex);
|
||||
|
||||
// Body is still enabled; the injected parent and parent/anim-root are not
|
||||
Assert.IsTrue(state.transformMaskElements[parentIndex].Item2 < 0.5f);
|
||||
Assert.IsTrue(state.transformMaskElements[animRootIndex].Item2 < 0.5f);
|
||||
Assert.IsTrue(state.transformMaskElements[bodyIndex].Item2 > 0.5f);
|
||||
|
||||
// Original paths are removed
|
||||
Assert.IsFalse(state.transformMaskElements.Any(e => e.Item1 == "Body"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void whenObjectMovedByBoneProxy_avatarMaskPathsAreRewritten()
|
||||
{
|
||||
var prefab = CreatePrefab("AvatarMaskRewriteTest.prefab");
|
||||
|
||||
AvatarProcessor.ProcessAvatar(prefab);
|
||||
|
||||
// Armature/Hips -> parent/relocated-to/Hips
|
||||
|
||||
var newMask = findFxLayer(prefab, "test").avatarMask;
|
||||
var state = ExtractedMask.FromAvatarMask(newMask);
|
||||
|
||||
var parentIndex = state.transformMaskElements.FindIndex(e => e.Item1 == "parent");
|
||||
var relocatedToIndex = state.transformMaskElements.FindIndex(e => e.Item1 == "parent/relocated-to");
|
||||
var hipsIndex = state.transformMaskElements.FindIndex(e => e.Item1 == "parent/relocated-to/Hips");
|
||||
// UpperLeg.L will be enabled, .R will be disabled
|
||||
var upperLegLIndex = state.transformMaskElements.FindIndex(e => e.Item1 == "parent/relocated-to/Hips/UpperLeg.L");
|
||||
var upperLegRIndex = state.transformMaskElements.FindIndex(e => e.Item1 == "parent/relocated-to/Hips/UpperLeg.R");
|
||||
|
||||
Assert.Greater(parentIndex, -1);
|
||||
Assert.Greater(relocatedToIndex, -1);
|
||||
Assert.Greater(hipsIndex, -1);
|
||||
Assert.Greater(upperLegLIndex, -1);
|
||||
Assert.Greater(upperLegRIndex, -1);
|
||||
|
||||
Assert.Greater(relocatedToIndex, parentIndex);
|
||||
Assert.Greater(hipsIndex, relocatedToIndex);
|
||||
Assert.Greater(upperLegLIndex, hipsIndex);
|
||||
Assert.Greater(upperLegRIndex, hipsIndex);
|
||||
|
||||
// Hips -> 1, .L -> 1, .R -> 0
|
||||
Assert.IsTrue(state.transformMaskElements[parentIndex].Item2 < 0.5f);
|
||||
Assert.IsTrue(state.transformMaskElements[relocatedToIndex].Item2 < 0.5f);
|
||||
Assert.IsTrue(state.transformMaskElements[hipsIndex].Item2 > 0.5f);
|
||||
Assert.IsTrue(state.transformMaskElements[upperLegLIndex].Item2 > 0.5f);
|
||||
Assert.IsTrue(state.transformMaskElements[upperLegRIndex].Item2 < 0.5f);
|
||||
|
||||
// Original paths are removed
|
||||
Assert.IsFalse(state.transformMaskElements.Any(e => e.Item1 == "Armature/Hips"));
|
||||
Assert.IsFalse(state.transformMaskElements.Any(e => e.Item1 == "Armature/Hips/UpperLeg.L"));
|
||||
Assert.IsFalse(state.transformMaskElements.Any(e => e.Item1 == "Armature/Hips/UpperLeg.R"));
|
||||
}
|
||||
}
|
||||
}
|
3
UnitTests~/Animation/AvatarMask/AvatarMaskTest.cs.meta
Normal file
3
UnitTests~/Animation/AvatarMask/AvatarMaskTest.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb1e5c662bcc4bdba53cc5fd95c54c4a
|
||||
timeCreated: 1725399401
|
72
UnitTests~/Animation/AvatarMask/av-mask-test-ac.controller
Normal file
72
UnitTests~/Animation/AvatarMask/av-mask-test-ac.controller
Normal file
@ -0,0 +1,72 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!91 &9100000
|
||||
AnimatorController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: av-mask-test-ac
|
||||
serializedVersion: 5
|
||||
m_AnimatorParameters: []
|
||||
m_AnimatorLayers:
|
||||
- serializedVersion: 5
|
||||
m_Name: test
|
||||
m_StateMachine: {fileID: 6076016822445767091}
|
||||
m_Mask: {fileID: 31900000, guid: ca0bdd9ea94848f40b9de82a5aefe3c1, type: 2}
|
||||
m_Motions: []
|
||||
m_Behaviours: []
|
||||
m_BlendingMode: 0
|
||||
m_SyncedLayerIndex: -1
|
||||
m_DefaultWeight: 0
|
||||
m_IKPass: 0
|
||||
m_SyncedLayerAffectsTiming: 0
|
||||
m_Controller: {fileID: 9100000}
|
||||
--- !u!1107 &6076016822445767091
|
||||
AnimatorStateMachine:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: test
|
||||
m_ChildStates:
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 6835839612632277213}
|
||||
m_Position: {x: 105.600006, y: 210.40001, z: 0}
|
||||
m_ChildStateMachines: []
|
||||
m_AnyStateTransitions: []
|
||||
m_EntryTransitions: []
|
||||
m_StateMachineTransitions: {}
|
||||
m_StateMachineBehaviours: []
|
||||
m_AnyStatePosition: {x: 50, y: 20, z: 0}
|
||||
m_EntryPosition: {x: 50, y: 120, z: 0}
|
||||
m_ExitPosition: {x: 800, y: 120, z: 0}
|
||||
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
|
||||
m_DefaultState: {fileID: 6835839612632277213}
|
||||
--- !u!1102 &6835839612632277213
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: test
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions: []
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 7400000, guid: 0d8ccd650d65c9f4690d79c89246c906, type: 2}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ff8ee7fe6e04b148bcd1b0f04280efb
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 9100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
72
UnitTests~/Animation/AvatarMask/base-fx-ac.controller
Normal file
72
UnitTests~/Animation/AvatarMask/base-fx-ac.controller
Normal file
@ -0,0 +1,72 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1107 &-9195093947163206206
|
||||
AnimatorStateMachine:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: base-fx
|
||||
m_ChildStates:
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 801668394021468748}
|
||||
m_Position: {x: 163.09534, y: 390.7027, z: 0}
|
||||
m_ChildStateMachines: []
|
||||
m_AnyStateTransitions: []
|
||||
m_EntryTransitions: []
|
||||
m_StateMachineTransitions: {}
|
||||
m_StateMachineBehaviours: []
|
||||
m_AnyStatePosition: {x: 50, y: 20, z: 0}
|
||||
m_EntryPosition: {x: 50, y: 120, z: 0}
|
||||
m_ExitPosition: {x: 800, y: 120, z: 0}
|
||||
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
|
||||
m_DefaultState: {fileID: 801668394021468748}
|
||||
--- !u!91 &9100000
|
||||
AnimatorController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: base-fx-ac
|
||||
serializedVersion: 5
|
||||
m_AnimatorParameters: []
|
||||
m_AnimatorLayers:
|
||||
- serializedVersion: 5
|
||||
m_Name: base-fx
|
||||
m_StateMachine: {fileID: -9195093947163206206}
|
||||
m_Mask: {fileID: 31900000, guid: ca0bdd9ea94848f40b9de82a5aefe3c1, type: 2}
|
||||
m_Motions: []
|
||||
m_Behaviours: []
|
||||
m_BlendingMode: 0
|
||||
m_SyncedLayerIndex: -1
|
||||
m_DefaultWeight: 0
|
||||
m_IKPass: 0
|
||||
m_SyncedLayerAffectsTiming: 0
|
||||
m_Controller: {fileID: 9100000}
|
||||
--- !u!1102 &801668394021468748
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: test
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions: []
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 7400000, guid: 0d8ccd650d65c9f4690d79c89246c906, type: 2}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec60d09b25b60f94eb23ece9a8a4483e
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 9100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
408
UnitTests~/Animation/AvatarMask/test-mask.mask
Normal file
408
UnitTests~/Animation/AvatarMask/test-mask.mask
Normal file
@ -0,0 +1,408 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!319 &31900000
|
||||
AvatarMask:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: test-mask
|
||||
m_Mask: 01000000000000000000000001000000010000000100000001000000010000000100000001000000010000000100000001000000
|
||||
m_Elements:
|
||||
- m_Path:
|
||||
m_Weight: 1
|
||||
- m_Path: Armature
|
||||
m_Weight: 0
|
||||
- m_Path: Armature/Hips
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot/BackRibbon_a.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot/BackRibbon_a.L/BackRibbon_a.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot/BackRibbon_a.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot/BackRibbon_a.R/BackRibbon_a.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot/BackRibbon_b.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot/BackRibbon_b.L/BackRibbon_b.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot/BackRibbon_b.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot/BackRibbon_b.R/BackRibbon_b.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot/BackRibbon_c.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot/BackRibbon_c.L/BackRibbon_c.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot/BackRibbon_c.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/BackRibbonRoot/BackRibbon_c.R/BackRibbon_c.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_a.001
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_a.001/Skirt_a.002
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_a.001/Skirt_a.002/Skirt_a.003
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_b.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_b.001.L/Skirt_b.002.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_b.001.L/Skirt_b.002.L/Skirt_b.003.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_b.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_b.001.R/Skirt_b.002.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_b.001.R/Skirt_b.002.R/Skirt_b.003.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_c.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_c.001.L/Skirt_c.002.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_c.001.L/Skirt_c.002.L/Skirt_c.003.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_c.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_c.001.R/Skirt_c.002.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_c.001.R/Skirt_c.002.R/Skirt_c.003.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_d.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_d.001.L/Skirt_d.002.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_d.001.L/Skirt_d.002.L/Skirt_d.003.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_d.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_d.001.R/Skirt_d.002.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_d.001.R/Skirt_d.002.R/Skirt_d.003.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_e.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_e.001.L/Skirt_e.002.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_e.001.L/Skirt_e.002.L/Skirt_e.003.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_e.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_e.001.R/Skirt_e.002.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_e.001.R/Skirt_e.002.R/Skirt_e.003.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_f.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_f.001.L/Skirt_f.002.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_f.001.L/Skirt_f.002.L/Skirt_f.003.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_f.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_f.001.R/Skirt_f.002.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_f.001.R/Skirt_f.002.R/Skirt_f.003.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_g.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_g.001.L/Skirt_g.002.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_g.001.L/Skirt_g.002.L/Skirt_g.003.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_g.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_g.001.R/Skirt_g.002.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_g.001.R/Skirt_g.002.R/Skirt_g.003.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_h.001
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_h.001/Skirt_h.002
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/SkirtRoot/Skirt_h.001/Skirt_h.002/Skirt_h.003
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/EarRoot
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/EarRoot/Ear.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/EarRoot/Ear.L/Ear.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/EarRoot/Ear.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/EarRoot/Ear.R/Ear.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.L/HairBack_b.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.L/HairBack_b.001.L/HairBack_b.002.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.L/HairBack_b.001.L/HairBack_b.002.L/HairBack_b.003.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.L/HairBack_b.001.L/HairBack_c.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.L/HairBack_b.001.L/HairBack_c.L/HairBack_c.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.L/HairBack_b.001.L/HairBack_d.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.R/HairBack_b.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.R/HairBack_b.001.R/HairBack_b.002.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.R/HairBack_b.001.R/HairBack_b.002.R/HairBack_b.003.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.R/HairBack_b.001.R/HairBack_c.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.R/HairBack_b.001.R/HairBack_c.R/HairBack_c.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_b.R/HairBack_b.001.R/HairBack_d.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_e.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_e.L/HairBack_e.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_e.L/HairBack_e.001.L/HairBack_e.002.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_e.L/HairBack_e.001.L/HairBack_e.002.L/HairBack_e.003.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_e.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_e.R/HairBack_e.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_e.R/HairBack_e.001.R/HairBack_e.002.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_e.R/HairBack_e.001.R/HairBack_e.002.R/HairBack_e.003.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_z.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_z.L/HairBack_z.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_z.L/HairBack_z.001.L/HairBack_z.002.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_z.L/HairBack_z.001.L/HairBack_z.002.L/HairBack_z.003.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_z.L/HairBack_z.004.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_z.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_z.R/HairBack_z.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_z.R/HairBack_z.001.R/HairBack_z.002.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_z.R/HairBack_z.001.R/HairBack_z.002.R/HairBack_z.003.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/HairBack_a/HairBack_a.001/HairBack_z.R/HairBack_z.004.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairfront.001
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairfront.001/Hairfront.002
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairfront1.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairfront1.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairfront2.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairfront2.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairside_a.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairside_a.L/Hairside_a.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairside_a.L/Hairside_a.001.L/Hairside_a.002.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairside_a.L/Hairside_b.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairside_a.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairside_a.R/Hairside_a.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairside_a.R/Hairside_a.001.R/Hairside_a.002.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairside_a.R/Hairside_b.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairside_c.001.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/HairRoot/Hairside_c.001.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/LeftEye
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Neck/Head/RightEye
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Index
|
||||
Proximal.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Index
|
||||
Proximal.L/Index Intermediate.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Index
|
||||
Proximal.L/Index Intermediate.L/Index Distal.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Little
|
||||
Proximal.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Little
|
||||
Proximal.L/Little Intermediate.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Little
|
||||
Proximal.L/Little Intermediate.L/Little Distal.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Middle
|
||||
Proximal.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Middle
|
||||
Proximal.L/Middle Intermediate.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Middle
|
||||
Proximal.L/Middle Intermediate.L/Middle Distal.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Ring
|
||||
Proximal.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Ring
|
||||
Proximal.L/Ring Intermediate.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Ring
|
||||
Proximal.L/Ring Intermediate.L/Ring Distal.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Thumb
|
||||
Proximal.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Thumb
|
||||
Proximal.L/Thumb Intermediate.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.L/UpperArm.L/LowerArm.L/Hand.L/Thumb
|
||||
Proximal.L/Thumb Intermediate.L/Thumb Distal.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Index
|
||||
Proximal.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Index
|
||||
Proximal.R/Index Intermediate.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Index
|
||||
Proximal.R/Index Intermediate.R/Index Distal.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Little
|
||||
Proximal.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Little
|
||||
Proximal.R/Little Intermediate.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Little
|
||||
Proximal.R/Little Intermediate.R/Little Distal.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Little
|
||||
Proximal.R/Little Intermediate.R/Little Distal.R/Little Distal.R_end
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Middle
|
||||
Proximal.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Middle
|
||||
Proximal.R/Middle Intermediate.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Middle
|
||||
Proximal.R/Middle Intermediate.R/Middle Distal.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Ring
|
||||
Proximal.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Ring
|
||||
Proximal.R/Ring Intermediate.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Ring
|
||||
Proximal.R/Ring Intermediate.R/Ring Distal.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Thumb
|
||||
Proximal.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Thumb
|
||||
Proximal.R/Thumb Intermediate.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Spine/Chest/Shoulder.R/UpperArm.R/LowerArm.R/Hand.R/Thumb
|
||||
Proximal.R/Thumb Intermediate.R/Thumb Distal.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/StrapRoot
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/StrapRoot/strap_a
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/StrapRoot/strap_a/strap_a.001
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/StrapRoot/strap_a/strap_a.001/strap_a.002
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/StrapRoot/strap_b
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/StrapRoot/strap_b/strap_b.001
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/StrapRoot/strap_b/strap_b.001/strap_b.002
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Tail
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Tail/Tail.001
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Tail/Tail.001/Tail.002
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Tail/Tail.001/Tail.002/Tail.003
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Tail/Tail.001/Tail.002/Tail.003/Tail.004
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Tail/Tail.001/Tail.002/Tail.003/Tail.004/Tail.005
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/Tail/Tail.001/Tail.002/Tail.003/Tail.004/Tail.005/Tail.006
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/UpperLeg.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/UpperLeg.L/LowerLeg.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/UpperLeg.L/LowerLeg.L/Foot.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/UpperLeg.L/LowerLeg.L/Foot.L/Toes.L
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/UpperLeg.R
|
||||
m_Weight: 0
|
||||
- m_Path: Armature/Hips/UpperLeg.R/LowerLeg.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/UpperLeg.R/LowerLeg.R/Foot.R
|
||||
m_Weight: 1
|
||||
- m_Path: Armature/Hips/UpperLeg.R/LowerLeg.R/Foot.R/Toes.R
|
||||
m_Weight: 1
|
||||
- m_Path: Body
|
||||
m_Weight: 1
|
8
UnitTests~/Animation/AvatarMask/test-mask.mask.meta
Normal file
8
UnitTests~/Animation/AvatarMask/test-mask.mask.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca0bdd9ea94848f40b9de82a5aefe3c1
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 31900000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
53
UnitTests~/Animation/AvatarMask/test.anim
Normal file
53
UnitTests~/Animation/AvatarMask/test.anim
Normal file
@ -0,0 +1,53 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!74 &7400000
|
||||
AnimationClip:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: test
|
||||
serializedVersion: 7
|
||||
m_Legacy: 0
|
||||
m_Compressed: 0
|
||||
m_UseHighQualityCurve: 1
|
||||
m_RotationCurves: []
|
||||
m_CompressedRotationCurves: []
|
||||
m_EulerCurves: []
|
||||
m_PositionCurves: []
|
||||
m_ScaleCurves: []
|
||||
m_FloatCurves: []
|
||||
m_PPtrCurves: []
|
||||
m_SampleRate: 60
|
||||
m_WrapMode: 0
|
||||
m_Bounds:
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
m_Extent: {x: 0, y: 0, z: 0}
|
||||
m_ClipBindingConstant:
|
||||
genericBindings: []
|
||||
pptrCurveMapping: []
|
||||
m_AnimationClipSettings:
|
||||
serializedVersion: 2
|
||||
m_AdditiveReferencePoseClip: {fileID: 0}
|
||||
m_AdditiveReferencePoseTime: 0
|
||||
m_StartTime: 0
|
||||
m_StopTime: 1
|
||||
m_OrientationOffsetY: 0
|
||||
m_Level: 0
|
||||
m_CycleOffset: 0
|
||||
m_HasAdditiveReferencePose: 0
|
||||
m_LoopTime: 0
|
||||
m_LoopBlend: 0
|
||||
m_LoopBlendOrientation: 0
|
||||
m_LoopBlendPositionY: 0
|
||||
m_LoopBlendPositionXZ: 0
|
||||
m_KeepOriginalOrientation: 0
|
||||
m_KeepOriginalPositionY: 1
|
||||
m_KeepOriginalPositionXZ: 0
|
||||
m_HeightFromFeet: 0
|
||||
m_Mirror: 0
|
||||
m_EditorCurves: []
|
||||
m_EulerEditorCurves: []
|
||||
m_HasGenericRootTransform: 0
|
||||
m_HasMotionFloatCurves: 0
|
||||
m_Events: []
|
8
UnitTests~/Animation/AvatarMask/test.anim.meta
Normal file
8
UnitTests~/Animation/AvatarMask/test.anim.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d8ccd650d65c9f4690d79c89246c906
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 7400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Reference in New Issue
Block a user