public IEnumerator CompleteWhenTargetObjectIsInsideRange()
        {
            // Activate in range condition
            ObjectInRangeCondition condition = new ObjectInRangeCondition(TrackedTrainingSceneObject, TargetTrainingSceneObject.GetProperty <TransformInRangeDetectorProperty>(), 5);

            condition.LifeCycle.Activate();

            while (condition.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                condition.Update();
            }

            // Move tracked object to the target position
            TrackedObject.transform.position = TargetPositionObject.transform.position - PositionOffsetNearTarget;

            while (condition.IsCompleted == false)
            {
                yield return(null);

                condition.Update();
            }

            // Assert that condition is now completed
            UnityEngine.Assertions.Assert.IsTrue(condition.IsCompleted, "TargetInRangeCondition should be completed!");
        }
        public IEnumerator DontCompleteWhenWrongObjectEntersRange()
        {
            // In addition to setup phase, also setup an additional object
            GameObject wrongObj = new GameObject("Wrong Object");

            wrongObj.transform.position = PositionFarFromTarget;
            TrainingSceneObject wrongTrainingSceneObject = wrongObj.AddComponent <TrainingSceneObject>();

            // Activate range condition
            ObjectInRangeCondition condition = new ObjectInRangeCondition(TrackedTrainingSceneObject, TargetTrainingSceneObject.GetProperty <TransformInRangeDetectorProperty>(), 5);

            condition.LifeCycle.Activate();

            while (condition.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                condition.Update();
            }

            // Move wrong object to the target position
            wrongTrainingSceneObject.transform.position = TargetPositionObject.transform.position;

            float startTime = Time.time;

            while (Time.time < startTime + 0.1f)
            {
                yield return(null);

                condition.Update();
            }

            // Assert that condition is not completed
            UnityEngine.Assertions.Assert.IsFalse(condition.IsCompleted, "TargetInRangeCondition should not be completed!");
        }
        public IEnumerator DontCompleteWhenTargetObjectLeavesRangeEarly()
        {
            // Set the target duration
            const float targetDuration = 0.1f;

            // Activate range condition
            ObjectInRangeCondition condition = new ObjectInRangeCondition(TrackedTrainingSceneObject, TargetTrainingSceneObject.GetProperty <TransformInRangeDetectorProperty>(), 5, targetDuration);

            condition.LifeCycle.Activate();

            while (condition.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                condition.Update();
            }

            // Move tracked object to the target position
            TrackedObject.transform.position = TargetPositionObject.transform.position;

            float startTime = Time.time;

            while (Time.time < startTime + 0.3f * targetDuration)
            {
                yield return(null);

                condition.Update();
            }

            // Move tracked object away from target position before condition is completed
            TrackedObject.transform.position = PositionFarFromTarget;

            startTime = Time.time;
            while (Time.time < startTime + 0.8f * targetDuration)
            {
                yield return(null);

                condition.Update();
            }

            // Assert that condition is not completed
            UnityEngine.Assertions.Assert.IsFalse(condition.IsCompleted, "TargetInRangeCondition should not be completed!");
        }
        public IEnumerator CompleteWhenTargetObjectIsInsideRangeWithDuration()
        {
            // Set the target duration
            const float targetDuration = 0.1f;

            // Activate in range condition
            ObjectInRangeCondition condition = new ObjectInRangeCondition(TrackedTrainingSceneObject, TargetTrainingSceneObject.GetProperty <TransformInRangeDetectorProperty>(), 5, targetDuration);

            condition.LifeCycle.Activate();

            while (condition.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                condition.Update();
            }

            // Move tracked object to the target position
            TrackedObject.transform.position = TargetPositionObject.transform.position - PositionOffsetNearTarget;

            yield return(null);

            condition.Update();

            float startTime = Time.time;

            while (condition.IsCompleted == false)
            {
                yield return(null);

                condition.Update();
            }

            float duration = Time.time - startTime;

            // Assert that condition has been completed after the specified duration
            Assert.AreEqual(targetDuration, duration, 0.05f);
            UnityEngine.Assertions.Assert.IsTrue(condition.IsCompleted, "TargetInRangeCondition should be completed!");
        }
        public IEnumerator AutoCompleteActive()
        {
            // Given an object in range condition,
            ObjectInRangeCondition condition = new ObjectInRangeCondition(TrackedTrainingSceneObject, TargetTrainingSceneObject.GetProperty <TransformInRangeDetectorProperty>(), 5);

            // When you activate and autocomplete it,
            condition.LifeCycle.Activate();

            while (condition.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                condition.Update();
            }

            condition.Autocomplete();

            // Then the condition is complete and the object is moved
            Assert.AreEqual(Stage.Active, condition.LifeCycle.Stage);
            Assert.IsTrue(condition.IsCompleted);
            Assert.IsTrue(TrackedTrainingSceneObject.GameObject.transform.position == TargetTrainingSceneObject.GameObject.transform.position);
        }
        public IEnumerator FastForwardDoesNotCompleteCondition()
        {
            // Given an object in range condition,
            ObjectInRangeCondition condition = new ObjectInRangeCondition(TrackedTrainingSceneObject, TargetTrainingSceneObject.GetProperty <TransformInRangeDetectorProperty>(), 5);

            // When you activate it,
            condition.LifeCycle.Activate();

            while (condition.LifeCycle.Stage != Stage.Active)
            {
                yield return(null);

                condition.Update();
            }

            // When you fast-forward it
            condition.LifeCycle.MarkToFastForward();

            // Then nothing happens.
            Assert.AreEqual(Stage.Active, condition.LifeCycle.Stage);
            Assert.IsFalse(condition.IsCompleted);
            Assert.IsFalse(TrackedTrainingSceneObject.GameObject.transform.position == TargetTrainingSceneObject.GameObject.transform.position);
        }