In this example, we're going to move the player character into an enemy character and detect the collision event that occurs. This approach can be used to validate that collisions are occurring as expected and that the correct event occurs as a result. In this case, that the player character health value changes as verified by the value of the health bar.


The general process is performed as follows:


  1. Register a Collision Monitor on the moving object
  2. Wait for the Collision event
  3. Perform an action/movement that should result in the event
  4. Check that the event occurred


In some cases, steps #2 and #3 above can be reversed. These are thread-safe commands, which means the order depends on how long it should take to perform the movement or action. If the action is particularly long-lived, it may be necessary to start the action, then `WaitForCollisionEvent`.


Below is an example of this in practice. For this example, we used the 3D Game Kit Lite from the Unity Asset Store.



For this demo, the Chomper enemy prefab was added to the _TemplateScene and can be anywhere on the Plane other than where the Ellen character is located. We then added Capsule Collider and Rigidbody components to the Ellen prefab to demonstrate this functionality. Lastly, add a NavMeshSurface to the Plane and bake this using the Navigation options. You may see some errors during replay such as, ""SetDestination" can only be called on an active agent that has been placed on a NavMesh." This occurs during manual replay and is unrelated to the test below.


[Test]
public void CollisionTest()
{
    // Wait for the player character to become active in the scene
    api.WaitForObject("//*[@name='Ellen']");

    try
    {
        // Get the position of the enemy character
        Vector3 chomper = api.GetObjectPosition("/*[@name='Chomper (1)' and @tag='Untagged']");

        // Register a collision event, which returns a string ID.
        // Note: This should be done for the moving/controlled object which has the RigidBody attached
        string id = api.RegisterCollisionMonitor("//*[@name='Ellen']");

        // Move the player character to the enemy character to initiate the collision.
        // Movement in this example is expected to take several seconds.
        api.NavAgentMoveToPoint("//*[@name='Ellen']", new Vector3(chomper.x, chomper.y, chomper.z), false);

        // Wait for a collision event to occur, capturing the ID from the registered monitor above.
        Collision didFire = api.WaitForCollisionEvent(id);

        // Check if the event was detected. This could be where the test performs some action as a result of the event.
        if (didFire != null)
            Console.WriteLine("Got event.");
        else
            Console.WriteLine("Never got event...");

        // Wait for multi-threaded events to synchronize
        api.Wait(5000);

        // Unregister the collision monitor from the player object
        api.UnregisterCollisionMonitor("//*[@name='Ellen']");

        // Check whether the collision resulted in a reduction in player health, as indicated in the health icon coloring
        Assert.AreEqual(api.GetObjectFieldValue<Color>("//*[@name='Heart'][4]/fn:component('UnityEngine.UI.Image')", "color").ToString(), "RGBA(1.000, 1.000, 1.000, 0.000)");

    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}