From 27399ae25b16b463d47d7e52bceba4da3c403e72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=C3=AF=7E?= Date: Mon, 19 Dec 2022 13:34:37 +0100 Subject: [PATCH] Add a first batch of automated tests --- Tests.meta | 8 + Tests/EditMode.meta | 8 + Tests/EditMode/AacEditModeTests.asmdef | 25 + Tests/EditMode/AacEditModeTests.asmdef.meta | 7 + ...ractSimpleSingleLayerAnimatorInternalAC.cs | 50 ++ ...impleSingleLayerAnimatorInternalAC.cs.meta | 3 + Tests/PlayMode.meta | 8 + Tests/PlayMode/AIACAnimatorWideTest.cs | 96 ++++ Tests/PlayMode/AIACAnimatorWideTest.cs.meta | 3 + Tests/PlayMode/AIACBoolTransitionTest.cs | 407 +++++++++++++++++ Tests/PlayMode/AIACBoolTransitionTest.cs.meta | 3 + Tests/PlayMode/AIACStateTest.cs | 198 ++++++++ Tests/PlayMode/AIACStateTest.cs.meta | 11 + Tests/PlayMode/AIACSubStateMachineTest.cs | 205 +++++++++ .../PlayMode/AIACSubStateMachineTest.cs.meta | 3 + Tests/PlayMode/AIACTransitionFunctionsTest.cs | 158 +++++++ .../AIACTransitionFunctionsTest.cs.meta | 3 + Tests/PlayMode/AacPlayModeTests.asmdef | 23 + Tests/PlayMode/AacPlayModeTests.asmdef.meta | 7 + .../PlayMode/AbstractSimpleSingleLayerAIAC.cs | 65 +++ .../AbstractSimpleSingleLayerAIAC.cs.meta | 3 + Tests/PlayMode/GenerationTests.meta | 3 + .../AIACVRCExtensionsDriverGenerationTest.cs | 430 +++++++++++++++++ ...CVRCExtensionsDriverGenerationTest.cs.meta | 3 + .../AIACVRCExtensionsMiscGenerationTest.cs | 431 ++++++++++++++++++ ...IACVRCExtensionsMiscGenerationTest.cs.meta | 3 + 26 files changed, 2164 insertions(+) create mode 100644 Tests.meta create mode 100644 Tests/EditMode.meta create mode 100644 Tests/EditMode/AacEditModeTests.asmdef create mode 100644 Tests/EditMode/AacEditModeTests.asmdef.meta create mode 100644 Tests/EditMode/AbstractSimpleSingleLayerAnimatorInternalAC.cs create mode 100644 Tests/EditMode/AbstractSimpleSingleLayerAnimatorInternalAC.cs.meta create mode 100644 Tests/PlayMode.meta create mode 100644 Tests/PlayMode/AIACAnimatorWideTest.cs create mode 100644 Tests/PlayMode/AIACAnimatorWideTest.cs.meta create mode 100644 Tests/PlayMode/AIACBoolTransitionTest.cs create mode 100644 Tests/PlayMode/AIACBoolTransitionTest.cs.meta create mode 100644 Tests/PlayMode/AIACStateTest.cs create mode 100644 Tests/PlayMode/AIACStateTest.cs.meta create mode 100644 Tests/PlayMode/AIACSubStateMachineTest.cs create mode 100644 Tests/PlayMode/AIACSubStateMachineTest.cs.meta create mode 100644 Tests/PlayMode/AIACTransitionFunctionsTest.cs create mode 100644 Tests/PlayMode/AIACTransitionFunctionsTest.cs.meta create mode 100644 Tests/PlayMode/AacPlayModeTests.asmdef create mode 100644 Tests/PlayMode/AacPlayModeTests.asmdef.meta create mode 100644 Tests/PlayMode/AbstractSimpleSingleLayerAIAC.cs create mode 100644 Tests/PlayMode/AbstractSimpleSingleLayerAIAC.cs.meta create mode 100644 Tests/PlayMode/GenerationTests.meta create mode 100644 Tests/PlayMode/GenerationTests/AIACVRCExtensionsDriverGenerationTest.cs create mode 100644 Tests/PlayMode/GenerationTests/AIACVRCExtensionsDriverGenerationTest.cs.meta create mode 100644 Tests/PlayMode/GenerationTests/AIACVRCExtensionsMiscGenerationTest.cs create mode 100644 Tests/PlayMode/GenerationTests/AIACVRCExtensionsMiscGenerationTest.cs.meta diff --git a/Tests.meta b/Tests.meta new file mode 100644 index 0000000..b25065f --- /dev/null +++ b/Tests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ad91af824b32bed4c8a08541bef67cfe +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/EditMode.meta b/Tests/EditMode.meta new file mode 100644 index 0000000..d607a77 --- /dev/null +++ b/Tests/EditMode.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c745f3802e61ded458735b8e5cf42e16 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/EditMode/AacEditModeTests.asmdef b/Tests/EditMode/AacEditModeTests.asmdef new file mode 100644 index 0000000..36391ae --- /dev/null +++ b/Tests/EditMode/AacEditModeTests.asmdef @@ -0,0 +1,25 @@ +{ + "name": "AacEditModeTests", + "references": [ + "UnityEngine.TestRunner", + "UnityEditor.TestRunner", + "AnimatorAsCodeFramework" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll", + "VRCSDKBase.dll", + "VRCSDK3A.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Tests/EditMode/AacEditModeTests.asmdef.meta b/Tests/EditMode/AacEditModeTests.asmdef.meta new file mode 100644 index 0000000..9f924a3 --- /dev/null +++ b/Tests/EditMode/AacEditModeTests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2a8152e7670c1814abad041ff22b7994 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/EditMode/AbstractSimpleSingleLayerAnimatorInternalAC.cs b/Tests/EditMode/AbstractSimpleSingleLayerAnimatorInternalAC.cs new file mode 100644 index 0000000..c1f2bdf --- /dev/null +++ b/Tests/EditMode/AbstractSimpleSingleLayerAnimatorInternalAC.cs @@ -0,0 +1,50 @@ +using System; +using AnimatorAsCode.V0; +using NUnit.Framework; +using UnityEditor; +using UnityEditor.Animations; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace av3_animator_as_code.Tests.EditMode +{ + public abstract class AbstractSimpleSingleLayerAnimatorInternalEditModeAC + { + protected GameObject _root; + private AnimatorController _container; + private string _containerPath; + + [SetUp] + public void SetUp() + { + _root = new GameObject("Root"); + _container = new AnimatorController(); + _containerPath = $"Assets/temp_aac_test__{Guid.NewGuid()}.asset"; + AssetDatabase.CreateAsset(_container, _containerPath); + } + + [TearDown] + public void TearDown() + { + Object.DestroyImmediate(_root); + AssetDatabase.DeleteAsset(_containerPath); + _root = null; + _container = null; + _containerPath = null; + } + + protected AacFlBase TestAac() + { + return AacV0.Create(new AacConfiguration + { + AnimatorRoot = _root.transform, + AssetContainer = _container, + AssetKey = "None", + AvatarDescriptor = null, + DefaultsProvider = new AacDefaultsProvider(), + SystemName = "Test", + DefaultValueRoot = _root.transform + }); + } + } +} \ No newline at end of file diff --git a/Tests/EditMode/AbstractSimpleSingleLayerAnimatorInternalAC.cs.meta b/Tests/EditMode/AbstractSimpleSingleLayerAnimatorInternalAC.cs.meta new file mode 100644 index 0000000..442b97d --- /dev/null +++ b/Tests/EditMode/AbstractSimpleSingleLayerAnimatorInternalAC.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 16d5c7dc8b974daf8719f0d02f1e3fb3 +timeCreated: 1671470027 \ No newline at end of file diff --git a/Tests/PlayMode.meta b/Tests/PlayMode.meta new file mode 100644 index 0000000..6598557 --- /dev/null +++ b/Tests/PlayMode.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d910756d511fe0b4996d2626cf6fd301 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/PlayMode/AIACAnimatorWideTest.cs b/Tests/PlayMode/AIACAnimatorWideTest.cs new file mode 100644 index 0000000..a53b248 --- /dev/null +++ b/Tests/PlayMode/AIACAnimatorWideTest.cs @@ -0,0 +1,96 @@ +using NUnit.Framework; +using UnityEditor.Animations; +using UnityEngine; +using Assert = UnityEngine.Assertions.Assert; + +namespace av3_animator_as_code.Tests.PlayMode +{ + public class AIACAnimatorWideTest : AbstractSimpleSingleLayerAIAC + { + [Test] + public void It_should_override_bool() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myBool = fx.BoolParameter("MyBool"); + first.TransitionsTo(second).When(myBool.IsTrue()); + fx.OverrideValue(myBool, true); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_override_int() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myInt = fx.IntParameter("MyInt"); + first.TransitionsTo(second).When(myInt.IsGreaterThan(1)); + fx.OverrideValue(myInt, 2); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_override_float() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myFloat = fx.FloatParameter("MyFloat"); + first.TransitionsTo(second).When(myFloat.IsGreaterThan(0.49f)); + fx.OverrideValue(myFloat, 0.5f); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + private static AnimatorStateInfo Info0(Animator animator) + { + return animator.GetCurrentAnimatorStateInfo(0); + } + } +} \ No newline at end of file diff --git a/Tests/PlayMode/AIACAnimatorWideTest.cs.meta b/Tests/PlayMode/AIACAnimatorWideTest.cs.meta new file mode 100644 index 0000000..f1d533f --- /dev/null +++ b/Tests/PlayMode/AIACAnimatorWideTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4b1c43dad69a46c697e2aa9ed5055e63 +timeCreated: 1671493684 \ No newline at end of file diff --git a/Tests/PlayMode/AIACBoolTransitionTest.cs b/Tests/PlayMode/AIACBoolTransitionTest.cs new file mode 100644 index 0000000..be4d041 --- /dev/null +++ b/Tests/PlayMode/AIACBoolTransitionTest.cs @@ -0,0 +1,407 @@ +using NUnit.Framework; +using UnityEditor.Animations; +using UnityEngine; +using Assert = UnityEngine.Assertions.Assert; + +namespace av3_animator_as_code.Tests.PlayMode +{ + public class AIACBoolTransitionTest : AbstractSimpleSingleLayerAIAC + { + [Test] + public void It_should_transition_when_bool_is_true() + { + var controller = new AnimatorController(); + var aac = TestAac(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myBool = fx.BoolParameter("MyBool"); + first.TransitionsTo(second).When(myBool.IsTrue()); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + + // Verify + // Frame 0 + Assert.AreEqual(1, animator.layerCount); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 2 + animator.SetBool("MyBool", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_when_bool_is_false() + { + var controller = new AnimatorController(); + var aac = TestAac(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myBool = fx.BoolParameter("MyBool"); + first.TransitionsTo(second).When(myBool.IsFalse()); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + + // Verify + // Frame 0 + Assert.AreEqual(1, animator.layerCount); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.SetBool("MyBool", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 2 + animator.SetBool("MyBool", false); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_when_both_bools_are_true() + { + var controller = new AnimatorController(); + var aac = TestAac(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myBoolOne = fx.BoolParameter("MyBoolOne"); + var myBoolTwo = fx.BoolParameter("MyBoolTwo"); + first.TransitionsTo(second).When(myBoolOne.IsTrue()).And(myBoolTwo.IsTrue()); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + + // Verify + // Frame 0 + Assert.AreEqual(1, animator.layerCount); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.SetBool("MyBoolOne", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 2 + animator.SetBool("MyBoolOne", false); + animator.SetBool("MyBoolTwo", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 3 + animator.SetBool("MyBoolOne", true); + animator.SetBool("MyBoolTwo", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_when_second_bool_is_true() + { + var controller = new AnimatorController(); + var aac = TestAac(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myBoolOne = fx.BoolParameter("MyBoolOne"); + var myBoolTwo = fx.BoolParameter("MyBoolTwo"); + first.TransitionsTo(second).When(myBoolOne.IsTrue()).Or().When(myBoolTwo.IsTrue()); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + + // Verify + // Frame 0 + Assert.AreEqual(1, animator.layerCount); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 2 + animator.SetBool("MyBoolTwo", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_when_group_of_bools_are_true() + { + var controller = new AnimatorController(); + var aac = TestAac(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myBools = fx.BoolParameters("MyBoolOne", "MyBoolTwo"); + first.TransitionsTo(second).When(myBools.AreTrue()); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + + // Verify + // Frame 0 + Assert.AreEqual(1, animator.layerCount); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 2 + animator.SetBool("MyBoolOne", true); + animator.SetBool("MyBoolTwo", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_when_group_of_bools_are_false() + { + var controller = new AnimatorController(); + var aac = TestAac(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myBools = fx.BoolParameters("MyBoolOne", "MyBoolTwo"); + first.TransitionsTo(second).When(myBools.AreFalse()); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + + // Verify + // Frame 0 + Assert.AreEqual(1, animator.layerCount); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.SetBool("MyBoolOne", true); + animator.SetBool("MyBoolTwo", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 2 + animator.SetBool("MyBoolOne", false); + animator.SetBool("MyBoolTwo", false); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_when_group_of_bools_are_true_except_one_of_them() + { + var controller = new AnimatorController(); + var aac = TestAac(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myBools = fx.BoolParameters("MyBoolOne", "MyBoolTwo", "MyBoolThree"); + first.TransitionsTo(second).When(myBools.AreTrueExcept(fx.BoolParameter("MyBoolThree"))); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + + // Verify + // Frame 0 + Assert.AreEqual(1, animator.layerCount); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.SetBool("MyBoolOne", true); + animator.SetBool("MyBoolTwo", true); + animator.SetBool("MyBoolThree", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 2 + animator.SetBool("MyBoolOne", true); + animator.SetBool("MyBoolTwo", true); + animator.SetBool("MyBoolThree", false); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_when_group_of_bools_are_true_except_another_group_of_them() + { + var controller = new AnimatorController(); + var aac = TestAac(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myBools = fx.BoolParameters("MyBoolOne", "MyBoolTwo", "MyBoolThree", "MyBoolFour"); + first.TransitionsTo(second).When(myBools.AreTrueExcept(fx.BoolParameters("MyBoolThree", "MyBoolFour"))); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + + // Verify + // Frame 0 + Assert.AreEqual(1, animator.layerCount); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.SetBool("MyBoolOne", true); + animator.SetBool("MyBoolTwo", true); + animator.SetBool("MyBoolThree", true); + animator.SetBool("MyBoolFour", false); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 2 + animator.SetBool("MyBoolOne", true); + animator.SetBool("MyBoolTwo", true); + animator.SetBool("MyBoolThree", false); + animator.SetBool("MyBoolFour", false); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_when_any_of_group_of_bools_is_true() + { + var controller = new AnimatorController(); + var aac = TestAac(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myBools = fx.BoolParameters("MyBoolOne", "MyBoolTwo"); + first.TransitionsTo(second).When(myBools.IsAnyTrue()); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + + // Verify + // Frame 0 + Assert.AreEqual(1, animator.layerCount); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 2 + animator.SetBool("MyBoolTwo", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_when_any_of_group_of_bools_is_false() + { + var controller = new AnimatorController(); + var aac = TestAac(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myBools = fx.BoolParameters("MyBoolOne", "MyBoolTwo"); + first.TransitionsTo(second).When(myBools.IsAnyFalse()); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + + // Verify + // Frame 0 + Assert.AreEqual(1, animator.layerCount); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.SetBool("MyBoolOne", true); + animator.SetBool("MyBoolTwo", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 2 + animator.SetBool("MyBoolTwo", false); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_when_any_of_group_of_bools_is_true_and_another_bool_is_also_true() + { + var controller = new AnimatorController(); + var aac = TestAac(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var myBools = fx.BoolParameters("MyBoolOne", "MyBoolTwo"); + var myMandatoryBool = fx.BoolParameter("MyBoolMandatory"); + first.TransitionsTo(second).When(myBools.IsAnyTrue()).And(myMandatoryBool.IsTrue()); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + + // Verify + // Frame 0 + Assert.AreEqual(1, animator.layerCount); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 2 + animator.SetBool("MyBoolOne", true); + animator.SetBool("MyBoolTwo", false); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 3 + animator.SetBool("MyBoolOne", false); + animator.SetBool("MyBoolTwo", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 4 + animator.SetBool("MyBoolOne", false); + animator.SetBool("MyBoolTwo", false); + animator.SetBool("MyBoolMandatory", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 5 + animator.SetBool("MyBoolOne", false); + animator.SetBool("MyBoolTwo", true); + animator.SetBool("MyBoolMandatory", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + private static AnimatorStateInfo Info0(Animator animator) + { + return animator.GetCurrentAnimatorStateInfo(0); + } + } +} \ No newline at end of file diff --git a/Tests/PlayMode/AIACBoolTransitionTest.cs.meta b/Tests/PlayMode/AIACBoolTransitionTest.cs.meta new file mode 100644 index 0000000..655e58d --- /dev/null +++ b/Tests/PlayMode/AIACBoolTransitionTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 922049111725f1a4ebdd237cddadd542 +timeCreated: 1671448209 \ No newline at end of file diff --git a/Tests/PlayMode/AIACStateTest.cs b/Tests/PlayMode/AIACStateTest.cs new file mode 100644 index 0000000..3e7fac1 --- /dev/null +++ b/Tests/PlayMode/AIACStateTest.cs @@ -0,0 +1,198 @@ +using NUnit.Framework; +using UnityEditor.Animations; +using UnityEngine; +using Assert = UnityEngine.Assertions.Assert; + +namespace av3_animator_as_code.Tests.PlayMode +{ + public class AIACStateTest : AbstractSimpleSingleLayerAIAC + { + [Test] + public void It_should_create_layer_with_state() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var init = fx.NewState("Init"); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + + // Verify + Assert.AreEqual(1, animator.layerCount); + var info = animator.GetCurrentAnimatorStateInfo(0); + Assert.IsTrue(info.IsName("Init")); + } + + [Test] + public void It_should_cause_write_defaults_OFF_to_preserve_animated_object_state() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var child = new GameObject + { + name = "Child", + transform = { parent = _root.transform } + }; + var first = fx.NewState("First") + .WithWriteDefaultsSetTo(false) + .WithAnimation(aac.NewClip().Toggling(child, false)); + var second = fx.NewState("Second") + .WithWriteDefaultsSetTo(false); + first.TransitionsTo(second).AfterAnimationFinishes(); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + animator.Update(0f); + Assert.IsTrue(Info0(animator).IsName("First")); + Assert.IsFalse(child.gameObject.activeSelf); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + Assert.IsFalse(child.gameObject.activeSelf); + } + + [Test] + public void It_should_cause_write_defaults_ON_to_revert_animated_object_state() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var child = new GameObject + { + name = "Child", + transform = { parent = _root.transform } + }; + var first = fx.NewState("First") + .WithWriteDefaultsSetTo(true) + .WithAnimation(aac.NewClip().Toggling(child, false)); + var second = fx.NewState("Second") + .WithWriteDefaultsSetTo(true); + first.TransitionsTo(second).AfterAnimationFinishes(); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + animator.Update(0f); + Assert.IsTrue(Info0(animator).IsName("First")); + Assert.IsFalse(child.gameObject.activeSelf); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + Assert.IsTrue(child.gameObject.activeSelf); // The object turns back on + } + + [Test] + public void It_should_apply_motion_time() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var child = new GameObject + { + name = "Child", + transform = { parent = _root.transform } + }; + fx.NewState("First") + .WithAnimation(aac.NewClip().Animating(clip => + { + clip.Animates(child.transform, "m_LocalScale.x").WithSecondsUnit(keyframes => keyframes.Linear(0f, 0f).Linear(1f, 10f)); + })) + .MotionTime(fx.FloatParameter("MyFloat")); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + animator.SetFloat("MyFloat", 0.5f); + animator.Update(1 / 60f); + Assert.AreEqual(5f, child.transform.localScale.x); + } + + [Test] + public void It_should_apply_speed() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var child = new GameObject + { + name = "Child", + transform = { parent = _root.transform } + }; + fx.NewState("First") + .WithAnimation(aac.NewClip().Animating(clip => + { + clip.Animates(child.transform, "m_LocalScale.x").WithSecondsUnit(keyframes => keyframes.Linear(0f, 0f).Linear(1f, 10f)); + })) + .WithSpeed(fx.FloatParameter("MyFloat")); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + animator.SetFloat("MyFloat", 2f); // At double the speed + animator.Update(15 / 60f); // Advance by a quarter of a second + Assert.AreEqual(5f, child.transform.localScale.x); + } + + [Test] + public void It_should_apply_speed_set_to_constant() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var child = new GameObject + { + name = "Child", + transform = { parent = _root.transform } + }; + fx.NewState("First") + .WithAnimation(aac.NewClip().Animating(clip => + { + clip.Animates(child.transform, "m_LocalScale.x").WithSecondsUnit(keyframes => keyframes.Linear(0f, 0f).Linear(1f, 10f)); + })) + .WithSpeedSetTo(2f); // At double the speed + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + animator.Update(15 / 60f); // Advance by a quarter of a second + Assert.AreEqual(5f, child.transform.localScale.x); + } + + private static AnimatorStateInfo Info0(Animator animator) + { + return animator.GetCurrentAnimatorStateInfo(0); + } + } +} \ No newline at end of file diff --git a/Tests/PlayMode/AIACStateTest.cs.meta b/Tests/PlayMode/AIACStateTest.cs.meta new file mode 100644 index 0000000..aadda5d --- /dev/null +++ b/Tests/PlayMode/AIACStateTest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82960f1d631a8964f8ae1d774c729625 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/PlayMode/AIACSubStateMachineTest.cs b/Tests/PlayMode/AIACSubStateMachineTest.cs new file mode 100644 index 0000000..dd3ae78 --- /dev/null +++ b/Tests/PlayMode/AIACSubStateMachineTest.cs @@ -0,0 +1,205 @@ +using NUnit.Framework; +using UnityEditor.Animations; +using UnityEngine; +using Assert = UnityEngine.Assertions.Assert; + +namespace av3_animator_as_code.Tests.PlayMode +{ + public class AIACSubStateMachineTest : AbstractSimpleSingleLayerAIAC + { + [Test] + public void It_should_transition_to_a_SSM() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var ssm = fx.NewSubStateMachine("SSM"); + ssm.NewState("SSM One"); + + first.TransitionsTo(ssm).AfterAnimationFinishes(); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("SSM One")); + } + + [Test] + public void It_should_exit_out_of_a_SSM() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + var ssm = fx.NewSubStateMachine("SSM"); + var one = ssm.NewState("SSM One"); + + first.TransitionsTo(ssm).AfterAnimationFinishes(); + one.Exits().AfterAnimationFinishes(); + ssm.TransitionsTo(second); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("SSM One")); + + // Frame 2 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_restart_the_SSM() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var ssm = fx.NewSubStateMachine("SSM"); + var one = ssm.NewState("SSM One"); + var two = ssm.NewState("SSM Two"); + + first.TransitionsTo(ssm).AfterAnimationFinishes(); + one.TransitionsTo(two).AfterAnimationFinishes(); + two.Exits().AfterAnimationFinishes(); + ssm.Restarts(); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("SSM One")); + + // Frame 2 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("SSM Two")); + + // Frame 3 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("SSM One")); + } + + [Test] + public void It_should_enter_a_SSM_conditionally__Entry_created_through_SSM_instance() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var ssm = fx.NewSubStateMachine("SSM"); + ssm.NewState("SSM One"); + + var two = ssm.NewState("SSM Two"); + first.TransitionsTo(ssm).AfterAnimationFinishes(); + ssm.EntryTransitionsTo(two).When(fx.BoolParameter("MyBool").IsTrue()); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.SetBool("MyBool", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("SSM Two")); + } + + [Test] + public void It_should_enter_a_SSM_conditionally__Entry_created_through_state_instance() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var ssm = fx.NewSubStateMachine("SSM"); + ssm.NewState("SSM One"); + + var two = ssm.NewState("SSM Two"); + first.TransitionsTo(ssm).AfterAnimationFinishes(); + two.TransitionsFromEntry().When(fx.BoolParameter("MyBool").IsTrue()); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.SetBool("MyBool", true); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("SSM Two")); + } + + [Test] + public void It_should_enter_the_default_SSM_entry_state_when_conditions_do_not_pass() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var ssm = fx.NewSubStateMachine("SSM"); + ssm.NewState("SSM One"); + + var two = ssm.NewState("SSM Two"); + first.TransitionsTo(ssm).AfterAnimationFinishes(); + ssm.EntryTransitionsTo(two).When(fx.BoolParameter("MyBool").IsTrue()); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.SetBool("MyBool", false); + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("SSM One")); + } + + private static AnimatorStateInfo Info0(Animator animator) + { + return animator.GetCurrentAnimatorStateInfo(0); + } + } +} \ No newline at end of file diff --git a/Tests/PlayMode/AIACSubStateMachineTest.cs.meta b/Tests/PlayMode/AIACSubStateMachineTest.cs.meta new file mode 100644 index 0000000..be583d6 --- /dev/null +++ b/Tests/PlayMode/AIACSubStateMachineTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2f4c7c62171d461fb2618bc0c52ba098 +timeCreated: 1671454674 \ No newline at end of file diff --git a/Tests/PlayMode/AIACTransitionFunctionsTest.cs b/Tests/PlayMode/AIACTransitionFunctionsTest.cs new file mode 100644 index 0000000..4192099 --- /dev/null +++ b/Tests/PlayMode/AIACTransitionFunctionsTest.cs @@ -0,0 +1,158 @@ +using AnimatorAsCode.V0; +using NUnit.Framework; +using UnityEditor.Animations; +using UnityEngine; +using Assert = UnityEngine.Assertions.Assert; + +namespace av3_animator_as_code.Tests.PlayMode +{ + public class AIACTransitionFunctionsTest : AbstractSimpleSingleLayerAIAC + { + [Test] + public void It_should_transition_after_animation_finishes() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var second = fx.NewState("Second"); + first.TransitionsTo(second).AfterAnimationFinishes(); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 + Assert.IsTrue(Info0(animator).IsName("First")); + + // Frame 1 + animator.Update(1 / 60f); + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_after_animation_finishes_in_2_frames() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.WithAnimation(aac.DummyClipLasting(2, AacFlUnit.Frames)); + var second = fx.NewState("Second"); + first.TransitionsTo(second).AfterAnimationFinishes(); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame 0 & 1 + for (var iter = 0; iter < 2; iter++) + { + Assert.IsTrue(Info0(animator).IsName("First"), $"In iteration {iter}"); + animator.Update(1 / 60f); + } + + // Frame 2 + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_after_animation_finishes_in_3_frames() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.WithAnimation(aac.DummyClipLasting(3, AacFlUnit.Frames)); + var second = fx.NewState("Second"); + first.TransitionsTo(second).AfterAnimationFinishes(); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frames [0:2] + for (var iter = 0; iter < 3; iter++) + { + Assert.IsTrue(Info0(animator).IsName("First"), $"In iteration {iter}"); + animator.Update(1 / 60f); + } + + // Frame 3 + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_after_animation_finishes_in_59_frames() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.WithAnimation(aac.DummyClipLasting(59, AacFlUnit.Frames)); + var second = fx.NewState("Second"); + first.TransitionsTo(second).AfterAnimationFinishes(); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame [0:59] + for (var iter = 0; iter < 59; iter++) + { + Assert.IsTrue(Info0(animator).IsName("First"), $"In iteration {iter}"); + animator.Update(1 / 60f); + } + + // Frame 60 + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + [Test] + public void It_should_transition_after_animation_finishes_in_60_frames_with_plus_one_error() + { + var aac = TestAac(); + var controller = new AnimatorController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.WithAnimation(aac.DummyClipLasting(60, AacFlUnit.Frames)); + var second = fx.NewState("Second"); + first.TransitionsTo(second).AfterAnimationFinishes(); + + var animator = _root.AddComponent(); + animator.runtimeAnimatorController = controller; + animator.enabled = false; + + // Verify + // Frame [0:61] (!!! !!!) + var error = 1; + for (var iter = 0; iter < 60 + error; iter++) + { + Assert.IsTrue(Info0(animator).IsName("First"), $"In iteration {iter}"); + animator.Update(1 / 60f); + } + + // Frame 62 + Assert.IsTrue(Info0(animator).IsName("Second")); + } + + private static AnimatorStateInfo Info0(Animator animator) + { + return animator.GetCurrentAnimatorStateInfo(0); + } + } +} \ No newline at end of file diff --git a/Tests/PlayMode/AIACTransitionFunctionsTest.cs.meta b/Tests/PlayMode/AIACTransitionFunctionsTest.cs.meta new file mode 100644 index 0000000..43eeca0 --- /dev/null +++ b/Tests/PlayMode/AIACTransitionFunctionsTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1cef528fbc6d417d8fa3514caf3ed5c1 +timeCreated: 1671447626 \ No newline at end of file diff --git a/Tests/PlayMode/AacPlayModeTests.asmdef b/Tests/PlayMode/AacPlayModeTests.asmdef new file mode 100644 index 0000000..90f54d3 --- /dev/null +++ b/Tests/PlayMode/AacPlayModeTests.asmdef @@ -0,0 +1,23 @@ +{ + "name": "AacPlayModeTests", + "references": [ + "UnityEngine.TestRunner", + "UnityEditor.TestRunner", + "AnimatorAsCodeFramework" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll", + "VRCSDKBase.dll", + "VRCSDK3A.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Tests/PlayMode/AacPlayModeTests.asmdef.meta b/Tests/PlayMode/AacPlayModeTests.asmdef.meta new file mode 100644 index 0000000..08164eb --- /dev/null +++ b/Tests/PlayMode/AacPlayModeTests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 22f62403ac909d54983bb7a357420cfe +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/PlayMode/AbstractSimpleSingleLayerAIAC.cs b/Tests/PlayMode/AbstractSimpleSingleLayerAIAC.cs new file mode 100644 index 0000000..d8d44b2 --- /dev/null +++ b/Tests/PlayMode/AbstractSimpleSingleLayerAIAC.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections; +using AnimatorAsCode.V0; +using NUnit.Framework; +using UnityEditor; +using UnityEditor.Animations; +using UnityEngine; +using UnityEngine.TestTools; +using Object = UnityEngine.Object; + +namespace av3_animator_as_code.Tests.PlayMode +{ + public abstract class AbstractSimpleSingleLayerAIAC + { + protected GameObject _root; + private AnimatorController _container; + private string _containerPath; + private AnimatorController _controller; + private string _controllerPath; + + [SetUp] + public void SetUp() + { + _root = new GameObject("Root"); + _container = new AnimatorController(); + _containerPath = $"Assets/temp_aac_test__container_{Guid.NewGuid()}.asset"; + AssetDatabase.CreateAsset(_container, _containerPath); + } + + [TearDown] + public void TearDown() + { + Object.Destroy(_root); + AssetDatabase.DeleteAsset(_containerPath); + if (_controllerPath != null) AssetDatabase.DeleteAsset(_controllerPath); + _root = null; + _container = null; + _containerPath = null; + _controller = null; + _controllerPath = null; + } + + protected AnimatorController NewPersistentController() + { + _controller = new AnimatorController(); + _controllerPath = $"Assets/temp_aac_test__ctrl_{Guid.NewGuid()}.asset"; + AssetDatabase.CreateAsset(_controller, _controllerPath); + return _controller; + } + + protected AacFlBase TestAac() + { + return AacV0.Create(new AacConfiguration + { + AnimatorRoot = _root.transform, + AssetContainer = _container, + AssetKey = "None", + AvatarDescriptor = null, + DefaultsProvider = new AacDefaultsProvider(), + SystemName = "Test", + DefaultValueRoot = _root.transform + }); + } + } +} \ No newline at end of file diff --git a/Tests/PlayMode/AbstractSimpleSingleLayerAIAC.cs.meta b/Tests/PlayMode/AbstractSimpleSingleLayerAIAC.cs.meta new file mode 100644 index 0000000..173f909 --- /dev/null +++ b/Tests/PlayMode/AbstractSimpleSingleLayerAIAC.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3f1941d210754dfd911bed075ed1b01d +timeCreated: 1671447669 \ No newline at end of file diff --git a/Tests/PlayMode/GenerationTests.meta b/Tests/PlayMode/GenerationTests.meta new file mode 100644 index 0000000..8eeb328 --- /dev/null +++ b/Tests/PlayMode/GenerationTests.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e7156157f9fa4cb289a54f1b57f39f3f +timeCreated: 1671471108 \ No newline at end of file diff --git a/Tests/PlayMode/GenerationTests/AIACVRCExtensionsDriverGenerationTest.cs b/Tests/PlayMode/GenerationTests/AIACVRCExtensionsDriverGenerationTest.cs new file mode 100644 index 0000000..7bc3d68 --- /dev/null +++ b/Tests/PlayMode/GenerationTests/AIACVRCExtensionsDriverGenerationTest.cs @@ -0,0 +1,430 @@ +using AnimatorAsCode.V0.Extensions.VRChat; +using NUnit.Framework; +using VRC.SDK3.Avatars.Components; +using VRC.SDKBase; + +namespace av3_animator_as_code.Tests.PlayMode.GenerationTests +{ + public class AIACVRCExtensionsDriverGenerationTest : AbstractSimpleSingleLayerAIAC + { + [Test] + public void It_generates_a_driver_that_sets_bool_to_true() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.Drives(fx.BoolParameter("MyBool"), true); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyBool", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Set, eParameter.type); + Assert.AreEqual(1f, eParameter.value); + } + + [Test] + public void It_generates_a_driver_that_sets_bool_to_false() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.Drives(fx.BoolParameter("MyBool"), false); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyBool", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Set, eParameter.type); + Assert.AreEqual(0f, eParameter.value); + } + + [Test] + public void It_generates_a_driver_that_sets_int_to_300() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.Drives(fx.IntParameter("MyInt"), 300); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyInt", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Set, eParameter.type); + Assert.AreEqual(300f, eParameter.value); + } + + [Test] + public void It_generates_a_driver_that_sets_float_to_400_point_56() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.Drives(fx.FloatParameter("MyFloat"), 400.56f); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyFloat", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Set, eParameter.type); + Assert.AreEqual(400.56f, eParameter.value); + } + + [Test] + public void It_generates_a_driver_that_increases_int_by_2() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.DrivingIncreases(fx.IntParameter("MyInt"), 2); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyInt", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Add, eParameter.type); + Assert.AreEqual(2f, eParameter.value); + } + + [Test] + public void It_generates_a_driver_that_decreases_int_by_2_through_adding_its_opposite() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.DrivingDecreases(fx.IntParameter("MyInt"), 2); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyInt", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Add, eParameter.type); + Assert.AreEqual(-2f, eParameter.value); + } + + [Test] + public void It_generates_a_driver_that_increases_float_by_3_point_4() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.DrivingIncreases(fx.FloatParameter("MyFloat"), 3.4f); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyFloat", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Add, eParameter.type); + Assert.AreEqual(3.4f, eParameter.value); + } + + [Test] + public void It_generates_a_driver_that_decreases_float_by_3_point_4_through_adding_its_opposite() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.DrivingDecreases(fx.FloatParameter("MyFloat"), 3.4f); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyFloat", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Add, eParameter.type); + Assert.AreEqual(-3.4f, eParameter.value); + } + + [Test] + public void It_generates_a_driver_that_copies_a_bool_to_another_bool() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.DrivingCopies(fx.BoolParameter("MyBoolSource"), fx.BoolParameter("MyBoolDestination")); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyBoolDestination", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Copy, eParameter.type); + Assert.IsFalse(eParameter.convertRange); + Assert.AreEqual("MyBoolSource", eParameter.source); + } + + [Test] + public void It_generates_a_driver_that_copies_a_bool_to_an_int() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.DrivingCopies(fx.BoolParameter("MyBoolSource"), fx.IntParameter("MyIntDestination")); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyIntDestination", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Copy, eParameter.type); + Assert.IsFalse(eParameter.convertRange); + Assert.AreEqual("MyBoolSource", eParameter.source); + } + + [Test] + public void It_generates_a_driver_that_copies_a_bool_to_a_float() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.DrivingCopies(fx.BoolParameter("MyBoolSource"), fx.FloatParameter("MyFloatDestination")); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyFloatDestination", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Copy, eParameter.type); + Assert.IsFalse(eParameter.convertRange); + Assert.AreEqual("MyBoolSource", eParameter.source); + } + + [Test] + public void It_generates_a_driver_that_copies_an_int_to_another_int() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.DrivingCopies(fx.IntParameter("MyIntSource"), fx.IntParameter("MyIntDestination")); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyIntDestination", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Copy, eParameter.type); + Assert.IsFalse(eParameter.convertRange); + Assert.AreEqual("MyIntSource", eParameter.source); + } + + [Test] + public void It_generates_a_driver_that_copies_a_float_to_another_float() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.DrivingCopies(fx.FloatParameter("MyFloatSource"), fx.FloatParameter("MyFloatDestination")); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyFloatDestination", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Copy, eParameter.type); + Assert.IsFalse(eParameter.convertRange); + Assert.AreEqual("MyFloatSource", eParameter.source); + } + + [Test] + public void It_generates_a_driver_that_remaps_a_bool_to_another_bool_to_invert_its_value() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.DrivingRemaps(fx.BoolParameter("MyBoolSource"), false, true, fx.BoolParameter("MyBoolDestination"), true, false); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyBoolDestination", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Copy, eParameter.type); + Assert.IsTrue(eParameter.convertRange); + Assert.AreEqual("MyBoolSource", eParameter.source); + Assert.AreEqual(0f, eParameter.sourceMin); + Assert.AreEqual(1f, eParameter.sourceMax); + Assert.AreEqual(1f, eParameter.destMin); + Assert.AreEqual(0f, eParameter.destMax); + } + + [Test] + public void It_generates_a_driver_that_remaps_an_int_percentage_to_a_joystick_float() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.DrivingRemaps(fx.IntParameter("MyIntSource"), 0, 100, fx.FloatParameter("MyFloatDestination"), -1f, 1f); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyFloatDestination", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Copy, eParameter.type); + Assert.IsTrue(eParameter.convertRange); + Assert.AreEqual("MyIntSource", eParameter.source); + Assert.AreEqual(0f, eParameter.sourceMin); + Assert.AreEqual(100f, eParameter.sourceMax); + Assert.AreEqual(-1f, eParameter.destMin); + Assert.AreEqual(1f, eParameter.destMax); + } + + [Test] + public void It_generates_a_driver_that_remaps_an_analog_float_to_an_inverse_joystick_float() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.DrivingRemaps(fx.FloatParameter("MyFloatSource"), 0, 1f, fx.FloatParameter("MyFloatDestination"), 1f, -1f); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAvatarParameterDriver)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAvatarParameterDriver), eBehaviour.GetType()); + Assert.AreEqual(1, eBehaviour.parameters.Count); + + var eParameter = eBehaviour.parameters[0]; + Assert.AreEqual("MyFloatDestination", eParameter.name); + Assert.AreEqual(VRC_AvatarParameterDriver.ChangeType.Copy, eParameter.type); + Assert.IsTrue(eParameter.convertRange); + Assert.AreEqual("MyFloatSource", eParameter.source); + Assert.AreEqual(0f, eParameter.sourceMin); + Assert.AreEqual(1f, eParameter.sourceMax); + Assert.AreEqual(1f, eParameter.destMin); + Assert.AreEqual(-1f, eParameter.destMax); + } + } +} \ No newline at end of file diff --git a/Tests/PlayMode/GenerationTests/AIACVRCExtensionsDriverGenerationTest.cs.meta b/Tests/PlayMode/GenerationTests/AIACVRCExtensionsDriverGenerationTest.cs.meta new file mode 100644 index 0000000..68f20b6 --- /dev/null +++ b/Tests/PlayMode/GenerationTests/AIACVRCExtensionsDriverGenerationTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1445919b64254b28a3330b2111691f7c +timeCreated: 1671469798 \ No newline at end of file diff --git a/Tests/PlayMode/GenerationTests/AIACVRCExtensionsMiscGenerationTest.cs b/Tests/PlayMode/GenerationTests/AIACVRCExtensionsMiscGenerationTest.cs new file mode 100644 index 0000000..0bd19d0 --- /dev/null +++ b/Tests/PlayMode/GenerationTests/AIACVRCExtensionsMiscGenerationTest.cs @@ -0,0 +1,431 @@ +using AnimatorAsCode.V0.Extensions.VRChat; +using NUnit.Framework; +using VRC.SDK3.Avatars.Components; +using VRC.SDKBase; + +namespace av3_animator_as_code.Tests.PlayMode.GenerationTests +{ + public class AIACVRCExtensionsMiscGenerationTest : AbstractSimpleSingleLayerAIAC + { + [Test] + public void It_generates_a_tracking_that_tracks_head() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.Head; + first.TrackingTracks(whichElement); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Tracking, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_animates_head() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.Head; + first.TrackingAnimates(whichElement); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_sets_head_to_tracking() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.Head; + first.TrackingSets(whichElement, VRC_AnimatorTrackingControl.TrackingType.Tracking); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Tracking, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_sets_Head_to_animation() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.Head; + first.TrackingSets(whichElement, VRC_AnimatorTrackingControl.TrackingType.Animation); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_sets_LeftHand_to_animation() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.LeftHand; + first.TrackingSets(whichElement, VRC_AnimatorTrackingControl.TrackingType.Animation); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_sets_RightHand_to_animation() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.RightHand; + first.TrackingSets(whichElement, VRC_AnimatorTrackingControl.TrackingType.Animation); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_sets_Hip_to_animation() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.Hip; + first.TrackingSets(whichElement, VRC_AnimatorTrackingControl.TrackingType.Animation); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_sets_LeftFoot_to_animation() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.LeftFoot; + first.TrackingSets(whichElement, VRC_AnimatorTrackingControl.TrackingType.Animation); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_sets_RightFoot_to_animation() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.RightFoot; + first.TrackingSets(whichElement, VRC_AnimatorTrackingControl.TrackingType.Animation); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_sets_LeftFingers_to_animation() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.LeftFingers; + first.TrackingSets(whichElement, VRC_AnimatorTrackingControl.TrackingType.Animation); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_sets_RightFingers_to_animation() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.RightFingers; + first.TrackingSets(whichElement, VRC_AnimatorTrackingControl.TrackingType.Animation); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_sets_Eyes_to_animation() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.Eyes; + first.TrackingSets(whichElement, VRC_AnimatorTrackingControl.TrackingType.Animation); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_sets_Mouth_to_animation() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + var whichElement = TrackingElement.Mouth; + first.TrackingSets(whichElement, VRC_AnimatorTrackingControl.TrackingType.Animation); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingMouth); + } + + [Test] + public void It_generates_a_tracking_that_sets_Head_and_Both_Hands_to_animation() + { + var aac = TestAac(); + var controller = NewPersistentController(); + var fx = aac.CreateMainArbitraryControllerLayer(controller); + + // Exercise + var first = fx.NewState("First"); + first.TrackingSets(TrackingElement.Head, VRC_AnimatorTrackingControl.TrackingType.Animation); + first.TrackingSets(TrackingElement.LeftHand, VRC_AnimatorTrackingControl.TrackingType.Animation); + first.TrackingSets(TrackingElement.RightHand, VRC_AnimatorTrackingControl.TrackingType.Animation); + + // Verify + var eState = controller.layers[0].stateMachine.states[0].state; + Assert.AreEqual(1, eState.behaviours.Length); + + var eBehaviour = (VRCAnimatorTrackingControl)eState.behaviours[0]; + Assert.AreEqual(typeof(VRCAnimatorTrackingControl), eBehaviour.GetType()); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingHead); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingLeftHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.Animation, eBehaviour.trackingRightHand); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingHip); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFoot); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingLeftFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingRightFingers); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingEyes); + Assert.AreEqual(VRC_AnimatorTrackingControl.TrackingType.NoChange, eBehaviour.trackingMouth); + } + } +} \ No newline at end of file diff --git a/Tests/PlayMode/GenerationTests/AIACVRCExtensionsMiscGenerationTest.cs.meta b/Tests/PlayMode/GenerationTests/AIACVRCExtensionsMiscGenerationTest.cs.meta new file mode 100644 index 0000000..b89f2ed --- /dev/null +++ b/Tests/PlayMode/GenerationTests/AIACVRCExtensionsMiscGenerationTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 89d6538a829c478d894320a1b1830359 +timeCreated: 1671494253 \ No newline at end of file