How to Use VHL Interface using Asset Bundle
This page describes how to use data from a Vortex VHL interface in a custom Unity script. This is a simply way to implement custom behavior or logic in Unity using data in a distributed Vortex simulation.
Overview
First of all, to manually create assets for the VHL Interface, a Unity project with the Vortex Integration Package is needed (such as VortexUnityTools or your own project).Â
For an overview of the assets workflow, refer to How are Asset Bundles used . VHL Interface follows the same pattern as for other supported features:
A prefab must be made and associated to a VHL Interface. They must share the same name.
The prefab must have a component attached to it: the VortexVHL component.
The prefab must be in an asset bundle. The asset bundle must have the same file name and path as the Vortex document (vxscene, mechanism, etc.) that contains the VHL interface.
Â
VortexVHL interface are also available directly in the Unity Scene, when the Unity Scene is associated with a Vortex Scene. See Communicate with Vortex using VHL interfaces for more information.
Using Asset Bundles to access VHL is primarily used in existing assets created with com.cm-labs.vortex.integration package and is kept to make the transition to com.cm-labs.vortex.integration.unity simpler.
Creating a Prefab for a VHL Interface
With the Vortex Studio Integration package installed, it is quite simple to create a prefab for a specific Vortex VHL interface. Here is a short guide:
First, identify which VHL interface you want to access from Unity. This can be done by opening any Vortex file that supports VHL interfaces, such as mechanisms, assemblies, scenes and graphics galleries.
Then, from the Unity Editor, create a new empty GameObject. This can be done by right-clicking the Hierarchy window and selecting Create Empty.
Copy the name of your Vortex VHL instance, and set it as this new GameObject's name. This will be the root of your prefab.
Add a VortexVHL component on this GameObject. This class allows to access VHL interface data from Unity.
From there, the prefab's content and behavior is up to you, the user. Typically, a custom script is added to this GameObject, alongside VortexVHLÂ component. From the script, you can access any VHL input, output or parameter; as is described in the following section.
Using the VortexVHL Component in a Script
To use the data in a script, the prefab must contain a script component:Â it is in such a script that the VHL interface's data can be accessed. To do this, you first need to get a reference to the VortexVHL component. It is recommended to do this in the Start or Awake method, then re-use it as needed.
The following methods can be used to access the value of the data from a VHL interface's field. All these methods take the same argument: the string corresponding to the field path. When using these methods, if a field is not found, an error will appear in the log and the value returned will be a default value.
Return Data Type | Get Field Method | Additional Notes |
---|---|---|
bool | GetBool | |
int | GetInt | |
double | GetReal | |
string | GetString | |
UnityEngine.Vector2 | GetVector2 | Vortex Vector 2 of double values. |
UnityEngine.Vector3 | GetVector3 | Vortex Vector 3 of double values. |
UnityEngine.Vector3 | GetVector3AsPosition | Vector 3, assumed as position information. It is converted from Vortex to Unity coordinate system. |
UnityEngine.Vector4 | GetVector4 | Vortex Vector 4 of double values. |
UnityEngine.Color | GetColor | Vortex Color of float values |
UnityEngine.Matrix4x4 | GetMatrix | Vortex Matrix44 represented by Unity's Matrix4x4 type. No conversion is done whatsoever. |
Vortex.Types.PositionRotation | GetMatrixAsPositionRotation | Matrix4x4, interpreted as transform information into the PositionRotation class, which contains a position vector, rotation quaternion, and scale vector adapted from Vortex to Unity coordinate system. These can be used directly to assign to Unity Transform component's position, rotation and scale properties. |
string | GetExtensionName |
It is also possible to set value to a VHL extension through Unity. However, this feature is only available on standalone simulators (single node) or on the master node of a multi-node simulator. For more information about nodes, please refer to Integrating Vortex Studio using the SDK - Making a Vortex Application .
The following methods can be used to set the value of the data from a VHL interface's field. All these methods take two arguments: the string corresponding to the field path and the value to be set in the VHL. When using these methods, if a field is not found, an error will appear in the log and the value returned will be a default value. These methods will also fail and return an error if the code is not running on the Master node.Â
Parameter Data Type | Set Field Method | Additional Notes |
---|---|---|
bool | SetBool | |
int | SetInt | |
double | SetReal | |
string | SetString | |
UnityEngine.Vector2 | SetVector2 | Vortex Vector 2 of double values. |
UnityEngine.Vector3 | SetVector3 | Vortex Vector 3 of double values. |
UnityEngine.Vector3 | SetVector3AsPosition | Vector 3, assumed as position information. It is converted from Unity to Vortex coordinate system. |
UnityEngine.Vector4 | SetVector4 | Vortex Vector 4 of double values. |
UnityEngine.Color | SetColor | Vortex Color of float values |
UnityEngine.Matrix4x4 | SetMatrix | Unity's Matrix44 represented by Vortex Matrix4x4 type. No conversion is done whatsoever. |
UnityEngine.Transform | SetMatrixAsPositionRotation | Unity's Transform converted to Vortex coordinate system as a Vortex Maxtrix4x4. |
Please note that for your custom script to be tied to your asset bundle and usable with the default Vortex Unity application, you need to follow the process described in this guide:Â How to use Unity Script with Asset Bundles .
VHL Interface Script Example
Here is an example of a script that uses a VHL interface to display some Vortex data in Unity.Â
Sample Script
using UnityEngine;
using Vortex;
public class DisplayVHLData : MonoBehaviour
{
private Vortex.VortexVHL vhl = null;
public UnityEngine.UI.Text speedText = null;
public UnityEngine.UI.Text distanceText = null;
public UnityEngine.UI.Image engineImage = null;
public bool isVisible = false;
void Awake()
{
vhl = GetComponent<Vortex.VortexVHL>();
}
void FixedUpdate()
{
if (speedText != null)
{
double speed = vhl.GetReal("Inputs.Speed");
// Displays speed with 2 decimals format
speedText.text = $"Current Speed: { speed.ToString("F2") }";
}
if (engineImage != null)
{
bool engineOn = vhl.GetBool("Inputs.Engine Active");
engineImage.enabled = engineOn;
}
if (distanceText != null)
{
double distance = vhl.GetReal("Outputs.Distance");
// Displays distance with 2 decimals format
distanceText.text = $"Distance Moved: { distance.ToString("F2")}";
}
vhl.SetBool("Parameters.Visibility", isVisible);
}
}
Here is how this script is attached to a prefab with the proper components and references to them:
And here is the VHL interface as defined in a mechanism in the Vortex Editor:
Once the asset bundle has been built and placed next to its corresponding mechanism, it can be loaded and the simulation can be started. The display will be added to the simulation and updated by the script.
.
Using VortexVHL dynamic fields
For ease of use, the VortexVHL component exposes dynamic fields. The member Inputs
, Outputs
and Parameters
are object extending C# System.Dynamic.DynamicObject
. For example, a VHL input property named "Velocity" can be access by writing vhl.Inputs.Velocity
. There is a few things to keep in mind while using this feature.
The dynamic fields are subject to the same limitations as C# DynamicObjectÂ
This means the properties can't be reserved words such asdouble
,return
,bool
, etc. This also means you can't use extension methods directly.// double myDouble = vhl.Inputs.double; // ERROR: double is a C# reserved keyword // Vector3 myPosition = vhl.Outputs.Position.MyExtensionMethod(); // ERROR: CS1973: Vector3<dynamic> has no applicable method named MyExtensionMethod() Vector3 myPosition = vhl.Outputs.Position; myPosition = myPosition.MyExtensionMethod(); // OK
Property's names are case sensitive
Non-alphanumeric characters are replaced with underscores
Vortex allows field's properties to contain character that can't be used to form valid C# identifiers such as space, parenthesis, punctuation to name a few. These properties can be access by replacing the non-alphanumeric values with underscores. For example, the VHL input property "Desired Velocity" can be access withvhl.Inputs.Desired_Velocity
, and the VHL output property "My output (5)" can be access withvhl.Outpus.My_output__5_
. Notice the double underscore betweenoutput
and5
: this is because the space and the opening parenthesis both account for one underscore.Values are returned as raw values
Objects like Vector3 and Matrix4x4 are returned as raw values. A Vector3 representing a position in Vortex frame of reference would need to be converted to Unity referential withÂConversionUtilities.VortexToUnityVector
. Similarly, a Matrix4x4 transformation matrix in the Vortex frame of reference also needs to be converted withÂConversionUtilities.VortexToUnityPositionRotation
.
Dynamic Field Usage Example
The following figures shows a VHL interface configuration and a script sample demonstrating how to use the dynamic fields.
Dynamic Fields
using UnityEngine;
using Vortex;
public class DynamicVHLData : MonoBehaviour
{
private Vortex.VortexVHL vhl = null;
public bool myBool = false;
public Color myColor = null;
public string myString = null;
void Awake()
{
vhl = GetComponent<Vortex.VortexVHL>();
}
void FixedUpdate()
{
myBool = vhl.Inputs.isActive; // yields true
myColor = vhl.Outputs.My_color; // yields a new UnityEngine.Color(1,1,1,1)
myString = vhl.Parameters.Texture; // yields "default texture"
}
}