public IEnumerator GameObjectIsEnabledAfterActivation() { // Given an active training scene object and a training with enable game object behavior, TrainingSceneObject toEnable = TestingUtils.CreateSceneObject("toEnable"); toEnable.GameObject.SetActive(false); EndlessConditionMock trigger = new EndlessConditionMock(); ICourse course = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicCourseStepBuilder("Step") .Enable(toEnable) .AddCondition(trigger))) .Build(); course.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode); CourseRunner.Initialize(course); CourseRunner.Run(); // When the behavior is activated CourseRunner.Initialize(course); CourseRunner.Run(); yield return(new WaitUntil(() => course.Data.FirstChapter.Data.Steps[0].LifeCycle.Stage == Stage.Active)); // Then the training scene object is enabled. Assert.True(toEnable.GameObject.activeSelf); // Cleanup TestingUtils.DestroySceneObject(toEnable); yield break; }
public IEnumerator NotExistingPrefab() { // Given the position provider training object, an invalid path to a not existing prefab, some valid default settings, and the activation mode = Activation, GameObject target = new GameObject(positionProviderName); TrainingSceneObject positionProvider = target.AddComponent <TrainingSceneObject>(); positionProvider.ChangeUniqueName(positionProviderName); ConfettiBehavior behavior = new ConfettiBehavior(false, positionProvider, pathToMockPrefab, areaRadius, duration, BehaviorExecutionStages.Activation); behavior.Configure(defaultMode); // When I activate that behavior and wait for one update cycle, behavior.LifeCycle.Activate(); while (behavior.LifeCycle.Stage != Stage.Activating) { yield return(null); behavior.Update(); } yield return(null); behavior.Update(); string prefabName = "Behavior" + pathToMockPrefab.Substring(pathToMockPrefab.LastIndexOf("/", StringComparison.Ordinal) + 1); GameObject machine = GameObject.Find(prefabName); // Then the activation state of the behavior is "active" and there is no confetti machine in the scene. Assert.AreEqual(Stage.Active, behavior.LifeCycle.Stage); Assert.AreEqual(null, machine); }
public IEnumerator CreateByName() { // Given the path to the confetti machine prefab, the position provider name, the duration, the bool isAboveTrainee, the area radius, and the activation mode, GameObject target = new GameObject(positionProviderName); TrainingSceneObject positionProvider = target.AddComponent <TrainingSceneObject>(); positionProvider.ChangeUniqueName(positionProviderName); BehaviorExecutionStages executionStages = BehaviorExecutionStages.ActivationAndDeactivation; // When we create ConfettiBehavior and pass training objects by their unique name, ConfettiBehavior confettiBehavior = new ConfettiBehavior(false, positionProviderName, pathToMockPrefab, areaRadius, duration, executionStages); confettiBehavior.Configure(defaultMode); // Then all properties of the MoveObjectBehavior are properly assigned. Assert.AreEqual(false, confettiBehavior.Data.IsAboveTrainee); Assert.AreEqual(positionProvider, confettiBehavior.Data.PositionProvider.Value); Assert.AreEqual(pathToMockPrefab, confettiBehavior.Data.ConfettiMachinePrefabPath); Assert.AreEqual(areaRadius, confettiBehavior.Data.AreaRadius); Assert.AreEqual(duration, confettiBehavior.Data.Duration); Assert.AreEqual(executionStages, confettiBehavior.Data.ExecutionStages); yield break; }
public IEnumerator FastForwardInactiveBehaviorAndActivateIt() { // Given MoveObjectBehavior that takes two training scene objects with different positions and rotations, and positive transition duration, float duration = 0.05f; GameObject movedGo = new GameObject(movedName); TrainingSceneObject moved = movedGo.AddComponent <TrainingSceneObject>(); moved.ChangeUniqueName(movedName); GameObject positionProviderGo = new GameObject(positionProviderName); positionProviderGo.transform.position = new Vector3(1, 2, 50); positionProviderGo.transform.rotation = Quaternion.Euler(57, 195, 188); TrainingSceneObject target = positionProviderGo.AddComponent <TrainingSceneObject>(); target.ChangeUniqueName(positionProviderName); MoveObjectBehavior behavior = new MoveObjectBehavior(moved, target, duration); // When we mark it to fast-forward and activate it, behavior.LifeCycle.MarkToFastForward(); behavior.LifeCycle.Activate(); // Then it autocompletes immediately, and moved object position and rotation matches the ones of positionProvider. Assert.AreEqual(Stage.Active, behavior.LifeCycle.Stage); Assert.IsTrue((movedGo.transform.position - positionProviderGo.transform.position).sqrMagnitude < 0.001f); Assert.IsTrue(Quaternion.Dot(movedGo.transform.rotation, positionProviderGo.transform.rotation) > 0.999f); // Cleanup created game objects. Object.DestroyImmediate(movedGo); Object.DestroyImmediate(positionProviderGo); yield return(null); }
public IEnumerator FastForwardActivatingBehavior() { // Given an UnlockObjectBehavior and a locked game object, GameObject gameObject = new GameObject("Test"); TrainingSceneObject targetObject = gameObject.AddComponent <TrainingSceneObject>(); UnlockObjectBehavior behavior = new UnlockObjectBehavior(targetObject); behavior.Configure(RuntimeConfigurator.Configuration.GetCurrentMode()); targetObject.SetLocked(true); bool isLockedInitially = targetObject.IsLocked; behavior.LifeCycle.Activate(); // When we mark the behavior to fast-forward, behavior.LifeCycle.MarkToFastForward(); // Then it should work without any differences because the behavior is done immediately anyways. bool isLockedDuringStep = targetObject.IsLocked; behavior.LifeCycle.Deactivate(); bool isLockedInEnd = targetObject.IsLocked; Assert.IsTrue(isLockedInitially, "Object should be locked initially"); Assert.IsFalse(isLockedDuringStep, "Object should be unlocked during step"); Assert.IsTrue(isLockedInEnd, "Object should be locked in the end"); // Cleanup created game objects. Object.DestroyImmediate(gameObject); yield return(null); }
public IEnumerator BuildingSnapZonePutTest() { // Given a snap zone and snappable property and a builder for a training with a PutIntoSnapZone default step GameObject snapZoneGo = new GameObject("SnapZone"); TrainingSceneObject snapZone = snapZoneGo.AddComponent <TrainingSceneObject>(); snapZoneGo.AddComponent <DummySnapZoneProperty>(); snapZone.ChangeUniqueName("SnapZone"); GameObject putGo = new GameObject("Puttable"); TrainingSceneObject objectToPut = putGo.AddComponent <TrainingSceneObject>(); putGo.AddComponent <DummySnappableProperty>(); objectToPut.ChangeUniqueName("ToPut"); LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(InteractionDefaultSteps.PutIntoSnapZone("TestSnapZonePutStep", "SnapZone", "ToPut"))); // When you build a training with it IStep step = builder.Build().Data.FirstChapter.Data.FirstStep; // Then it has a step with a SnappedCondition Assert.True(step != null); Assert.True(step.Data.Name == "TestSnapZonePutStep"); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.Count == 1); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() is SnappedCondition); Assert.True(ReferenceEquals((step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() as SnappedCondition).Data.Target.Value.SceneObject, objectToPut)); // Cleanup Object.DestroyImmediate(snapZoneGo); Object.DestroyImmediate(putGo); return(null); }
public IEnumerator SamePosition() { // Given MoveObjectBehavior that takes two training scene objects with the same position and rotation, and positive transition duration, float duration = 0.05f; GameObject movedGo = new GameObject(movedName); TrainingSceneObject moved = movedGo.AddComponent <TrainingSceneObject>(); moved.ChangeUniqueName(movedName); GameObject targetGo = new GameObject(positionProviderName); TrainingSceneObject target = targetGo.AddComponent <TrainingSceneObject>(); target.ChangeUniqueName(positionProviderName); MoveObjectBehavior behavior = new MoveObjectBehavior(moved, target, duration); behavior.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode); // When we activate the behavior, behavior.LifeCycle.Activate(); yield return(null); behavior.Update(); // Then it does not finish its activation immediately. Assert.IsTrue(behavior.LifeCycle.Stage == Stage.Activating); // Cleanup created game objects. Object.DestroyImmediate(movedGo); Object.DestroyImmediate(targetGo); yield return(null); }
public IEnumerator DisableGameObjectBehavior() { // Given DisableGameObjectBehavior, TrainingSceneObject trainingSceneObject = TestingUtils.CreateSceneObject("TestObject"); ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .DisableAutomaticAudioHandling() .Disable("TestObject"))) .Build(); // When we serialize and deserialize a training with it string serialized = JsonTrainingSerializer.Serialize(training1); ICourse training2 = JsonTrainingSerializer.Deserialize(serialized); DisableGameObjectBehavior behavior1 = training1.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as DisableGameObjectBehavior; DisableGameObjectBehavior behavior2 = training2.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as DisableGameObjectBehavior; // Then it's target training scene object is still the same. Assert.IsNotNull(behavior1); Assert.IsNotNull(behavior2); Assert.AreEqual(behavior1.Data.Target.Value, behavior2.Data.Target.Value); TestingUtils.DestroySceneObject(trainingSceneObject); return(null); }
public IEnumerator LockObjectBehavior() { // Given a training with LockObjectBehavior TrainingSceneObject trainingSceneObject = TestingUtils.CreateSceneObject("TestObject"); ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .DisableAutomaticAudioHandling() .AddBehavior(new LockObjectBehavior(trainingSceneObject)))) .Build(); // When we serialize and deserialize it ICourse training2 = JsonTrainingSerializer.Deserialize(JsonTrainingSerializer.Serialize(training1)); // Then that's behavior target is still the same. LockObjectBehavior behavior1 = training1.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as LockObjectBehavior; LockObjectBehavior behavior2 = training2.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as LockObjectBehavior; Assert.IsNotNull(behavior1); Assert.IsNotNull(behavior2); Assert.AreEqual(behavior1.Data.Target.Value, behavior2.Data.Target.Value); // Cleanup TestingUtils.DestroySceneObject(trainingSceneObject); return(null); }
public IEnumerator HighlightTest() { // Given we have a training scene object and a builder for a training with a step with highlight that object GameObject go = new GameObject("Highlightable"); TrainingSceneObject highlightable = go.AddComponent <TrainingSceneObject>(); highlightable.ChangeUniqueName("Highlightable"); LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(new BasicStepBuilder("TestHighlightStep") .Highlight("Highlightable"))); // When we build a training from it IStep step = builder.Build().Data.FirstChapter.Data.FirstStep; // Then we have a step with VRTKObjectHighlight behavior. Assert.True(step != null); Assert.True(step.Data.Name == "TestHighlightStep"); Assert.True(step.Data.Behaviors.Data.Behaviors.First() is VRTKObjectHighlight); Assert.True(ReferenceEquals((step.Data.Behaviors.Data.Behaviors.First() as VRTKObjectHighlight).Data.Target.Value, highlightable)); // Cleanup Object.DestroyImmediate(go); return(null); }
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 BuildingUseTest() { // Given a usable property and a builder for a training with Use default step GameObject usableGo = new GameObject("Usable"); TrainingSceneObject usable = usableGo.AddComponent <TrainingSceneObject>(); usableGo.AddComponent <UsableProperty>(); usable.ChangeUniqueName("Usable"); LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(DefaultSteps.Use("TestUseStep", "Usable"))); // When you build a training with it IStep step = builder.Build().Data.FirstChapter.Data.FirstStep; // Then it has a step with an UsedCondition Assert.True(step != null); Assert.True(step.Data.Name == "TestUseStep"); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.Count == 1); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() is UsedCondition); Assert.True(ReferenceEquals((step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() as UsedCondition).Data.UsableProperty.Value.SceneObject, usable)); // Cleanup Object.DestroyImmediate(usableGo); return(null); }
public IEnumerator BuildingGrabTest() { // Given a `GrabbableProperty` and a builder for a training with a Grab default step GameObject go = new GameObject("TestGrabbable"); TrainingSceneObject to = go.AddComponent <TrainingSceneObject>(); go.AddComponent <GrabbableProperty>(); to.ChangeUniqueName("Grabbable"); LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(DefaultSteps.Grab("TestGrabStep", "Grabbable"))); // When we build a training from it IStep step = builder.Build().Data.FirstChapter.Data.FirstStep; //Then it should has a stap with a GrabbedCondition which refers to the `GrabbableProperty`. Assert.True(step != null); Assert.True(step.Data.Name == "TestGrabStep"); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.Count == 1); GrabbedCondition condition = step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() as GrabbedCondition; Assert.True(ReferenceEquals(to, condition.Data.GrabbableProperty.Value.SceneObject)); // Cleanup Object.DestroyImmediate(go); yield return(null); }
public override Rect Draw(Rect rect, object currentValue, Action <object> changeValueCallback, GUIContent label) { lockableCollection = (LockableObjectsCollection)currentValue; Rect currentPosition = new Rect(rect.x, rect.y, rect.width, EditorDrawingHelper.HeaderLineHeight); currentPosition.y += 10; GUI.Label(currentPosition, "Automatically unlocked objects in this step"); for (int i = 0; i < lockableCollection.SceneObjects.Count; i++) { ISceneObject objectInScene = lockableCollection.SceneObjects[i]; currentPosition = DrawSceneObject(currentPosition, objectInScene); currentPosition.y += EditorDrawingHelper.SingleLineHeight; } currentPosition.y += EditorDrawingHelper.SingleLineHeight; EditorGUI.LabelField(currentPosition, "To add new TrainingSceneObject, drag it in here:"); currentPosition.y += EditorDrawingHelper.SingleLineHeight + EditorDrawingHelper.VerticalSpacing; TrainingSceneObject newSceneObject = (TrainingSceneObject)EditorGUI.ObjectField(currentPosition, null, typeof(TrainingSceneObject), true); if (newSceneObject != null) { lockableCollection.AddSceneObject(newSceneObject); } // EditorDrawingHelper.HeaderLineHeight - 24f is just the magic number to make it properly fit... return(new Rect(rect.x, rect.y, rect.width, currentPosition.y - EditorDrawingHelper.HeaderLineHeight - 24f)); }
public IEnumerator UnregisterAllowsToPlaceTest() { // Create reference GameObject obj1 = new GameObject("MyObject"); TrainingSceneObject reference1 = obj1.AddComponent <TrainingSceneObject>(); reference1.ChangeUniqueName("Test"); RuntimeConfigurator.Configuration.SceneObjectRegistry.Unregister(reference1); // Create reference GameObject obj2 = new GameObject("MyObject"); TrainingSceneObject reference2 = obj2.AddComponent <TrainingSceneObject>(); reference2.ChangeUniqueName("Test"); // Assert that new added reference can be found Assert.IsTrue(RuntimeConfigurator.Configuration.SceneObjectRegistry.ContainsGuid(reference2.Guid)); Assert.IsTrue(RuntimeConfigurator.Configuration.SceneObjectRegistry.ContainsName(reference2.UniqueName)); Assert.AreEqual(reference2, RuntimeConfigurator.Configuration.SceneObjectRegistry.GetByName(reference2.UniqueName)); // Clean up Object.DestroyImmediate(obj1); Object.DestroyImmediate(obj2); yield return(null); }
public IEnumerator ObjectInRangeCondition() { // Given a training with ObjectInRangeCondition, TrainingSceneObject testObjectToo = TestingUtils.CreateSceneObject("TestObjectToo"); TransformInRangeDetectorProperty detector = testObjectToo.gameObject.AddComponent <TransformInRangeDetectorProperty>(); TrainingSceneObject testObject = TestingUtils.CreateSceneObject("TestObject"); ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddCondition(new ObjectInRangeCondition(testObject, detector, 1.5f)))) .Build(); // When we serialize and deserialize it ICourse training2 = Serializer.CourseFromByteArray(Serializer.CourseToByteArray(training1)); // Then that condition's target, detector and range should stay unchanged. ObjectInRangeCondition condition1 = training1.Data.FirstChapter.Data.FirstStep.Data.Transitions.Data.Transitions.First().Data.Conditions.First() as ObjectInRangeCondition; ObjectInRangeCondition condition2 = training2.Data.FirstChapter.Data.FirstStep.Data.Transitions.Data.Transitions.First().Data.Conditions.First() as ObjectInRangeCondition; Assert.IsNotNull(condition1); Assert.IsNotNull(condition2); Assert.AreEqual(condition1.Data.Range, condition2.Data.Range); Assert.AreEqual(condition1.Data.Target.Value, condition2.Data.Target.Value); Assert.AreEqual(condition1.Data.DistanceDetector.Value, condition2.Data.DistanceDetector.Value); // Cleanup TestingUtils.DestroySceneObject(testObjectToo); TestingUtils.DestroySceneObject(testObject); return(null); }
public IEnumerator ChangeNameBeforeAwakeTest() { // Create reference GameObject obj = new GameObject("MyObject"); obj.SetActive(false); TrainingSceneObject reference = obj.AddComponent <TrainingSceneObject>(); reference.ChangeUniqueName("Test"); reference.ChangeUniqueName("Test2"); obj.SetActive(true); // Assert that reference is now registered at the registry. Assert.IsTrue(RuntimeConfigurator.Configuration.SceneObjectRegistry.ContainsGuid(reference.Guid)); Assert.AreEqual(reference, RuntimeConfigurator.Configuration.SceneObjectRegistry.GetByGuid(reference.Guid)); Assert.IsFalse(RuntimeConfigurator.Configuration.SceneObjectRegistry.ContainsName("Test")); Assert.IsTrue(RuntimeConfigurator.Configuration.SceneObjectRegistry.ContainsName("Test2")); Assert.AreEqual(reference, RuntimeConfigurator.Configuration.SceneObjectRegistry.GetByName("Test2")); // Clean up Object.DestroyImmediate(obj); yield return(null); }
public IEnumerator EnableGameObjectBehavior() { // Given EnableGameObjectBehavior, TrainingSceneObject trainingSceneObject = TestingUtils.CreateSceneObject("TestObject"); ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicCourseStepBuilder("Step") .Enable("TestObject"))) .Build(); // When we serialize and deserialize a training course with it ICourse training2 = Serializer.CourseFromByteArray(Serializer.CourseToByteArray(training1)); EnableGameObjectBehavior behavior1 = training1.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as EnableGameObjectBehavior; EnableGameObjectBehavior behavior2 = training2.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as EnableGameObjectBehavior; // Then it's target training scene object is still the same. Assert.IsNotNull(behavior1); Assert.IsNotNull(behavior2); Assert.AreEqual(behavior1.Data.Target.Value, behavior2.Data.Target.Value); TestingUtils.DestroySceneObject(trainingSceneObject); return(null); }
public IEnumerator BuildingTouchTest() { // Given you have a touchable property and a builder for a training with Touch default step GameObject touchableGo = new GameObject("Touchable"); TrainingSceneObject touchable = touchableGo.AddComponent <TrainingSceneObject>(); touchableGo.AddComponent <DummyTouchableProperty>(); touchable.ChangeUniqueName("Touchable"); LinearTrainingBuilder builder = new LinearTrainingBuilder("TestTraining") .AddChapter(new LinearChapterBuilder("TestChapter") .AddStep(InteractionDefaultSteps.Touch("TestTouchStep", "Touchable"))); // When you build a training with it IStep step = builder.Build().Data.FirstChapter.Data.FirstStep; // Then it has a step with a TouchCOndition Assert.True(step != null); Assert.True(step.Data.Name == "TestTouchStep"); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.Count == 1); Assert.True(step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() is TouchedCondition); Assert.True(ReferenceEquals((step.Data.Transitions.Data.Transitions.First().Data.Conditions.First() as TouchedCondition).Data.TouchableProperty.Value.SceneObject, touchable)); // Cleanup Object.DestroyImmediate(touchableGo); return(null); }
public IEnumerator UnlockObjectBehavior() { // Given a training with UnlockObjectBehavior TrainingSceneObject trainingSceneObject = TestingUtils.CreateSceneObject("TestObject"); ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddBehavior(new UnlockObjectBehavior(trainingSceneObject)))) .Build(); // When we serialize and deserialize it ICourse training2 = Serializer.CourseFromByteArray(Serializer.CourseToByteArray(training1)); UnlockObjectBehavior behavior1 = training1.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as UnlockObjectBehavior; UnlockObjectBehavior behavior2 = training2.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as UnlockObjectBehavior; // Then that behavior's target should not change. Assert.IsNotNull(behavior1); Assert.IsNotNull(behavior2); Assert.AreEqual(behavior1.Data.Target.Value, behavior2.Data.Target.Value); // Cleanup TestingUtils.DestroySceneObject(trainingSceneObject); return(null); }
public IEnumerator FastForwardInactiveBehavior() { // Given MoveObjectBehavior that takes two training scene objects with different positions and rotations, and positive transition duration, float duration = 0.05f; GameObject movedGo = new GameObject(movedName); TrainingSceneObject moved = movedGo.AddComponent <TrainingSceneObject>(); moved.ChangeUniqueName(movedName); GameObject positionProviderGo = new GameObject(positionProviderName); positionProviderGo.transform.position = new Vector3(1, 2, 50); positionProviderGo.transform.rotation = Quaternion.Euler(57, 195, 188); TrainingSceneObject target = positionProviderGo.AddComponent <TrainingSceneObject>(); target.ChangeUniqueName(positionProviderName); MoveObjectBehavior behavior = new MoveObjectBehavior(moved, target, duration); // When we mark it to fast-forward, behavior.LifeCycle.MarkToFastForward(); // Then it doesn't autocomplete because it wasn't activated yet. Assert.AreEqual(Stage.Inactive, behavior.LifeCycle.Stage); // Cleanup created game objects. Object.DestroyImmediate(movedGo); Object.DestroyImmediate(positionProviderGo); yield return(null); }
public IEnumerator MoveObjectBehavior() { // Given training with MoveObjectBehavior TrainingSceneObject moved = TestingUtils.CreateSceneObject("moved"); TrainingSceneObject positionProvider = TestingUtils.CreateSceneObject("positionprovider"); ICourse training1 = new LinearTrainingBuilder("Training") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicStepBuilder("Step") .AddBehavior(new MoveObjectBehavior(moved, positionProvider, 24.7f)))) .Build(); // When that training is serialized and deserialzied ICourse training2 = Serializer.CourseFromByteArray(Serializer.CourseToByteArray(training1)); // Then we should have two identical move object behaviors MoveObjectBehavior behavior1 = training1.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as MoveObjectBehavior; MoveObjectBehavior behavior2 = training2.Data.FirstChapter.Data.FirstStep.Data.Behaviors.Data.Behaviors.First() as MoveObjectBehavior; Assert.IsNotNull(behavior1); Assert.IsNotNull(behavior2); Assert.IsFalse(ReferenceEquals(behavior1, behavior2)); Assert.AreEqual(behavior1.Data.Target.Value, behavior2.Data.Target.Value); Assert.AreEqual(behavior1.Data.PositionProvider.Value, behavior2.Data.PositionProvider.Value); Assert.AreEqual(behavior1.Data.Duration, behavior2.Data.Duration); // Cleanup created game objects. TestingUtils.DestroySceneObject(moved); TestingUtils.DestroySceneObject(positionProvider); return(null); }
public IEnumerator CreateByName() { // Given two training scene objects and a duration, GameObject movedGo = new GameObject(movedName); TrainingSceneObject moved = movedGo.AddComponent <TrainingSceneObject>(); moved.ChangeUniqueName(movedName); GameObject targetGo = new GameObject(positionProviderName); TrainingSceneObject positionProvider = targetGo.AddComponent <TrainingSceneObject>(); positionProvider.ChangeUniqueName(positionProviderName); float duration = 0.25f; // When we create MoveObjectBehavior and pass training scene objects by their unique name, MoveObjectBehavior moveObjectBehavior = new MoveObjectBehavior(movedName, positionProviderName, duration); // Then all properties of the MoveObjectBehavior are properly assigned Assert.AreEqual(moved, moveObjectBehavior.Data.Target.Value); Assert.AreEqual(positionProvider, moveObjectBehavior.Data.PositionProvider.Value); Assert.AreEqual(moveObjectBehavior.Data.Duration, duration); // Cleanup created game objects. Object.DestroyImmediate(movedGo); Object.DestroyImmediate(targetGo); yield return(null); }
/// <summary> /// Adds a new TrainingSceneObject to the list. /// </summary> public void AddTrainingSceneObject(TrainingSceneObject target) { if (acceptedTrainingSceneObjects.Contains(target) == false) { acceptedTrainingSceneObjects = acceptedTrainingSceneObjects.Append(target).ToArray(); } }
public IEnumerator StillActivatingWhenPositiveDurationNotFinished() { // Given the position provider training object, some valid default settings, and the activation mode = Activation, GameObject target = new GameObject(positionProviderName); TrainingSceneObject positionProvider = target.AddComponent <TrainingSceneObject>(); positionProvider.ChangeUniqueName(positionProviderName); ConfettiBehavior behavior = new ConfettiBehavior(false, positionProvider, pathToPrefab, areaRadius, 2f, BehaviorExecutionStages.Activation); behavior.Configure(defaultMode); // When I activate that behavior, behavior.LifeCycle.Activate(); while (behavior.LifeCycle.Stage != Stage.Activating) { yield return(null); behavior.Update(); } // And wait two update cycles, yield return(null); behavior.Update(); yield return(null); behavior.Update(); // Then the activation state of the behavior is "activating". Assert.AreEqual(Stage.Activating, behavior.LifeCycle.Stage); }
/// <summary> /// Removes an existing training scene object from the list. /// </summary> public void RemoveTrainingSceneObject(TrainingSceneObject target) { if (acceptedTrainingSceneObjects.Contains(target)) { acceptedTrainingSceneObjects = acceptedTrainingSceneObjects.Where((obj => obj != target)).ToArray(); } }
public IEnumerator FastForwardActivatingBehavior() { // Given an active ConfettiBehavior with activation mode "Activation", GameObject target = new GameObject(positionProviderName); TrainingSceneObject positionProvider = target.AddComponent <TrainingSceneObject>(); positionProvider.ChangeUniqueName(positionProviderName); ConfettiBehavior behavior = new ConfettiBehavior(false, positionProvider, pathToPrefab, areaRadius, duration, BehaviorExecutionStages.Activation); behavior.Configure(defaultMode); behavior.LifeCycle.Activate(); while (behavior.LifeCycle.Stage != Stage.Activating) { yield return(null); behavior.Update(); } // When we mark it to fast-forward, behavior.LifeCycle.MarkToFastForward(); // Then it autocompletes immediately. Assert.AreEqual(Stage.Active, behavior.LifeCycle.Stage); }
public IEnumerator GameObjectStaysDisabled() { // Given an active training scene object and a training course with disable game object behavior, TrainingSceneObject toDisable = TestingUtils.CreateSceneObject("ToDisable"); EndlessConditionMock trigger = new EndlessConditionMock(); ICourse course = new LinearTrainingBuilder("Course") .AddChapter(new LinearChapterBuilder("Chapter") .AddStep(new BasicCourseStepBuilder("Step") .Disable(toDisable)) .AddStep(new BasicCourseStepBuilder("Step") .AddCondition(trigger))) .Build(); course.Configure(RuntimeConfigurator.Configuration.Modes.CurrentMode); // When the behavior is activated and after the step is completed CourseRunner.Initialize(course); CourseRunner.Run(); yield return(new WaitUntil(() => course.Data.FirstChapter.Data.Steps[1].LifeCycle.Stage == Stage.Active)); trigger.Autocomplete(); yield return(new WaitUntil(() => course.Data.FirstChapter.Data.Steps[1].LifeCycle.Stage == Stage.Inactive)); // Then the training scene object stays disabled. Assert.False(toDisable.GameObject.activeSelf); // Cleanup. TestingUtils.DestroySceneObject(toDisable); yield break; }
public IEnumerator ActivationWithSpawnedMachine() { // Given a positive duration, a position provider, some valid default settings, and the activation mode = Activation, GameObject target = new GameObject(positionProviderName); TrainingSceneObject positionProvider = target.AddComponent <TrainingSceneObject>(); positionProvider.ChangeUniqueName(positionProviderName); ConfettiBehavior behavior = new ConfettiBehavior(false, positionProvider, pathToPrefab, areaRadius, duration, BehaviorExecutionStages.Activation); behavior.Configure(defaultMode); // When I activate that behavior and wait until it's activating, behavior.LifeCycle.Activate(); while (behavior.LifeCycle.Stage != Stage.Activating) { yield return(null); behavior.Update(); } string prefabName = "Behavior" + pathToPrefab.Substring(pathToPrefab.LastIndexOf("/", StringComparison.Ordinal) + 1); GameObject machine = GameObject.Find(prefabName); // Then the activation state of the behavior is "activating" and the ConfettiMachine exists in the scene. Assert.AreEqual(Stage.Activating, behavior.LifeCycle.Stage); Assert.IsTrue(machine != null); }
public IEnumerator RunsInstantlyWhenDelayTimeIsZero() { // Given a complete scaling behavior with duration time == 0, const float duration = 0f; GameObject target = new GameObject(targetName); TrainingSceneObject positionProvider = target.AddComponent <TrainingSceneObject>(); positionProvider.ChangeUniqueName(targetName); Vector3 endScale = target.transform.localScale + newScale; IBehavior behavior = new ScalingBehavior(new SceneObjectReference(targetName), endScale, duration); behavior.Configure(defaultMode); // When we activate it and wait one update cycle, behavior.LifeCycle.Activate(); while (behavior.LifeCycle.Stage != Stage.Activating) { yield return(null); behavior.Update(); } yield return(null); behavior.Update(); // Then the behavior is activated immediately and the object is scaled correctly. Assert.AreEqual(Stage.Active, behavior.LifeCycle.Stage); Assert.IsTrue(target.transform.localScale == endScale); }