mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2024-12-29 18:55:06 +08:00
132 lines
5.7 KiB
C#
132 lines
5.7 KiB
C#
#if MA_VRCSDK3_AVATARS
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using nadena.dev.modular_avatar.core;
|
|
using nadena.dev.modular_avatar.core.editor;
|
|
using NUnit.Framework;
|
|
using UnityEditor;
|
|
using UnityEditor.Animations;
|
|
using UnityEngine;
|
|
using VRC.SDK3.Avatars.Components;
|
|
using AvatarProcessor = nadena.dev.ndmf.AvatarProcessor;
|
|
|
|
namespace modular_avatar_tests
|
|
{
|
|
public class MergeBlendTreeTest : TestBase
|
|
{
|
|
[Test]
|
|
public void SimpleMergeTest()
|
|
{
|
|
BlendTree bt1 = new BlendTree();
|
|
bt1.blendParameter = "abcd";
|
|
bt1.blendParameterY = "defg";
|
|
bt1.blendType = BlendTreeType.Simple1D;
|
|
bt1.AddChild(AnimationTestUtil.AnimationWithPath("a"));
|
|
|
|
BlendTree bt2 = new BlendTree();
|
|
bt2.blendParameter = "p1";
|
|
bt2.blendParameterY = "p2";
|
|
bt2.blendType = BlendTreeType.FreeformCartesian2D;
|
|
bt2.AddChild(AnimationTestUtil.AnimationWithPath("b"));
|
|
|
|
var root = CreateRoot("root");
|
|
var c1 = CreateChild(root, "child1");
|
|
var mergeComponent = c1.AddComponent<ModularAvatarMergeBlendTree>();
|
|
mergeComponent.BlendTree = bt1;
|
|
mergeComponent.PathMode = MergeAnimatorPathMode.Relative;
|
|
CreateChild(c1, "a");
|
|
|
|
var c2 = CreateChild(root, "child2");
|
|
var mergeComponent2 = c2.AddComponent<ModularAvatarMergeBlendTree>();
|
|
mergeComponent2.BlendTree = bt2;
|
|
mergeComponent2.PathMode = MergeAnimatorPathMode.Absolute;
|
|
CreateChild(c2, "b");
|
|
|
|
AvatarProcessor.ProcessAvatar(root);
|
|
|
|
var fxController = FindController(root, VRCAvatarDescriptor.AnimLayerType.FX).animatorController as AnimatorController;
|
|
var fx = findFxLayer(root, MergeBlendTreePass.BlendTreeLayerName);
|
|
Assert.AreSame(fxController.layers[0].stateMachine, fx.stateMachine);
|
|
Assert.AreEqual(1, fx.stateMachine.states.Length);
|
|
|
|
var motion = fx.stateMachine.states[0].state.motion as BlendTree;
|
|
Assert.AreEqual(BlendTreeType.Direct, motion.blendType);
|
|
Assert.AreEqual(2, motion.children.Length);
|
|
Assert.AreEqual(MergeBlendTreePass.ALWAYS_ONE, motion.children[0].directBlendParameter);
|
|
Assert.AreEqual(MergeBlendTreePass.ALWAYS_ONE, motion.children[1].directBlendParameter);
|
|
AnimationTestUtil.AssertAnimationHasPath(((BlendTree)motion.children[0].motion).children[0].motion as AnimationClip, "child1/a");
|
|
AnimationTestUtil.AssertAnimationHasPath(((BlendTree)motion.children[1].motion).children[0].motion as AnimationClip, "b");
|
|
|
|
Assert.IsTrue(fxController.parameters.Any(p =>
|
|
p.name == "abcd" && p.type == AnimatorControllerParameterType.Float));
|
|
Assert.IsFalse(fxController.parameters.Any(p =>
|
|
p.name == "defg" && p.type == AnimatorControllerParameterType.Float));
|
|
Assert.IsTrue(fxController.parameters.Any(p =>
|
|
p.name == "p1" && p.type == AnimatorControllerParameterType.Float));
|
|
Assert.IsTrue(fxController.parameters.Any(p =>
|
|
p.name == "p2" && p.type == AnimatorControllerParameterType.Float));
|
|
Assert.IsTrue(fxController.parameters.Any(p =>
|
|
p.name == MergeBlendTreePass.ALWAYS_ONE && p.type == AnimatorControllerParameterType.Float
|
|
&& Math.Abs(p.defaultFloat - 1.0f) < 0.0001f));
|
|
}
|
|
|
|
[Test]
|
|
public void AlternateRootTest()
|
|
{
|
|
BlendTree bt = new BlendTree();
|
|
bt.AddChild(AnimationTestUtil.AnimationWithPath("a"));
|
|
|
|
var root = CreateRoot("root");
|
|
var c1 = CreateChild(root, "child1");
|
|
var mergeComponent = c1.AddComponent<ModularAvatarMergeBlendTree>();
|
|
mergeComponent.BlendTree = bt;
|
|
mergeComponent.PathMode = MergeAnimatorPathMode.Relative;
|
|
mergeComponent.RelativePathRoot.referencePath = "child2";
|
|
CreateChild(c1, "a");
|
|
|
|
var c2 = CreateChild(root, "child2");
|
|
CreateChild(c2, "a");
|
|
|
|
AvatarProcessor.ProcessAvatar(root);
|
|
|
|
var fx = findFxLayer(root, MergeBlendTreePass.BlendTreeLayerName);
|
|
var motion = fx.stateMachine.states[0].state.motion as BlendTree;
|
|
|
|
AnimationTestUtil.AssertAnimationHasPath(((BlendTree)motion.children[0].motion).children[0].motion as AnimationClip, "child2/a");
|
|
}
|
|
|
|
[Test]
|
|
public void MergeOrderTest()
|
|
{
|
|
var root = CreateRoot("root");
|
|
var bt = new BlendTree();
|
|
|
|
var c1 = CreateChild(root, "child1");
|
|
var mergeComponent = c1.AddComponent<ModularAvatarMergeBlendTree>();
|
|
mergeComponent.BlendTree = bt;
|
|
|
|
TestMerge(root, "m1");
|
|
TestMerge(root, "m2").layerPriority = int.MinValue;
|
|
TestMerge(root, "m3").layerPriority = int.MaxValue;
|
|
|
|
AvatarProcessor.ProcessAvatar(root);
|
|
|
|
var layerNames = (FindController(root, VRCAvatarDescriptor.AnimLayerType.FX).animatorController as AnimatorController)
|
|
.layers.Select(l => l.name).ToArray();
|
|
|
|
Assert.AreEqual(new[] {MergeBlendTreePass.BlendTreeLayerName, "m2", "Eyes", "FaceMood", "m1", "m3"}, layerNames);
|
|
}
|
|
|
|
ModularAvatarMergeAnimator TestMerge(GameObject root, string mergeName, Motion motion = null)
|
|
{
|
|
var obj = CreateChild(root, mergeName);
|
|
var merge = obj.AddComponent<ModularAvatarMergeAnimator>();
|
|
merge.animator = AnimationTestUtil.TestController(mergeName, motion);
|
|
|
|
return merge;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif |