When starting out in Studio, the first kind of type you will likely need to cast between are the 3D types listed under “Scene Graph.” All of these types are related by the fact that they all exist in the 3D space of your project, so they all describe a position, orientation and scale. They can also contain parent-children relationships with each other. Using the types explorer (shown below), you can view the hierarchal relationship between all of the types in Studio, as well as all of the functions they use.
The hierarchy of types can help you determine whether a cast is going to be valid or not. A cast between a child to a parent (or its parent’s parent, and so on) will always be valid. The parent class of a vkEntity3D is a vkNode3D, so I know if I have a vkEntity3D I can always cast to a vkNode3D (or even a vkNodeBase, which is the parent of a vkNode3D).
Vice versa, a cast between a parent to a child is only sometimes valid. If we take a look at vkEntity3D again we can see two of its children are vkLight and vkCamera. If a type has more than one child, it is up to the user to make sure they are making a valid cast, because while it’s true a vkEntity3D can be either a vkLight or a vkCamera, it has to be one or the other, not both (as one vkEntity3D component cannot be both a camera and light at the same time).
To drive the point home, let’s put this information to use in a real example. In the project we have a fan, and our goal is to make the fan blades rotate. I first start by creating a new behavior, called “fanBehavior” on the fan blade actor. We notice that in the component ring of the actor, we now have a vkEntity3D and fanBehavior.
We then create a “rotate” task, drag in the rotate building block, and parameterize the axis and radian angle with respects to how we want the fan to rotate. The target of the rotate building block is looking for a vkNode3DPtr, and from what we learned above we know that a vkEntity3D can be cast into a vkNode3D. To do this, we simply need to expand the “Target” tab of the task (note our fanBehavior component is automatically there) and add a new member of type vkNode3DPtr. The “Target” tab of any task or function acts as a way to access any other components on the object, such as it’s 3DEntity, constraints, or physics. In this case we are accessing the vkEntity3D component and casting it to a vkNode3D, so we can then link this new member to the target of our rotate building block.
This works because we know there is vkEntity3D contained in the component ring, so by adding a new member to the Target tab of the task of type vkNode3D, Studio does an automatic cast between the two components for us. Alternatively, we could’ve added a new member of type vkEntity3D, and explicitly used the vkNode3D::ComponentCast to retrieve our vkNode3D.
Casting in VSL works very similar to the schematic example above. Below is the exact same task that we did in schematic, but coded in VSL instead. Note that we simply add a vkNode3DPtr within the “Target” bracket just as we did in the “Target” tab of the schematic task.
Definition of the task rotateVSL
bool Execute(const vkTaskContext& iCtx)
This is just one example of a casting between a hierarchy of types within Studio. As you continue to develop in Studio, you will realize how critical understanding this concept is, as this same tactic will be used time and time again!