diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorPlayback/TestAnimatorPlayback.cs b/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorPlayback/TestAnimatorPlayback.cs index d9913f3..8ddce65 100644 --- a/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorPlayback/TestAnimatorPlayback.cs +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorPlayback/TestAnimatorPlayback.cs @@ -1,6 +1,7 @@ using Adnc.AnimatorHelpers.Conditions; using Adnc.AnimatorHelpers.Variables; using Adnc.Utility.Testing; +using Adnc.AnimatorHelpers.Editors.Testing.Utilities; using NUnit.Framework; using UnityEngine; using Object = UnityEngine.Object; @@ -10,35 +11,41 @@ public class TestAnimatorPlayback : TestBase { private const string ANIMATOR_STUB_LOC = "AnimatorTesting/AnimatorStub"; private AnimatorPlayback _playback; - private Animator _anim; + private AnimatorStub _stub; [SetUp] public void SetupAnimatorPlayback () { _playback = ScriptableObject.CreateInstance(); - var stub = Resources.Load(ANIMATOR_STUB_LOC); - _anim = Object.Instantiate(stub).GetComponent(); + + _stub = new AnimatorStub(new GameObject("AnimatorStub")); + _stub.AnimatorCtrl.AddParameter("bool", AnimatorControllerParameterType.Bool); + _stub.AnimatorCtrl.AddParameter("float", AnimatorControllerParameterType.Float); + _stub.AnimatorCtrl.AddParameter("int", AnimatorControllerParameterType.Int); + _stub.AnimatorCtrl.AddParameter("trigger", AnimatorControllerParameterType.Trigger); + + _stub.InjectCtrl(); } [TearDown] public void TeardownAnimatorPlayback () { - Object.DestroyImmediate(_anim.gameObject); + Object.DestroyImmediate(_stub.Animator.gameObject); _playback = null; - _anim = null; + _stub = null; } [Test] public void StubBoolIsFalse () { - Assert.IsFalse(_anim.GetBool("bool")); + Assert.IsFalse(_stub.Animator.GetBool("bool")); } [Test] public void StubFloatIsZero () { - Assert.IsTrue(Mathf.Abs(_anim.GetFloat("float")) < 0.1f); + Assert.IsTrue(Mathf.Abs(_stub.Animator.GetFloat("float")) < 0.1f); } [Test] public void StubIntIsZero () { - Assert.IsTrue(_anim.GetInteger("int") == 0); + Assert.IsTrue(_stub.Animator.GetInteger("int") == 0); } [Test] @@ -48,9 +55,9 @@ public void PlaySetsAnimatorBool () { value = true }); - _playback.Play(_anim); + _playback.Play(_stub.Animator); - Assert.IsTrue(_anim.GetBool("bool")); + Assert.IsTrue(_stub.Animator.GetBool("bool")); } [Test] @@ -60,9 +67,9 @@ public void PlaySetsAnimatorFloat () { value = 1 }); - _playback.Play(_anim); + _playback.Play(_stub.Animator); - Assert.AreEqual(_anim.GetFloat("float"), 1); + Assert.AreEqual(_stub.Animator.GetFloat("float"), 1); } [Test] @@ -72,9 +79,9 @@ public void PlaySetsAnimatorInt () { value = 1 }); - _playback.Play(_anim); + _playback.Play(_stub.Animator); - Assert.AreEqual(_anim.GetInteger("int"), 1); + Assert.AreEqual(_stub.Animator.GetInteger("int"), 1); } [Test] @@ -85,7 +92,7 @@ public void IsConditionMetTrueWithNoAnimatorNull () { [Test] public void IsConditionMetIsTrueWithNoConditions () { _playback.conditions.RemoveAt(0); - Assert.IsTrue(_playback.IsConditionsMet(_anim)); + Assert.IsTrue(_playback.IsConditionsMet(_stub.Animator)); } [Test] @@ -100,7 +107,7 @@ public void IsConditionMetFalseWhenConditionsNotMet () { variableType = ConditionVarType.Bool }); - Assert.IsFalse(_playback.IsConditionsMet(_anim)); + Assert.IsFalse(_playback.IsConditionsMet(_stub.Animator)); } [Test] @@ -115,9 +122,11 @@ public void IsConditionMetTrueWhenConditionsAreMet () { variableType = ConditionVarType.Bool }); - _anim.SetBool("bool", true); + _stub.Animator.SetBool("bool", true); - Assert.IsTrue(_playback.IsConditionsMet(_anim)); + Assert.IsTrue(_playback.IsConditionsMet(_stub.Animator)); } + + } } diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorStub.meta b/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorStub.meta new file mode 100644 index 0000000..205cba2 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorStub.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 398b717c3ad8425b9f5e8f7c29fc0040 +timeCreated: 1514425430 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorStub/TestAnimatorStub.cs b/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorStub/TestAnimatorStub.cs new file mode 100644 index 0000000..964666c --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorStub/TestAnimatorStub.cs @@ -0,0 +1,146 @@ +using Adnc.Utility.Testing; +using Adnc.AnimatorHelpers.Editors.Testing.Utilities; +using NUnit.Framework; +using UnityEngine; + +namespace Adnc.AnimatorHelpers.Editors.Testing { + public class TestAnimatorStub : TestBase { + private GameObject _go; + private AnimatorStub _animStub; + + [SetUp] + public void Setup () { + _go = new GameObject("AnimatorStub"); + } + + [TearDown] + public void Teardown () { + Object.DestroyImmediate(_go); + } + + [Test] + public void DoesNotFailCreationIfNoGameObject () { + var stub = new AnimatorStub(null); + + Assert.IsTrue(stub.IsValid); + } + + [Test] + public void CreatesIfGameObjectPassedIn () { + var stub = new AnimatorStub(_go); + + Assert.IsTrue(stub.IsValid); + } + + [Test] + public void AttachRuntimeController () { + var stub = new AnimatorStub(_go); + + stub.InjectCtrl(); + + Assert.AreSame(stub.Animator.runtimeAnimatorController, stub.AnimatorCtrl); + } + + [Test] + public void GetAnimatorParameter () { + var stub = new AnimatorStub(_go); + const string param = "test"; + + stub.AnimatorCtrl.AddParameter(param, AnimatorControllerParameterType.Bool); + stub.InjectCtrl(); + var result = stub.Animator.GetBool(param); + + Assert.IsFalse(result); + } + + [Test] + public void SetAnimatorParameter () { + var stub = new AnimatorStub(_go); + const string param = "test"; + + stub.AnimatorCtrl.AddParameter(param, AnimatorControllerParameterType.Bool); + stub.InjectCtrl(); + stub.Animator.SetBool(param, true); + var result = stub.Animator.GetBool(param); + + Assert.IsTrue(result); + } + + [Test] + public void CreateNewLayerReturnsLayer () { + var stub = new AnimatorStub(_go); + var layer = stub.AddLayer("Test"); + + Assert.IsNotNull(layer); + } + + [Test] + public void CreateNewLayerAddsAnotherLayer () { + var stub = new AnimatorStub(_go); + stub.AddLayer("Test"); + + Assert.AreEqual(stub.AnimatorCtrl.layers.Length, 2); + } + + [Test] + public void CreateNewLayerSetsName () { + var layerName = "Test"; + var stub = new AnimatorStub(_go); + var layer = stub.AddLayer(layerName); + + Assert.AreEqual(layerName, layer.name); + } + + [Test] + public void CreateNewLayerSetsStateMachine () { + var stub = new AnimatorStub(_go); + var layer = stub.AddLayer("Test"); + + Assert.IsNotNull(layer.stateMachine); + } + + [Test] + public void CreateNewLayerCreatesAtLeastOneState () { + var stub = new AnimatorStub(_go); + var layer = stub.AddLayer("Test"); + + Assert.IsTrue(layer.stateMachine.states.Length >= 1); + } + + [Test] + public void CreateNewLayerSetsDefaultState () { + var stub = new AnimatorStub(_go); + var layer = stub.AddLayer("Test"); + + Assert.IsNotNull(layer.stateMachine.defaultState); + } + + [Test] + public void PlayAdvancesToTheNextState () { + var stub = new AnimatorStub(_go); + var layer = stub.AnimatorCtrl.layers[0]; + const string stateName = "New State"; + var state = layer.stateMachine.AddState(stateName); + var trans = layer.stateMachine.defaultState.AddTransition(state); + + layer.stateMachine.defaultState.AddTransition(state); + trans.hasExitTime = true; + stub.InjectCtrl(); + stub.Animator.Update(10); + + var stateInfo = stub.Animator.GetCurrentAnimatorStateInfo(0); + Assert.IsTrue(stateInfo.IsName(stateName)); + } + + [Test] + public void RuntimeControllerNameSameAsCreationName () { + var stub = new AnimatorStub(_go); + + stub.AnimatorCtrl.name = "asdf"; + stub.InjectCtrl(); + + Assert.AreEqual(stub.AnimatorCtrl.name, stub.Animator.runtimeAnimatorController.name); + Assert.AreNotEqual(stub.Animator.gameObject.name, stub.Animator.runtimeAnimatorController.name); + } + } +} \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorStub/TestAnimatorStub.cs.meta b/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorStub/TestAnimatorStub.cs.meta new file mode 100644 index 0000000..350221e --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/AnimatorStub/TestAnimatorStub.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1a7ff51069de4853993454e05329a7ab +timeCreated: 1514422879 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter.meta b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter.meta new file mode 100644 index 0000000..8316e14 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ec808eee2e764200abc2b1abb1643ae6 +timeCreated: 1514504311 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestAnimatorParameters.cs b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestAnimatorParameters.cs new file mode 100644 index 0000000..f838596 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestAnimatorParameters.cs @@ -0,0 +1,105 @@ +using System; +using Adnc.AnimatorHelpers.Editors.Testing.Utilities; +using Adnc.AnimatorHelpers.HasParameters; +using Adnc.Utility.Testing; +using NUnit.Framework; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace Adnc.AnimatorHelpers.Editors.Testing.HasParameters { + [TestFixture(Category = "HasParameter")] + public class TestAnimatorParameters : TestBase { + private AnimatorStub _stub; + + [SetUp] + public void Setup () { + _stub = new AnimatorStub(); + } + + [TearDown] + public void Teardown () { + Object.DestroyImmediate(_stub.Animator.gameObject); + _stub = null; + } + + [Test] + public void ErrorsOnNullAnimatorConstructor () { + Assert.Throws(() => { new AnimatorParameters(null); }); + } + + [Test] + public void DoesNotCrashOnNullAnimatorParameters () { + _stub.InjectCtrl(); + var par = new AnimatorParameters(_stub.Animator); + } + + [Test] + public void StoresAllParameters () { + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "a", + defaultBool = true, + type = AnimatorControllerParameterType.Bool + }); + + _stub.InjectCtrl(); + var par = new AnimatorParameters(_stub.Animator); + + Assert.IsTrue(par.parameters.dic.ContainsKey("a")); + } + + [Test] + public void StoresAllBools () { + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "a", + defaultBool = true, + type = AnimatorControllerParameterType.Bool + }); + + _stub.InjectCtrl(); + var par = new AnimatorParameters(_stub.Animator); + + Assert.IsTrue(par.bools.dic.ContainsKey("a")); + } + + [Test] + public void StoresAllFloats () { + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "a", + defaultFloat = 1, + type = AnimatorControllerParameterType.Float + }); + + _stub.InjectCtrl(); + var par = new AnimatorParameters(_stub.Animator); + + Assert.IsTrue(par.floats.dic.ContainsKey("a")); + } + + [Test] + public void StoresAllInts () { + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "a", + defaultInt = 1, + type = AnimatorControllerParameterType.Int + }); + + _stub.InjectCtrl(); + var par = new AnimatorParameters(_stub.Animator); + + Assert.IsTrue(par.ints.dic.ContainsKey("a")); + } + + [Test] + public void StoresAllTriggers () { + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "a", + type = AnimatorControllerParameterType.Trigger + }); + + _stub.InjectCtrl(); + var par = new AnimatorParameters(_stub.Animator); + + Assert.IsTrue(par.triggers.dic.ContainsKey("a")); + } + } +} \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestAnimatorParameters.cs.meta b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestAnimatorParameters.cs.meta new file mode 100644 index 0000000..6e4cb33 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestAnimatorParameters.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dfd3f899a0e44f65b01f33bdf4c04dc4 +timeCreated: 1514505628 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestAnimatorParametersCollection.cs b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestAnimatorParametersCollection.cs new file mode 100644 index 0000000..ae94cdb --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestAnimatorParametersCollection.cs @@ -0,0 +1,120 @@ +using System; +using Adnc.AnimatorHelpers.Editors.Testing.Utilities; +using Adnc.AnimatorHelpers.HasParameters; +using Adnc.Utility.Testing; +using NUnit.Framework; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace Adnc.AnimatorHelpers.Editors.Testing.HasParameters { + [TestFixture(Category = "HasParameter")] + public class TestAnimatorParametersCollection : TestBase { + private AnimatorParametersCollection _animParCol; + private AnimatorStub _stub; + + [SetUp] + public void Setup () { + _animParCol = new AnimatorParametersCollection(); + _stub = new AnimatorStub(); + + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + defaultBool = true, + name = "a", + type = AnimatorControllerParameterType.Bool + }); + } + + [TearDown] + public void Teardown () { + Object.DestroyImmediate(_stub.Animator.gameObject); + _stub = null; + } + + [Test] + public void SetParameterReturnsAnimatorParameters () { + _stub.InjectCtrl(); + var ps = _animParCol.SetParameters("a", _stub.Animator); + + Assert.IsNotNull(ps); + } + + [Test] + public void SetParameterStoresCachedAnimator () { + _stub.InjectCtrl(); + var ps = _animParCol.SetParameters("a", _stub.Animator); + var psCache = _animParCol.GetParameters("a"); + + Assert.AreSame(ps, psCache); + } + + [Test] + public void SetAnimatorEmptyStringErrors () { + Assert.Throws(() => { + _animParCol.SetParameters("", _stub.Animator); + }); + } + + [Test] + public void SetAnimatorNullStringErrors () { + Assert.Throws(() => { + _animParCol.SetParameters(null, _stub.Animator); + }); + } + + [Test] + public void SetAnimatorNullAnimatorErrors () { + Assert.Throws(() => { + _animParCol.SetParameters("a", null); + }); + } + + [Test] + public void GetMissingAnimatorParametersReturnsNull () { + Assert.IsNull(_animParCol.GetParameters("a")); + } + + [Test] + public void GetParametersNullReturnsError () { + Assert.Throws(() => { + _animParCol.GetParameters(null); + }); + } + + [Test] + public void GetParametersEmptyStringReturnsError () { + Assert.Throws(() => { + _animParCol.GetParameters(""); + }); + } + + [Test] + public void GetParametersAutoGeneratesCacheIfItDoesNotExist () { + _stub.InjectCtrl(); + var psCache = _animParCol.GetParameters("a", _stub.Animator); + + Assert.IsNotNull(psCache); + Assert.IsTrue(_animParCol.HasParameters("a")); + } + + [Test] + public void GetParametersDoesNotAutoGenerateCacheIfItExists () { + _stub.InjectCtrl(); + var ps = _animParCol.SetParameters("a", _stub.Animator); + + Assert.AreSame(ps, _animParCol.GetParameters("a", _stub.Animator)); + } + + [Test] + public void HasParametersReturnsTrueIfParameters () { + _stub.InjectCtrl(); + var ps = _animParCol.SetParameters("a", _stub.Animator); + + Assert.IsTrue(_animParCol.HasParameters("a")); + } + + [Test] + public void HasParametersReturnsFalseIfNoParameters () { + Assert.IsFalse(_animParCol.HasParameters("a")); + } + } +} \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestAnimatorParametersCollection.cs.meta b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestAnimatorParametersCollection.cs.meta new file mode 100644 index 0000000..5f420be --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestAnimatorParametersCollection.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 66cf147f67cf45f893e04221ee08c945 +timeCreated: 1514506980 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestHasParametersExtensions.cs b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestHasParametersExtensions.cs new file mode 100644 index 0000000..1eeb5f9 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestHasParametersExtensions.cs @@ -0,0 +1,227 @@ +using Adnc.AnimatorHelpers.Editors.Testing.Utilities; +using Adnc.AnimatorHelpers.HasParameters; +using Adnc.Utility.Testing; +using NUnit.Framework; +using UnityEngine; + +namespace Adnc.AnimatorHelpers.Editors.Testing.HasParameters { + [TestFixture(Category = "HasParameter")] + public class TestHasParametersExtensions : TestBase { + private AnimatorStub _stub; + private AnimatorHelperRuntime _runtime; + + [SetUp] + public void Setup () { + _runtime = new GameObject("AnimatorRuntime").AddComponent(); + _stub = new AnimatorStub(); + + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "bool", + type = AnimatorControllerParameterType.Bool + }); + + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "float", + type = AnimatorControllerParameterType.Float + }); + + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "int", + type = AnimatorControllerParameterType.Int + }); + + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "trigger", + type = AnimatorControllerParameterType.Trigger + }); + } + + [TearDown] + public void Teardown () { + Object.DestroyImmediate(_stub.Animator.gameObject); + _stub = null; + + Object.DestroyImmediate(_runtime.gameObject); + AnimatorHelperRuntime.ClearSingleton(); + _runtime = null; + } + + [Test] + public void HasParameterDoesNotFailOnMultipleIdenticalKeyNames () { + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "bool", + type = AnimatorControllerParameterType.Float + }); + + _stub.InjectCtrl(); + + Assert.IsTrue(_stub.Animator.HasParameter("bool")); + } + + [Test] + public void HasParameterWorksWithPreCaching () { + _stub.InjectCtrl(); + AnimatorHelperRuntime.Instance.Cache(_stub.Animator); + var id = _stub.Animator.runtimeAnimatorController.name; + + Assert.IsTrue(AnimatorHelperRuntime.Instance.parameters.HasParameters(id)); + Assert.IsTrue(_stub.Animator.HasParameter("bool")); + } + + // @TODO Move cahce test onto a AnimatorHelperRuntime testing class + [Test] + public void HasParameterGetsTheSameParameterCacheAcrossAnimatorControllers () { + _stub.InjectCtrl(); + _stub.Animator.HasParameter("bool"); + + var clone = Object.Instantiate(_stub.Animator.gameObject).GetComponent(); + var id = clone.runtimeAnimatorController.name; + + Assert.IsTrue(AnimatorHelperRuntime.Instance.parameters.HasParameters(id)); + + Assert.IsTrue(clone.HasParameter("bool")); + + Object.DestroyImmediate(clone.gameObject); + } + + [Test] + public void HasParameterReturnsTrue () { + _stub.InjectCtrl(); + + Assert.IsTrue(_stub.Animator.HasParameter("bool")); + } + + [Test] + public void HasParameterReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasParameter("asdf")); + } + + [Test] + public void HasParameterEmptyReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasParameter("")); + } + + [Test] + public void HasParameterNullReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasParameter(null)); + } + + [Test] + public void HasBoolReturnsTrue () { + _stub.InjectCtrl(); + + Assert.IsTrue(_stub.Animator.HasBool("bool")); + } + + [Test] + public void HasBoolReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasBool("asdf")); + } + + [Test] + public void HasBoolEmptyReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasBool("")); + } + + [Test] + public void HasBoolNullReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasBool(null)); + } + + [Test] + public void HasFloatReturnsTrue () { + _stub.InjectCtrl(); + + Assert.IsTrue(_stub.Animator.HasFloat("float")); + } + + [Test] + public void HasFloatReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasFloat("asdf")); + } + + [Test] + public void HasFloatEmptyReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasFloat("")); + } + + [Test] + public void HasFloatNullReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasFloat(null)); + } + + [Test] + public void HasIntReturnsTrue () { + _stub.InjectCtrl(); + + Assert.IsTrue(_stub.Animator.HasInt("int")); + } + + [Test] + public void HasIntReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasInt("asdf")); + } + + [Test] + public void HasIntEmptyReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasInt("")); + } + + [Test] + public void HasIntNullReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasInt(null)); + } + + [Test] + public void HasTriggerReturnsTrue () { + _stub.InjectCtrl(); + + Assert.IsTrue(_stub.Animator.HasTrigger("trigger")); + } + + [Test] + public void HasTriggerReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasTrigger("asdf")); + } + + [Test] + public void HasTriggerEmptyReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasTrigger("")); + } + + [Test] + public void HasTriggerNullReturnsFalse () { + _stub.InjectCtrl(); + + Assert.IsFalse(_stub.Animator.HasTrigger(null)); + } + } +} \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestHasParametersExtensions.cs.meta b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestHasParametersExtensions.cs.meta new file mode 100644 index 0000000..1cb2361 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestHasParametersExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 57b9372d955542df993f522c1a9c9256 +timeCreated: 1514508493 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestHasParametersExtensionsStressTests.cs b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestHasParametersExtensionsStressTests.cs new file mode 100644 index 0000000..eda24eb --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestHasParametersExtensionsStressTests.cs @@ -0,0 +1,69 @@ +using Adnc.AnimatorHelpers.Editors.Testing.Utilities; +using Adnc.AnimatorHelpers.HasParameters; +using Adnc.Utility.Testing; +using NUnit.Framework; +using UnityEngine; + +namespace Adnc.AnimatorHelpers.Editors.Testing.HasParameters { + [TestFixture(Category = "HasParameter")] + public class TestHasParametersExtensionsStressTests : TestBase { + private AnimatorStub _stub; + private AnimatorHelperRuntime _runtime; + + [SetUp] + public void Setup () { + _runtime = new GameObject("AnimatorRuntime").AddComponent(); + _stub = new AnimatorStub(); + } + + [TearDown] + public void Teardown () { + Object.DestroyImmediate(_stub.Animator.gameObject); + _stub = null; + + Object.DestroyImmediate(_runtime.gameObject); + AnimatorHelperRuntime.ClearSingleton(); + _runtime = null; + } + + [Test] + public void CallWithSingleParameter () { + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "bool", + type = AnimatorControllerParameterType.Bool + }); + + _stub.InjectCtrl(); + + _stub.Animator.HasBool("bool"); + } + + [Test] + public void CallWithHundredParameters () { + for (var i = 0; i < 100; i++) { + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "bool" + i, + type = AnimatorControllerParameterType.Bool + }); + } + + _stub.InjectCtrl(); + + _stub.Animator.HasBool("bool"); + } + + [Test] + public void CallWithThosandParameters () { + for (var i = 0; i < 1000; i++) { + _stub.AnimatorCtrl.AddParameter(new AnimatorControllerParameter { + name = "bool" + i, + type = AnimatorControllerParameterType.Bool + }); + } + + _stub.InjectCtrl(); + + _stub.Animator.HasBool("bool"); + } + } +} \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestHasParametersExtensionsStressTests.cs.meta b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestHasParametersExtensionsStressTests.cs.meta new file mode 100644 index 0000000..0ceed65 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestHasParametersExtensionsStressTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a4d53d6b3f5c48ba86ebe3925ca92b3d +timeCreated: 1514508532 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestParameters.cs b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestParameters.cs new file mode 100644 index 0000000..baeffcd --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestParameters.cs @@ -0,0 +1,36 @@ +using Adnc.AnimatorHelpers.HasParameters; +using Adnc.Utility.Testing; +using NUnit.Framework; + +namespace Adnc.AnimatorHelpers.Editors.Testing.HasParameters { + [TestFixture(Category = "HasParameter")] + public class TestParameters : TestBase { + [Test] + public void AddIncrementsList () { + var p = new Parameters(); + + p.Add("a", true); + + Assert.That(p.list.Count, Is.GreaterThan(0)); + } + + [Test] + public void AddInjectsKeyValueIntoList () { + var p = new Parameters(); + + var kv = p.Add("a", true); + + Assert.That(p.list, Contains.Item(kv)); + } + + [Test] + public void AddInjectsKeyValueIntoDictionary () { + var p = new Parameters(); + + var kv = p.Add("a", true); + + Assert.That(p.dic, Contains.Key(kv.key)); + Assert.IsTrue(p.dic.ContainsValue(kv)); + } + } +} \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestParameters.cs.meta b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestParameters.cs.meta new file mode 100644 index 0000000..bb149d0 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/HasParameter/TestParameters.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 90ba4c81723b4e7e957382cead9ace08 +timeCreated: 1514504351 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/Utilities.meta b/Assets/AdncAnimatorHelpers/Editor/Testing/Utilities.meta new file mode 100644 index 0000000..ada2a0e --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/Utilities.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5d2746f3628f40c7b8ddcf035be4a137 +timeCreated: 1514425299 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/Utilities/AnimatorStub.cs b/Assets/AdncAnimatorHelpers/Editor/Testing/Utilities/AnimatorStub.cs new file mode 100644 index 0000000..253e53f --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/Utilities/AnimatorStub.cs @@ -0,0 +1,73 @@ +using UnityEditor.Animations; +using UnityEngine; + +namespace Adnc.AnimatorHelpers.Editors.Testing.Utilities { + public class AnimatorStub { + /// + /// Reference to the Animator attached to the passed GameObject + /// + public Animator Animator { get; private set; } + + /// + /// Reference to an automatically generated AnimatorController + /// + public AnimatorController AnimatorCtrl { get; private set; } + + /// + /// Is this a valid AnimatorStub? + /// + public bool IsValid { + get { return Animator != null && AnimatorCtrl != null; } + } + + /// + /// Inject the animator stub onto a GameObject + /// + /// + public AnimatorStub (GameObject target = null) { + if (target == null) { + target = new GameObject("AnimatorStub"); + } + + Animator = target.AddComponent(); + AnimatorCtrl = new AnimatorController {name = "AnimatorDefault"}; + + AddLayer("Default"); + } + + /// + /// Create new layers on the Animator with a specific name + /// + /// + /// + public AnimatorControllerLayer AddLayer (string name) { + var layer = new AnimatorControllerLayer { + name = name, + stateMachine = new AnimatorStateMachine { + name = "Default" + } + }; + + layer.stateMachine.defaultState = layer.stateMachine.AddState("Default"); + AnimatorCtrl.AddLayer(layer); + + return layer; + } + + /// + /// Should be called when you want to inject your AnimatorController into you Animator. WARNING! Once you + /// do this it creates a static instance of your AnimatorController and you cannot change it. + /// + public void InjectCtrl () { + Animator.runtimeAnimatorController = AnimatorCtrl; + } + + void LogError (string error) { + if (!Application.isPlaying) { + return; + } + + Debug.LogError(error); + } + } +} diff --git a/Assets/AdncAnimatorHelpers/Editor/Testing/Utilities/AnimatorStub.cs.meta b/Assets/AdncAnimatorHelpers/Editor/Testing/Utilities/AnimatorStub.cs.meta new file mode 100644 index 0000000..9c97071 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Editor/Testing/Utilities/AnimatorStub.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9867d31a1c2d4da593fcc61ce27f393a +timeCreated: 1514425341 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Examples/Default.meta b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback.meta similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default.meta rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback.meta diff --git a/Assets/AdncAnimatorHelpers/Examples/Default/AnimatorExample.controller b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/AnimatorExample.controller similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default/AnimatorExample.controller rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/AnimatorExample.controller diff --git a/Assets/AdncAnimatorHelpers/Examples/Default/AnimatorExample.controller.meta b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/AnimatorExample.controller.meta similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default/AnimatorExample.controller.meta rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/AnimatorExample.controller.meta diff --git a/Assets/AdncAnimatorHelpers/Examples/Default/AnimatorPlaybackExample.cs b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/AnimatorPlaybackExample.cs similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default/AnimatorPlaybackExample.cs rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/AnimatorPlaybackExample.cs diff --git a/Assets/AdncAnimatorHelpers/Examples/Default/AnimatorPlaybackExample.cs.meta b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/AnimatorPlaybackExample.cs.meta similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default/AnimatorPlaybackExample.cs.meta rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/AnimatorPlaybackExample.cs.meta diff --git a/Assets/AdncAnimatorHelpers/Examples/Default/Default.unity b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/Default.unity similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default/Default.unity rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/Default.unity diff --git a/Assets/AdncAnimatorHelpers/Examples/Default/Default.unity.meta b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/Default.unity.meta similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default/Default.unity.meta rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/Default.unity.meta diff --git a/Assets/AdncAnimatorHelpers/Examples/Default/FadeSquare.anim b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/FadeSquare.anim similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default/FadeSquare.anim rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/FadeSquare.anim diff --git a/Assets/AdncAnimatorHelpers/Examples/Default/FadeSquare.anim.meta b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/FadeSquare.anim.meta similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default/FadeSquare.anim.meta rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/FadeSquare.anim.meta diff --git a/Assets/AdncAnimatorHelpers/Examples/Default/PlaybackExample.asset b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/PlaybackExample.asset similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default/PlaybackExample.asset rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/PlaybackExample.asset diff --git a/Assets/AdncAnimatorHelpers/Examples/Default/PlaybackExample.asset.meta b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/PlaybackExample.asset.meta similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default/PlaybackExample.asset.meta rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/PlaybackExample.asset.meta diff --git a/Assets/AdncAnimatorHelpers/Examples/Default/Square.png b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/Square.png similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default/Square.png rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/Square.png diff --git a/Assets/AdncAnimatorHelpers/Examples/Default/Square.png.meta b/Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/Square.png.meta similarity index 100% rename from Assets/AdncAnimatorHelpers/Examples/Default/Square.png.meta rename to Assets/AdncAnimatorHelpers/Examples/AnimatorPlayback/Square.png.meta diff --git a/Assets/AdncAnimatorHelpers/Scripts/AnimatorHelperRuntime.meta b/Assets/AdncAnimatorHelpers/Scripts/AnimatorHelperRuntime.meta new file mode 100644 index 0000000..179169f --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/AnimatorHelperRuntime.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6d99ba8900a6488dbe212301152b4cbe +timeCreated: 1514432326 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/AnimatorHelperRuntime/AnimatorHelperRuntime.cs b/Assets/AdncAnimatorHelpers/Scripts/AnimatorHelperRuntime/AnimatorHelperRuntime.cs new file mode 100644 index 0000000..53e3dfa --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/AnimatorHelperRuntime/AnimatorHelperRuntime.cs @@ -0,0 +1,13 @@ +using Adnc.AnimatorHelpers.HasParameters; +using UnityEngine; +using Adnc.Utility.Singletons; + +namespace Adnc.AnimatorHelpers { + public class AnimatorHelperRuntime : SingletonBase { + public AnimatorParametersCollection parameters = new AnimatorParametersCollection(); + + public void Cache (Animator animator) { + parameters.SetParameters(animator.runtimeAnimatorController.name, animator); + } + } +} \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/AnimatorHelperRuntime/AnimatorHelperRuntime.cs.meta b/Assets/AdncAnimatorHelpers/Scripts/AnimatorHelperRuntime/AnimatorHelperRuntime.cs.meta new file mode 100644 index 0000000..3ad1497 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/AnimatorHelperRuntime/AnimatorHelperRuntime.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4a7afd3e1f2c4d9ab60e3e9a23e39fd8 +timeCreated: 1514432336 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/HasParameter.meta b/Assets/AdncAnimatorHelpers/Scripts/HasParameter.meta new file mode 100644 index 0000000..e09a08f --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/HasParameter.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 280309cb8dae452492ab598df745fc3a +timeCreated: 1514445879 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/HasParameter/AnimatorParameters.cs b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/AnimatorParameters.cs new file mode 100644 index 0000000..bd5ffce --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/AnimatorParameters.cs @@ -0,0 +1,39 @@ +using System; +using UnityEngine; + +namespace Adnc.AnimatorHelpers.HasParameters { + public class AnimatorParameters { + public readonly Parameters parameters = new Parameters(); + public readonly Parameters bools = new Parameters(); + public readonly Parameters ints = new Parameters(); + public readonly Parameters floats = new Parameters(); + public readonly Parameters triggers = new Parameters(); + + public AnimatorParameters (Animator animator) { + if (animator == null) { + throw new ArgumentNullException("animator"); + } + + foreach (var p in animator.parameters) { + parameters.Add(p.name, p); + + switch (p.type) { + case AnimatorControllerParameterType.Float: + floats.Add(p.name, p.defaultFloat); + break; + case AnimatorControllerParameterType.Int: + ints.Add(p.name, p.defaultInt); + break; + case AnimatorControllerParameterType.Bool: + bools.Add(p.name, p.defaultBool); + break; + case AnimatorControllerParameterType.Trigger: + triggers.Add(p.name, p.name); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/HasParameter/AnimatorParameters.cs.meta b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/AnimatorParameters.cs.meta new file mode 100644 index 0000000..e9c069f --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/AnimatorParameters.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0cfbc22467084aaa9a703a6c04fc74f9 +timeCreated: 1514446909 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/HasParameter/AnimatorParametersCollection.cs b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/AnimatorParametersCollection.cs new file mode 100644 index 0000000..3583ee0 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/AnimatorParametersCollection.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Adnc.AnimatorHelpers.HasParameters { + public class AnimatorParametersCollection { + private Dictionary _dic = new Dictionary(); + + public AnimatorParameters SetParameters (string id, Animator animator) { + if (string.IsNullOrEmpty(id)) { + throw new ArgumentNullException(id); + } + + var ap = new AnimatorParameters(animator); + _dic.Add(id, ap); + + return ap; + } + + public AnimatorParameters GetParameters (string id) { + if (string.IsNullOrEmpty(id)) { + throw new ArgumentNullException("id"); + } + + AnimatorParameters result; + _dic.TryGetValue(id, out result); + + return result; + } + + public AnimatorParameters GetParameters (string id, Animator setOnEmpty) { + var result = GetParameters(id); + if (result == null) { + result = SetParameters(id, setOnEmpty); + } + + return result; + } + + public bool HasParameters (string id) { + return _dic.ContainsKey(id); + } + } +} \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/HasParameter/AnimatorParametersCollection.cs.meta b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/AnimatorParametersCollection.cs.meta new file mode 100644 index 0000000..6457df8 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/AnimatorParametersCollection.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b3268d3df677439d8f998ca83031a577 +timeCreated: 1514447432 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/HasParameter/HasParametersExtensions.cs b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/HasParametersExtensions.cs new file mode 100644 index 0000000..1e9e691 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/HasParametersExtensions.cs @@ -0,0 +1,91 @@ +using UnityEngine; + +namespace Adnc.AnimatorHelpers.HasParameters { + public static class HasParametersExtensions { + private static AnimatorParameters GetAnimatorParameters (Animator animator) { + var id = animator.runtimeAnimatorController.name; + var parameters = AnimatorHelperRuntime.Instance.parameters.GetParameters(id, animator); + return parameters; + } + + /// + /// Checks if this Animator has a parameter with the passed string name + /// + /// + /// + /// + public static bool HasParameter (this Animator animator, string name) { + if (string.IsNullOrEmpty(name)) { + return false; + } + + var parameters = GetAnimatorParameters(animator); + + return parameters.parameters.dic.ContainsKey(name); + } + + /// + /// Checks if this Animator has a bool with the passed string name + /// + /// + /// + /// + public static bool HasBool (this Animator animator, string name) { + if (string.IsNullOrEmpty(name)) { + return false; + } + + var parameters = GetAnimatorParameters(animator); + + return parameters.bools.dic.ContainsKey(name); + } + + /// + /// Checks if this Animator has an int with the passed string name + /// + /// + /// + /// + public static bool HasInt (this Animator animator, string name) { + if (string.IsNullOrEmpty(name)) { + return false; + } + + var parameters = GetAnimatorParameters(animator); + + return parameters.ints.dic.ContainsKey(name); + } + + /// + /// Checks if this Animator has a float with the passed string name + /// + /// + /// + /// + public static bool HasFloat (this Animator animator, string name) { + if (string.IsNullOrEmpty(name)) { + return false; + } + + var parameters = GetAnimatorParameters(animator); + + return parameters.floats.dic.ContainsKey(name); + } + + /// + /// Checks if this Animator has a trigger with the passed string name + /// + /// + /// + /// + public static bool HasTrigger (this Animator animator, string name) { + if (string.IsNullOrEmpty(name)) { + return false; + } + + var parameters = GetAnimatorParameters(animator); + + return parameters.triggers.dic.ContainsKey(name); + } + } +} \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/HasParameter/HasParametersExtensions.cs.meta b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/HasParametersExtensions.cs.meta new file mode 100644 index 0000000..a09444c --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/HasParametersExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7cd5795e243a4bc7918f671743a5159e +timeCreated: 1514447910 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/HasParameter/KeyValue.cs b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/KeyValue.cs new file mode 100644 index 0000000..63e02c5 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/KeyValue.cs @@ -0,0 +1,6 @@ +namespace Adnc.AnimatorHelpers.HasParameters { + public class KeyValue { + public string key; + public V value; + } +} \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/HasParameter/KeyValue.cs.meta b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/KeyValue.cs.meta new file mode 100644 index 0000000..3808127 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/KeyValue.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ae321c3bd7dd4bf3b93f0ef1653dd98f +timeCreated: 1514446492 \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/HasParameter/Parameters.cs b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/Parameters.cs new file mode 100644 index 0000000..d056d82 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/Parameters.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; + +namespace Adnc.AnimatorHelpers.HasParameters { + public class Parameters { + public readonly List> list = new List>(); + public readonly Dictionary> dic = new Dictionary>(); + + public KeyValue Add (string key, V value) { + if (dic.ContainsKey(key)) { + return dic[key]; + } + + var kv = new KeyValue { + key = key, + value = value + }; + + list.Add(kv); + dic.Add(key, kv); + + return kv; + } + } +} \ No newline at end of file diff --git a/Assets/AdncAnimatorHelpers/Scripts/HasParameter/Parameters.cs.meta b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/Parameters.cs.meta new file mode 100644 index 0000000..1bf01f7 --- /dev/null +++ b/Assets/AdncAnimatorHelpers/Scripts/HasParameter/Parameters.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a812e6dd98a744eb975511a1d2b8f89c +timeCreated: 1514446297 \ No newline at end of file diff --git a/Assets/Dist/AdncAnimatorHelpers.unitypackage b/Assets/Dist/AdncAnimatorHelpers.unitypackage index ecf4bc8..eac6832 100644 Binary files a/Assets/Dist/AdncAnimatorHelpers.unitypackage and b/Assets/Dist/AdncAnimatorHelpers.unitypackage differ diff --git a/Assets/Plugins/AdncUtility/Scripts/AnimatorPlayback.cs b/Assets/Plugins/AdncUtility/Scripts/AnimatorPlayback.cs index 81ab5bf..e7eff6c 100644 --- a/Assets/Plugins/AdncUtility/Scripts/AnimatorPlayback.cs +++ b/Assets/Plugins/AdncUtility/Scripts/AnimatorPlayback.cs @@ -1,6 +1,7 @@ using UnityEngine; namespace Adnc.Utility { + [System.Obsolete("Please use Adnc.AnimatorHelpers.AnimatorPlayback instead")] [System.Serializable] public class AnimatorPlayback { // When playing an animation twice it will always reset diff --git a/Assets/Plugins/AdncUtility/Scripts/Singleton.meta b/Assets/Plugins/AdncUtility/Scripts/Singleton.meta new file mode 100644 index 0000000..9a81e93 --- /dev/null +++ b/Assets/Plugins/AdncUtility/Scripts/Singleton.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 883e7ef0ec145485685c04006eb3138e +folderAsset: yes +timeCreated: 1514525384 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/AdncUtility/Scripts/Singleton/SingletonBase.cs b/Assets/Plugins/AdncUtility/Scripts/Singleton/SingletonBase.cs new file mode 100644 index 0000000..2caf3b4 --- /dev/null +++ b/Assets/Plugins/AdncUtility/Scripts/Singleton/SingletonBase.cs @@ -0,0 +1,65 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Adnc.Utility.Singletons { + // @SRC http://wiki.unity3d.com/index.php/Singleton + public abstract class SingletonBase : MonoBehaviour where T : MonoBehaviour { + private static T _instance; + + private static string SingletonName { + get { return typeof(T).Name; } + } + + public static T Instance { + get { + if (_instance != null) { + return _instance; + } + + var instances = FindObjectsOfType(typeof(T)); + if (instances.Length >= 1) { + if (Application.isPlaying) { + Debug.AssertFormat( + instances.Length == 1, + "{1} {0} singletons detected. There should only ever be one present", + SingletonName, + instances.Length); + } + + _instance = (T)instances[0]; + return _instance; + } + + var singleton = new GameObject(SingletonName); + _instance = singleton.AddComponent(); + + // Only add DontDestroyOnLoad if the user fails to manually implement the component in a scene + // Thereby giving the user more control over the singleton lifecycle + if (Application.isPlaying) { + DontDestroyOnLoad(singleton); + } + + return _instance; + } + } + + protected virtual void OnDestroy () { + if (_instance == this) { + _instance = null; + } + } + + /// + /// Test friendly method to prevent persisting singletons with editor tests + /// + public static void ClearSingleton () { + if (Application.isPlaying || _instance == null) { + return; + } + + DestroyImmediate(_instance.gameObject); + _instance = null; + } + } +} diff --git a/Assets/Plugins/AdncUtility/Scripts/Singleton/SingletonBase.cs.meta b/Assets/Plugins/AdncUtility/Scripts/Singleton/SingletonBase.cs.meta new file mode 100644 index 0000000..42f314e --- /dev/null +++ b/Assets/Plugins/AdncUtility/Scripts/Singleton/SingletonBase.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: c20580b8253554c1ea4de13d6045a46b +timeCreated: 1514525393 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/AdncUtility/Scripts/Singleton/SingletonStub.cs b/Assets/Plugins/AdncUtility/Scripts/Singleton/SingletonStub.cs new file mode 100644 index 0000000..da7ffa1 --- /dev/null +++ b/Assets/Plugins/AdncUtility/Scripts/Singleton/SingletonStub.cs @@ -0,0 +1,9 @@ +namespace Adnc.Utility.Singletons { + /// + /// Testing only class + /// + public class SingletonStub : SingletonBase { + [InfoBox("For testing purposes only. Do not implement", InfoBoxType.Error)] + public string globalString = "test"; + } +} \ No newline at end of file diff --git a/Assets/Plugins/AdncUtility/Scripts/Singleton/SingletonStub.cs.meta b/Assets/Plugins/AdncUtility/Scripts/Singleton/SingletonStub.cs.meta new file mode 100644 index 0000000..f4aeb85 --- /dev/null +++ b/Assets/Plugins/AdncUtility/Scripts/Singleton/SingletonStub.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d8c771498cfd49bf9faca05cc80f4348 +timeCreated: 1514525518 \ No newline at end of file diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt index 7a6fffb..b798bd6 100644 --- a/ProjectSettings/ProjectVersion.txt +++ b/ProjectSettings/ProjectVersion.txt @@ -1 +1 @@ -m_EditorVersion: 2017.2.0f3 +m_EditorVersion: 2017.3.0p1 diff --git a/README.md b/README.md index f9c30c8..1ffd67a 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Grab the export package and import it into your Unity project ### AnimatorPlayback Objects -How to use an AnimatorPlayback to play animations with variables. +How to use the `AnimatorPlayback` object to play animations with variables. ![Preview of Playback Helper](/playback-helper-example.png) @@ -52,6 +52,21 @@ public class AnimatorPlaybackExample : MonoBehaviour { Note that the AnimatorPlayback objects are fully unit and runtime tested due to their level of complexity. +### Features + + * AnimatorPlayback objects to easily detect animation completion conditions + * Pre-built library on AnimatorBehavior(s) for complex animation playback + * Animator extensions that add missing functionality to Unity's Animator component + * Animator unit testing helper (for editor only tests) + * Unit tested + +#### Requesting Features + +Please file a GitHub [issue ticket](https://github.com/ashblue/unity-animator-helpers/issues) if you'd like to +request a feature. + +You can view the current [roadmap here](https://github.com/ashblue/unity-animator-helpers/projects/1). + ## Animator Behaviors There are several animator helper scripts to assist you with Animator Behavior(s). @@ -72,3 +87,81 @@ Here is a brief list of helpers. New ones will be added as the repo is updated o * SetVarRandomInt * RandomSpeed * RandomStartTime + +See documentation on methods (in code) for complete details. + +## Animator Extensions + +Unity Animator Helpers extends the pre-existing functionality of Unity3D's built in `Animator` component with static +extensions. This doesn't hurt or break any existing functionality. For example you could do the following to check if +you have a particular bool parameter. + +```c# +public class AnimatorExtensionExample : MonoBehaviour { + private Animator anim; + + public string hasAnimatorBool = "myBool"; + + private void Start () { + anim = GetComponent(); + + Debug.LogFormat("Animator has bool {0}: {1}", hasAnimatorBool, anim.HasBool(hasAnimatorBool)); + } +} +``` + +### Available Animator extensions + +* HasParameter(name) +* HasBool(name) +* HasFloat(name) +* HasInt(name) +* HasTrigger(name) + +See documentation on methods (in code) for complete details. + +### Extension Caching +Animator extensions perform some caching to make lookups instant. This only happens on the first extension +call per unique `AnimatorController`. While this generally shouldn't cause performance problems and is almost instant. +You may need to call `AnimatorHelperRuntime.Instance.Cache(Animator)` on `Start` or `Awake` if your `Animator(s)` +have over 300 parameters. Please note that your `AnimatorController` object (what you pass into the Animator via +inspector) must be uniquely named in order for the caching to work correctly. + +## Animator Unit Test Helper + +This library provides an `AnimatorStub` (editor only) class that makes testing animations via pure code super simple. +All you need to do is the following. + +```c# +using Adnc.AnimatorHelpers.Editors.Testing.Utilities; +using NUnit.Framework; +using UnityEngine; + +public class TestAnimatorStub { + private AnimatorStub _stub; + + [SetUp] + public void Setup () { + _stub = new AnimatorStub(); + } + + [TearDown] + public void Teardown () { + // The stub is attached to a GameObject, so it must be destroyed manually + Object.DestroyImmediate(_stub.Animator.gameObject); + } + + [Test] + public void MyTest () { + // Setup your AnimatorController as desired + stub.AnimatorCtrl.AddParameter("myBool", AnimatorControllerParameterType.Bool); + + // Inject a runtime version of the AnimatorController with all of your settings + stub.InjectCtrl(); + + // Test as normal + // stub.Animator.Update(10); // If you need to simulate time + Assert.IsTrue(stub.Animator.HasBool("myBool)); + } +} +```