Now, let's look at one of the most important features of GameDriver: the Hierarchy Path query language. Hierarchy Path is a robust query language that enables you to identify any object, component, or property in a scene based on one or more characteristics of that object. Characteristics include the path of the object, such as the parent-child relationship, the name and/or tag of the object, or any one of its components or property values. The language is based pretty closely on XPath, which according to Mozilla.org, uses a non-XML syntax to provide a flexible way of addressing or pointing to different parts of an XML document. It can also be used to test address nodes within a document to determine whether or not they match a pattern. The major difference between XPath and Hierarchy Path, or HPath, is that there's no XML representation of the objects in the game engine. Instead, the GameDriver agent processes the HPath query in real-time using objects in memory. A Hierarchy Path can also be used to access game engine's static methods or properties, even if no object implements that method.
Now, let's look at some of the basic notation of the Hierarchy Path. Here we have a typical query for GetObjectFieldValue, which includes the name of the object (which is 'test status') and the component which is a 'UnityEngine.UI.text' with a field of text. This means that we have a command; the GetObjectField command's return type in this case is a string. The Hierarchy Path query itself is comprised of the tag, which in this case is actually a wild card. We don't specify any tag in this query. The object name is 'test status' and then the component itself, which is the 'UnityEngine.UI.text' component, and the property which is '@text'. We're going to query this object for the value of that '@text' field.
Hierarchy Path supports both relative and absolute paths. A relative path can be used to work with objects that have a simple or unique path or property such as any tag, or an object with any tag and an object name of 'test status'. The absolute path provides an exact path that can be used for working with static objects such as this object, which is 'test status', but it has both the parent and child represented as well as the tags specifically for each of those objects. The difference between these two is that the first one, the relative path, will be resilient to changes in the application. If this 'test status' object moves from one parent to another in different releases, the query will still work. The second one will not work if this object is moved from under the canvas object to another. Objects can also be referred to by their components or properties. For example, we have this 'test status' object again with the component of the 'UnityEngine.UI.text' and the field of '@text'. If there are multiple 'test status' objects in the scene, but only one of them contains this UI text component with a text field, only that one will be returned. We can also search by values using any one of those properties, such as this 'contains' function which is looking for any object in the scene which contains a 'TextMeshProUGUI' component with a text field that has a value of 'America'. This is going to be a much more complicated query. So if there are a lot of objects that contain the 'TextMeshProUGUI', then it's going to be specifically looking for the one that has the text field with the value of 'America'.
We also support Boolean operators such as 'And' or 'Or' for finding objects in a more complex scene. For example, we're looking for this object which has the name of 'button', any tag, and any root, and has a component with a UI text field value of 'default string value', which hasn't changed. We can also examine parent or grandparent relationships, or parent-child relationships, and we can look for siblings. The 'tag parent path' in this case is looking for an object which has the name of 'canvas', but is the child of an object which has the 'button tag' associated with it.
And finally, for the path features, we can identify object clones by specifying an instance predicate starting with zero. If there are multiple objects in the scene which have a parent of 'canvas' and the name of 'test status', this will find the third such object within the scene that has that name. Or we can specify the first or last if we don't know the number of objects that are going to be created at runtime, in some cases, clones which will be used to instantiate tens or dozens or even hundreds of an object. We might be looking for the first or the last such object using this method. We can also work with relative paths, such as the instance predicate. In this case, we're showing the second instance of the object with the name of 'test status', but it can be any object named 'test status' as long as it's the second one.
We provide some tools to make it easier for you to work with Hierarchy Path. You don't need to handwrite these complex paths yourself, such as the Object Explorer and the editor plug-ins, which we'll show in a few minutes here with the 2D demo. This allows you to simply find an object in the scene that you're looking for in order to perform some action or some validation, and right-click that object to capture its relative or absolute path using name or tag, or name and tag, and using the Object Explorer, where we can traverse the entire scene of objects and their components, properties, and methods, and then log or copy the precise path to that object, property, or method into a Hierarchy Path query. We also provide the HPath REPL, which allows you to test in real-time whether or not your Hierarchy Path is valid and what the return result is. As we can see in two examples here, we have two different paths to two objects such as this 'Chomper' object, in this case, the 12th such object, and its current hit points. We only see one. But if I take away the instance predicate and I just look for any 'Chomper' with the component of 'Game Kit 3D' and 'Damageable' with the 'current hit points' property, it's going to give me 26 of those in this example.
Finally, we have the Hierarchy Path debugger. This is a tool used to determine whether or not your Hierarchy Path is valid and that it is returning a result, but also to understand the specific result that's returned. If we're looking for a combination or one of the Boolean queries that the previous slide mentioned, we might look for an object with the name of 'Chomper' and has a component with the transform of rotation with a certain value. We can enter that here and it will return the result. Or if we're more interested in the value contained within a property, as shown in this example, where we enter the name of the 'Chomper', the 11th instance of that object with the component of 'Unity transform', and we're looking for the specific rotation value, that's returning the result here. This is important for a tester who might not know the details of how these things were implemented.