Unreal - Developing Custom Object Conversions
For users of the Speckle for Unreal Engine plugin, it is quite common to want to customise the way Speckle Objects are converted to native Unreal Objects. The converters we provide offer some level of control, which may fit most users needs. For users looking for more control, beyond the settings/properties exposed by a specific converter, this tutorial is for you! Maybe we don't include a converter for a specific type of object you need, Maybe you are trying to support a completely custom typ
For users of the Speckle for Unreal Engine plugin, it is quite common to want to customise the way Speckle Objects are converted to native Unreal Objects.
The converters we provide offer some level of control, which may fit most users needs. For users looking for more control, beyond the settings/properties exposed by a specific converter, this tutorial is for you!
Maybe we don't include a converter for a specific type of object you need,
Maybe you are trying to support a completely custom type of object,
Maybe you just don't like the way we convert a specific type.
In this tutorial, we will showcase the process of adding support for a completely custom type of object. From defining our Object Model, Creating a new SpeckleConverter
class, writing ToNative
conversion, and finally receiving our new objects in our scene.
This tutorial is aimed at Developer/Quazai-Dev users and should be approachable by people with only a beginner level understanding of Unreal, and Speckle.
To follow along with this tutorial you need an Unreal 4/5 project with the Speckle for Unreal plugin installed, and a compatible IDE (VS2022/Rider). See our Getting Started for help getting setup.
Read the Docs!
Before starting this tutorial, it's a good idea to read the docs relevant to conversion in Unreal. If you get stuck or are doing something complex that this tutorial doesn't cover, then don't hesitate to open a discussion on our forums.
Goals
In this tutorial we are going to add support for converting 3D Views as Camera actors. The View
type is an Object Model that is defined in our Objects kit.
We will show the process of :
- Creating our Camera Object Model by mirroring the .NET
View
object model. - Creating a converter for this type in Blueprint.
- Adding an instance of our converter to our
SpeckleConverterComponent
, and receiving camera objects along with our scene.
⚠️Views/Cameras are due for a bit of an overhall within Speckle, so much of the specific camera conversion is subject to change. However this still serves as a great example for this tutorial.
Defining an Object Model
Before we can do anything with a Speckle Object in Unreal Engine, we first require an Object Model. An Object Model represents our Speckle Object and defines its properties.
In our case, we have an Object Model already defined in .NET, and so we will be recreating it in Unreal. However, the process would be the same if this weren't the case.
This is the only part of this tutorial that must be written in C++.
If you aren't super familiar with C++, there is good news, we aren't writing any complex conversion logic here, we are just defining properties, and setting their values from the JSON object.
If we look at the .NET Object Model, we can see what properties we need to store.
The .NET Object Model Objects.BuiltElements.View
Here is a useful table of common .NET/Python/UE equivalent types.
First we will create a new UObject
class. This can be done from the C++ classes
folder in the Content Browser, or through your IDE.
Then we will change our object to inherit from the UBase
type. This is the type that all Object Models inherit from.
We can then add our properties, making sure we define them as UPROPERTY(BlueprintReadWrite)
. Setting a Category
is optional. And finally declaring our Parse
function and constructor, specifying the Speckle Type string.
Header file of our View3D Object Model with UPROPERTY
declarations
We will ignore the Units
property, as we will be baking unit conversion in our Parse
method.
The final step is to create a Parse
function that will define how we want to set these properties from the received JSON object.
Looking at the relevant docs, we can understand the structure of this function.
We have two parameters,
Obj
- the JSON object we want to parse,ReadTransport
- A collection of all other received JSON Speckle Objects.
This is needed to dereference detached properties, dechunk chunked properties, and parse nested speckle object properties.USpeckleObjectUtils
has some helper functions to make this process quite easy, which we can use to easily parse our Vector properties.
C++ implementation of the View3D::Parse
function
For required properties, we want to return false
if they are missing/invalid, rather than perform fatal assertions or exceptions.
We also want to remove the explicit properties we parse from the DynamicProperties
array.
ThisParse
method is an area we are looking to improve/simplify the developer experiance. There are a few techincal challanges for us to overcome before we can push a native deserializer like the reflection based deserializers we use in the .NET and Python SDK.
Let us know how important this feature is on the forums!
Creating a Converter
Now we have an Object Model defined, we can create a Converter class to define how to convert these objects into Native Actors/Components.
This step can be done in either C++ or Blueprint. To keep it simple for this tutorial, we will show it using Blueprint.
First create a new Object
blueprint.
Then, under Class Settings, add ISpeckleConverter
as the interface we are implementing.
Now, we can see the interface functions we must implement.
The first function we shall implement is CanConvertToNative
. This is a simple function where we can define what types of Speckle Objects this converter can convert. First we shall create a new member Variable of type Base Class Reference.
We can then set the default value of this set to include our View3D class. In this case, this will be the only type we will convert.
We can then implement our CanConvertToNative
function, which will simply check if a given Base Type
is in our SpeckleTypes
set, evaluating to a bool
which we return.
Now for the juicy part, implementing our ToNative function! For the interface implementation, we want to first cast SpeckleBase
is the type we expect (in our case View3D), then we can create a function ViewToNative
that will have our actual ToNative conversion logic.
The ViewToNative
to native function will have the following inputs/outputs.
If you are unable to set an input of typeWorld
, then add aSpawn Actor in World
node, then collapse to function.
Our ViewToNative
function should create our CameraActor
and set it up with the correct Transform and Camera settings. The first part is we want to create a transform from the ForwardsDirection
and UpDirection
vectors we have. Then we can use the Spawn Actor in World
node to create our actor.
Normally it is not possible to Spawn actors in an Object blueprint, because creating an actor requires a world context and Epic decided to only expose this for Actor blueprints (even though here we have a world context!). To get around this Spawn Actor in World
node is actually a custom node we provide that wraps the UWorld::SpawnActor
function, and is accessible in any Blueprint.
For the transform conversion, we must make sure we flip the Y axis, since Speckle Objects use a Right Handed, Z-up coordinate system, and Unreal uses a Left Handed, Z-up coordinate system.
For further reference to UE's coordinate system, see A Practical Guide to Unreal Engine 4’s Coordinate System by Nick Mower.
Now we have set up the creation of actors with a correct transform. The final step is to apply our Camera Projection Mode.
Receiving Setup
Now we have implemented our camera converter, we need to add it to our Speckle Unreal Manager. This can be done by first, creating an instance of our converter in our Contents folder. This can be done by right-clicking in a Content folder, and under "Create Advanced Asset", selecting Speckle Converter
.
We select our View3DConverter
type, and give our instance a name (e.g. "MyView3DConverter"). We can then add it to the SpeckleConverterComponent
on our SpeckleUnrealManager
.
Your browser does not support the video tag.
Now finally we can test receiving a stream with views, and see what objects are created. Here is an example stream with several views:
Speckle Stream
And receiving our stream, we can see our camera actors have been created in the right spots! 🥳
Conclusion
In conclusion, whether for adding support for a new type of object, or simply as a tool for controlling the conversion process, the Speckle for Unreal Engine plugin allows easy development of custom conversion logic. In this tutorial we explored the process of developing conversion for the View objects to Camera Actors. We hope this tutorial was helpful, and empowers our users to develop their own conversion logic.
If you have any further questions, or need help in any way, please reach out on our forums.
Don't forget to ⭐ our GitHub repositories.
Happy Hacking!
Subscribe to Speckle News
Stay updated on the amazing tools coming from the talented Speckle community.