In this article you’ll find an overview of the main differences between Virtools and Studio. By reviewing scenarios as you would have in Virtools and showing you how they can be done in Studio, you will find out more about the differences between one another.
You’ll see there are a lot of common concepts in Virtools and Studio (especially those concerning the behavioral engine and building blocks), yet they are two very different software. Both software have been designed to provide new tools to developers, designers and artists to quickly create 3D interactive applications, but Studio is a complete rewrite based on the MP technology – originally developed to cope with some of Virtools weaknesses.
Getting started with Studio if you have already used Virtools can therefore be both advantageous and disadvantageous. Since the approach has changed, this article provides the appropriate Studio equivalent of some Virtools concepts. We advise you to read the Studio User Manual to find out more on specific Studio features and concepts.
This article is also meant to raise questions and provide answers to Virtools/Studio differences. Do not hesitate to provide feedback in the Studio forum and ask for specific topics on how to transition from Virtools to Studio.
Overview of concept changes
Whereas a Virtools composition is regarded as a single large “.cmo” file that contains all the assets used for the composition, a Studio project is considered a tree of files gathered inside a project folder. Whenever possible, Studio keeps used assets as they were originally created (e.g. using a third-party software like 3D modeling tools, image editors, sound editors), and Studio-generated assets are described in an XML file format, with each specific resource having its own asset (a behavior, a VSL/schematic script, a stage description).
This asset-driven approach allows for:
- Collaborative work on different parts of a project.
- Easy replacement/iteration on source assets.
- Easy integration with a source control system.
- External editing of Studio assets through a text editor.
The above structure (which emulates how a project organizes its assets) is very well adapted to iterations in authoring mode and can also be used in “runtime” mode. For final deployment, a “build” step allows you to optionally process all these assets (like resize a texture depending on the targeted platform) and packed them into a single experience file that can be deployed on 3DVIA.com for example.
Components and Actors
A concept in Studio which was not present in Virtools but which can be familiar to many game engine users, is the “component” system.
In Virtools, objects are of a fixed given type created in C++ (like 3DEntity, Group). These objects, that you can manipulate in the “Level Editor”, describe the contents of your composition. Since almost all these objects inherit from the BeObject type (behavioral type), you can extend their capabilities by using scripts and attributes that you can attach to them.
In Studio, every element of the project that is displayed or running is called an actor, and it is made up of components. Typically, a 3D object is an actor made up of one single “vkEntity3D” component. An actor can then be extended by adding components (like physics, 2D object, particle system) to its “ring of components”.
Here is an example of an actor made up of 4 components:
Components in actor Building_A_-node: vkEntity3D, KeyboardMove, vkSound, vkPlaneConstraint.
Together with actors and components, a Studio project is made up of stages. Stages contain the actors to display. Conceptually, it is important to understand that any modification you do to an actor will be stored in the stage that contains the modified actor, as a “configuration”. This means that actor modifications are not stored in the asset from which the actor was originally created, but in the stage asset.
Components will also allow you to access some features that were formerly addressed in Virtools through Building Blocks. In Studio, you can add components to objects, available from the library (see the following chapter on this subject).
A lot of things regarding the Behavior Engine have changed. One key concept to understand is the behavior paradigm.
In Virtools, a behavior is a script that you attach to an object in the scene. The behavior is specific to the object you attach it to.
In Studio, creating a behavior is like creating a new type of component which exposes some parameters, called members, and which consists of some tasks and functions. These tasks act like the old script paradigm, they are equivalent to the Virtools behaviors. Creating a behavior in Studio is pretty much like being able to generate a C++ class definition on the fly and attach an instance of this class to any object.
As there are many things to say related to this topic, a dedicated chapter is available here.
The API has been completely rewritten. Even if some terms mays look similar to what was available in Virtools, they can mean something different in Studio, so be careful.
As opposed to Virtools, where there exists naming differences between VSL, building blocks and C++, a single naming convention is now used throughout the Studio software. This naming convention also ensures that almost any C++ function declared in the SDK, or by an external add-on developer, can be used “as-is” a VSL function and a Schematic building block. Moreover, any function created as a building block can be used in VSL and vice-versa.
One of the consequences of this new API is that scripts coming from Virtools cannot be opened in Studio, any 3D/2D media stored in a .cmo/.nmo can be imported inside Studio but behaviors cannot.
Creating new Objects
In Virtools, the 3D view contains icons for you to create several types of objects such as cameras, lights, arrays, and so on.
In Studio, the act of creating an object is called “instantiation” and starts by drag and dropping the object’s template from the Libraries view. The “Presets” folder contains all the system templates from which you can create objects, by instantiation.
Included with Studio, you also have access to a library of sample models, which you can use to quickly prototype gameplay.
Lastly, don’t forget to log on to 3DVIA.com and search for ready to use templates such as cameras, particle systems, UI components, …
Another important concept in Studio is the difference between components and resources. Resources are shared data, such as sound data (vkSoundResource), texture data (vkTexture), material data (vkMaterial), mesh data (vkRenderable). To create a resource, right-click on a stage in the Project Editor.
The first thing to understand about Studio scripting is that you do not work on a specific behavior instance. In Virtools, a script is a unique instance attached to a unique object which can be copied but with no “share” concept. In Studio, when you edit a behavior’s schematic task or function, you are editing the definition of that task or function, which is shared by all the behavior’s instances present in the project.
Scripts, Tasks, Functions
To add a script to an object in Studio, you first need to create a behavior and then create a task or a function as part of that behavior. A task in Studio is like a script in Virtools, that is a piece of code/graph that is executed every frame until deactivated. A function, on the other hand:
- is executed only when explicitely called through VSL/Schematic programming or through events,
- it is executed immediatly within a frame (cannot contain frame breaks or be execute over several frames),
- it is the equivalent of a deactivated script in Virtools, which you used to call using the BB “CallScript”, but with the added capabilities of having input/output parameters
Whereas Schematic was the only way to create a script on a Virtools object, in Studio a task can be defined in Schematic or in VSL:
A Schematic task looks like a Virtools script, and a VSL task looks like this:
The behavior also has members, which are behavior parameters that can be edited in the Property View or accessed through VSL and Schematic.
The way of editing the configuration of a script (behavior) in Virtools is to have local variables in the script and edit those variables in the Schematic:
In Studio, you can still edit behavior parameters in the Schematic but they will be shared by all the instances of the behavior. The standard way to go is to “expose” parameters of the behavior (members) from the Behavior Editor. (This is also the way to emulate Virtools Attributes).
Every actor in the project which has this behavior in its component ring will store the configuration of these parameters, which can be accessed through VSL/Schematic and edited from the Property View. This configuration is stored on a per actor basis at a stage level. But you can edit several actors at the same time in the Property View by selecting all of them.
In the Property View, a parameter will appear in bold face if its value is different from the one specified in the Behavior Editor. It is important to understand that the value you edit in the Behavior Editor is a “default value“, that is the value to use when an instance of this behavior is created and attached to an actor. Then, the actor itself holds its own value and can configure it differently. On the other hand, when you access a behavior member in VSL/Schematic, you are accessing the value hold by a given actor (by default the actor which contains the behavior component).
Calling / executing a script / VSL
Whereas in Virtools a script can be activated/deactivated, in Studio you use “StartTask” or “StopTask” to start/stop a task.
Since VSL is now tightly integrated with the Schematic, there is no equivalent to Virtools’ CallScript and RunVSL building blocks. As a result, a task, a function, a building block can be written in Schematic or in VSL, and you can directly call a VSL function in the Schematic and a Schematic function in VSL.
As an example, below you’ll find the same exact function written in VSL and written in the Schematic. The legitimacy of using the Schematic for such a function is indeed arguable, but the purpose of this example is to illustrate the exchangeability of using one or the other.
These two functions can be called from another VSL/Schematic task or function:
|Called from VSL||Called from Schematic|
Building Blocks library
In Studio, building blocks are available from the Building Blocks view, in the behavior Workset:
|Building Blocks in Virtools||Building Blocks in Studio|
You can also access API and low-level functionalities, for use in the Schematic, from the Types view. The Types view provides access to all the SDK types, including classes and functions, which you can directly drag and drop in the Schematic for use like a building block. To search for a specific type in the Types view, simply hit CTRL + F to activate the search box.
For example, to use the “ClosestPoint” method available on a vkAABox, you can drag and drop it from the Types view to the Schematic. New classes and methods created in C++ with the SDK and bound to the engine will also appear in the Types view.
You can also use the SHIFT + CTRL + Double Click shortcut in the Schematic to open a completion box that will list all the available API methods.
Like you can create your functions, you can create your own building blocks, in VSL or with the Schematic. The choice of using VSL or Schematic is given when the building block is created. Below, a VSL building block:
|Creation f rom the Building Blocks view contextual menu:
Creation from the Schematic editor context menu:
|Building Block description:|
When used in the Schematic, the above building block will look like this:
In Virtools’ Schematic, you can create parameter operations to perform simple operations between 1 or 2 parameters, or to access certain object properties like the position of a 3D entity.
Since there are no parameter operations in Studio, this section will tell you how the same functionalities can be achieved.
In Studio, any building block can be converted to the equivalent of a parameter operation, called an evaluator. An evaluator is a building block which is executed when its output parameters need to be evaluated. An evaluator can have any number of input and output parameters but cannot have more than one in trigger.
So a graph like this:
can be converted to an evaluator flow by converting the different BBs to evaluators:
To perform simple mathematical operation, use the “Operator” building block. You can choose the operation to perform from a fixed list but any type can be used as input (start typing the name of the type and use auto-completion). For rather complex operations, you can quickly create a VSL function or a VSL BB, which is the optimal way of performing complex computations. “Operator” BB is available from the “Logic > Calculator” category in the Building Blocks view. You can also CTRL + Double-Click in the Schematic and start typing “Operator”.
In Virtools, access to object properties is carried out using parameter operations or building blocks. Local parameters are created directly inside the Schematic view.
In Studio, properties of components and other types of structures can be freely accessed without requiring specific BBs or evaluators. To access an object’s properties or a local parameter, you can do one of the following:
In Virtools, in order to read or set the value of a structure such as a vector, you could use the Get Component BB or Set Component BB. In Studio, every member structure can be directly accessed for read or write operations, provided the member has been exposed. For example, a BB that takes a vkVec3 as input parameter exposes it, by default, as a single parameter, but you can expose each of its x,y and z fields independently for editing or linking separately.
To expose fields/sub-members, you can do one of the following:
- Select the BB. In the “Pin” drawer, every input parameter is listed and you can expand the parameter structure to display its sub-members. In the example below, we have exposed the “y” field of the input “Position”.
- Right-click on the parameter and choose “Export members” from the contextual menu.
Exposing the sub-members of a building block input parameter will allow you (for example) to have one of its fields with a fixed value, and two other fields coming from different links. The same possibilities also apply to output parameters.
Attributes on objects
In Virtools, you could add attributes to objects through building blocks and “Object Setup”. Attributes could be used by default system to handle objects with specific properties (collisions, particles, AI) but also by the user to attach application-specific data to objects.
In Studio, this feature is handled through components and behaviors. System features are provided through components such as physics and particle systems, and the user can create its own behavior to store any type of data on any actor. A behavior does not necessarily have to have a task or a function; it can simply consist of a list of members (like attributes) that can be attached as an additional component to an object.
To know if a given actor has a behavior (e.g. to test the presence of an attribute for example) you can add this behavior type to the list of targets of your task (See Accessing Properties). You can also use the “ComponentCast” method in VSL to require an interface on any component (or QueryComponent).
- In VSL, the call looks like this:
- and in Schematic:
These two methods will return a pointer to the behavior (or NULL if the component ring does not have such a behavior). Once you have access to a component you can access its properties as explained above.
Shortcuts in scripts
In Virtools you could use shortcuts for different purposes:
- To access a local or input parameter anywhere in a Schematic graph.In Studio, you can directly link to parameters available in the top or bottom drawers, or drop in an empty space of the Schematic to directly connect to an exposed/local variable.
- To share parameters between different scripts.In Studio, your tasks are shared by all the instances of the behavior, so exchanging parameters between behaviors needs to be done through the behavior members themselves.Commonly used methods:
- Create a behavior to manage several behaviors.
In this case, a specific singleton behavior is created to host global variables that other tasks will be able to access and modify. To be able to access such behavior from anywhere, you can use a static member which stores a pointer to this unique instance.
- Call the functions of another behavior through parameters.
- Store a pointer to another behavior instance in the members.
- Use the Global parameters actor (right-click on the default stage to enable Global Parameters).
- Create a behavior to manage several behaviors.
In Virtools, a behavior link could be delayed (in number of frames) before executing the next building block. Most of the time, the delay was set to 1, but a larger value could be used to overcome priority issues.
In Studio, this is handled though a Frame Break which forces the next BB to be executed at the next frame. To handle larger frame delays, you can use the Counter BB.
In Virtools, you cannot create new structures but you can create new enums or flags using a specific editor:
In Studio, you can freely create any type of class (behavior), structures, enums or flags, as the subtype of a behavior (when editing the behavior, double-click on “new type” in the Sub-Types section of the Behavior Editor) or as a global type (right-click in the user folders of the Types view).
Creating a new type opens up a dialog from which you can choose the kind of type you want to create and, optionally, a parent class for classes.
The newly created type can be used as a type for any member of a behavior or, if use recursively, as the type for another type. The serialization and display is automatically handled by Studio.
Below, the editor for each type:
Each type has its own display UI when used as a member in the Property View:
Sending/receiving messages: Events
In Virtools the SendMessage/Wait Message building blocks were used to send and receive messages, and some parameters could be attached to a message.
In Studio, messages are replaced by events. Events can be system events (sent by the engine) or user-created events.
To create a new event type, you need to create a new class (see above chapter) that inherits from the vkUserEvent class. You can then add members to this event.
There is a dedicated article on event handling, the important thing to note is that, except for the Wait Event BB in the Schematic, events are handled immediately. When a function is set to be triggered by an event, it will be immediately called when the event is sent to the behavior owner of the function.
Another important thing to note about system events such as vkClickableXXXEvents is that these events are only sent by actors holding a vkClickable component in their component ring. This component can be added to any 3D or 2D actor by drag and dropping it from the Libraries view to the actor in question.
Priority/order of execution
In Virtools, the priority of execution was first organized on object priority, then each script could have its own priority. In Studio, the order of execution of tasks is handled from the Task Groups view in the behavior workset.
|In this view, the order of execution of tasks inside a frame is explicitly accessible and modifiable. The order of execution is read from top to bottom and each group can be freely repositioned. The ordering of task groups is saved on a per project basis. By default, every behavior task is executed during the BehavioralProcess task group. You can create new behavioral task groups and set your task to be executed during this group. In the following example, all the active instances of the “SchematicTask” are executed during “TaskToExecuteFirst” then all the active instances of the “VSLTask” are executed during “BehavioralProcess”.|
In Virtools, you can activate “trace mode” to see in real time which BBs are active and more globally the current activity of links inside a graph. There is currently no such mode inside Studio but the breakpoint mode enables you to achieve very precise debugging while still being able to navigate inside the scene.
In Virtools, a dedicated object type, the DataArray , can be used to store data in rows. In Studio, you can create any type of static or dynamic array, whose cells can be of any type. So you can create a multidimensional array for example.
Let’s say we want to create an array where each row contains a float, an object, a string and a vector position. In Virtools, it will look like this:
In Studio, start by creating the appropriate subtype (a class) in a behavior editor. This will define the type of elements of your array.
Then create a member in this behavior to store your array.
Now you can edit the array on every instance of this behavior. This can be achieved:
- In the property view by
- Clicking edit – to add/remove row and setup valuesor
- Extending the parameter and setup values directly inside the property view.
- In VSL, you have direct access to the methods and members of a vkArray:
- In Schematic, the “array” BBs, available from the Logic > Container category in the Building Blocks view, provide everything you need to parse arrays:To use these BBs in the Schematic, simply drag and drop them in the Schematic and edit their variable settings (right-click on a BB to edit its variable settings) to match the format of the vkArray you want to parse:
Once this is done, the BB inputs/outputs automatically match the format of the array (all the array BBs are configurable to match the content of the array).
Searching in Schematics
CTRL + F
As explained above, many features achieved through building blocks in Virtools are now natively available within Studio. For all these features you can still use VSL or building blocks to control properties and/or create effects in runtime.
|Physics||User uses building blocks to make its objects part of the physic world:||User applies a “Physics Rigid object” component from the Libraries view to the models that need to be part of the physics world:
Building blocks/VSL can be used to (de)activate, apply forces, etc.
|Shadows||User uses building blocks to make its objects cast/receive shadows:||Shadows are now natively part of the render engine.
Enabling them is just like enabling a parameter on a Light.\
Each object can choose to receive/cast shadows.
|Particle Systems||User drops a “Particle System” BB and configures its parameters inside the Schematic.||User applies a “Particle Systems” component from the Libraries view to the 3D objects that need to emit particles.
The parameters are edited in the Property View of the object.
Ready-to-use Particle Systems (smoke, fire ,etc.) are also available from the 3DVIA.com explorer.