> ## Documentation Index
> Fetch the complete documentation index at: https://speckle-assistant.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Unreal

export const app_0 = undefined

export const versions_0 = "4.27 & 5.x and newer"

export const connector_0 = "Unreal"

<div class="callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border-2 border-red-600 bg-red-100/50 dark:border-red-600 dark:bg-red-400/20" data-callout-type="warning">
  <div class="mt-0.5 w-4" data-component-part="callout-icon">
    <svg class="flex-none w-5 h-5 text-red-700 dark:text-red-300" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-label="Warning">
      <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
    </svg>
  </div>

  <div class="text-sm prose min-w-0 w-full text-red-700 dark:text-red-300" data-component-part="callout-content">
    <b>Notice</b>: This user guide is based on the legacy {connector_0} connector.<br />
    We recommend using our new connectors instead, as they are easier to use and actively maintained. This legacy documentation may not be up to date.
  </div>
</div>

<Info>
  Legacy Speckle supports {app_0} versions: {versions_0}
</Info>

Our Unreal Engine Connector reached a **beta** stage of development. <br />
Currently, we only support **receiving geometry** (sending support is on our roadmap). <br />

We officially support Unreal Engine 4.27 and newer 5.X versions on Windows, Mac, and Linux platforms (other platforms untested).

Make sure to check out (and star :star: ) our Github repository: [https://github.com/specklesystems/speckle-unreal](https://github.com/specklesystems/speckle-unreal)
If you have any thoughts or suggestions about this plugin, you're welcome to [discuss them in our forum](https://speckle.community/).

<Info>
  For additional resources, see Unreal's guides on [Installing Unreal Engine](https://docs.unrealengine.com/4.27/en-US/Basics/InstallingUnrealEngine/),
  [Setting Up Visual Studio for Unreal Engine](https://docs.unrealengine.com/4.27/en-US/ProductionPipelines/DevelopmentSetup/VisualStudioSetup/),
  and [Create a New Project](https://docs.unrealengine.com/4.27/en-US/Basics/Projects/Browser/).
</Info>

## Installation (Marketplace)

The Unreal Connector is packaged as a code plugin on the [Unreal Engine Marketplace](https://www.unrealengine.com/marketplace/en-US/product/speckle-for-unreal-engine). For most users, this installation method is recommended.

Once installed, it is necessary to **enable the Speckle plugin** for your project from the **`Edit → Plugins`** menu. Once enabled, you should be promoted to restart your project.

**That's It!** Your project can now use the Speckle plugin!

## Installation (Git)

For developers wanting to modify the source code, trial work-in-progress branches, and/or contribute changes back to the speckle-unreal repo, installing through [git](https://git-scm.com/) is prefered.

1. Git clone [this repo](https://github.com/specklesystems/speckle-unreal) into your project's `Plugins` directory (created as needed).

```
git clone https://github.com/specklesystems/speckle-unreal
```

3. Open your UE project (or restart the editor if you already have it opened). This will build the plugin in your environment.

If you encounter build issues, try building your project from VS/Rider directly. Look at the `Saved\Logs\` files for error messages,
and don't hesitate to reach out on our [community forums](https://speckle.community) for help!

## Usage (Editor)

The plugin includes an actor type named `Speckle Unreal Manager` that you can use to import objects from Speckle.

Here is how to use it:

1. In the `Place Actors` sidebar, search for *Speckle Unreal Manager* and add it to the world.

<Frame>
  <img src="https://mintcdn.com/speckle-assistant/2EmalpcbVGQpx8bs/images/legacy/unreal/speckle_manager_actor.png?fit=max&auto=format&n=2EmalpcbVGQpx8bs&q=85&s=2397806ce128c2499e7dd3624bb1309b" width="50%" alt="speckle manager actor" data-path="images/legacy/unreal/speckle_manager_actor.png" />
</Frame>

***

2. Select the `SpeckleUnrealManager` instance in the `World Outliner` sidebar and use the options presented in the `Speckle` category.

<Frame>
  <img src="https://mintcdn.com/speckle-assistant/2EmalpcbVGQpx8bs/images/legacy/unreal/speckle_manager_config.png?fit=max&auto=format&n=2EmalpcbVGQpx8bs&q=85&s=598dc107007538b38c3d6dcfa1a2753d" width="50%" alt="speckle manager config" data-path="images/legacy/unreal/speckle_manager_config.png" />
</Frame>

***

3. There are **two ways to import objects** using the `Speckle Unreal Manager` actor.

<Tip>
  Import <b>a specific object</b> id, by specifying a <i>Server URL</i> + <i>Project id</i> + <i>Object id</i>

  <Accordion title="Expand">
    <summary>Expand</summary>

    **1.** Firstly, ensure the **"specify by object id" checkbox is checked**, and the **Sever URL** matches the Speckle server you are using (default [`https://app.speckle.systems`](https://app.speckle.systems))

    **2.** Enter the **Project ID**. This can be copied from the url of your project, and pasted into the "Project ID" property of your `Speckle Unreal Manager`.

    <Frame>
      <img src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/finding_stream_id.png?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=ec8af7a0415437a143db88285bcdf24c" width="75%" alt="screenshot of a speckle project url https://app.speckle.systems/streams/76c45cdb32, with the project id 76c45cdb32 highlighted" data-path="images/legacy/unreal/finding_stream_id.png" />
    </Frame>

    **3.** Enter the  **Object ID** of the object you want to receive.
    You can explore the objects in a project by using the Speckle Web App for the Speckle server that you use.

    <Frame>
      <img src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/finding_object_id.png?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=2f01b6702d2238624cfca88c4c38f0b5" width="75%" alt="screenshot of the property panel of a Speckle version,> highlighting the object ID of the selected (root) object" data-og-width="963" data-og-height="884" data-path="images/legacy/unreal/finding_object_id.png" data-optimize="true" data-opv="3" srcset="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/finding_object_id.png?w=280&fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=3b055d045569b8aea6aa4d61d31a0509 280w, https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/finding_object_id.png?w=560&fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=c817e534d468ca52d9ab50fd454e3bef 560w, https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/finding_object_id.png?w=840&fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=bb6c25bdfe3856708550b05c4192b142 840w, https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/finding_object_id.png?w=1100&fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=1436e16bd0cbd0180feb467d789917e3 1100w, https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/finding_object_id.png?w=1650&fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=14f0ae9acfb30f838ecd0a75b8a50ec3 1650w, https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/finding_object_id.png?w=2500&fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=01f944ad1536d5d934241f05904f4e67 2500w" />
    </Frame>

    **4. If the stream is private**, you will need to generate an **auth token**.
    To do so, head to your profile page [https://app.speckle.systems/profile](https://app.speckle.systems/profile), and generate a new Access Token (with all scopes)

    <Frame>
      <img src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/generate_auth_token.png?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=44b04f09c038540432e82979a8e506d4" width="75%" alt="screen shot of profile page, with arrow pointing towards the new token button" data-path="images/legacy/unreal/generate_auth_token.png" />
    </Frame>
  </Accordion>
</Tip>

<center><b>OR</b></center>

<Tip>
  Import <b>a speckle version</b>, by specifying a <i>Server URL</i> + <i>Auth Token</i>, and then select a <i>project</i> + <i>model</i> + <i>version</i> from the drop down menu.

  <Accordion title="Expand">
    <summary>Expand</summary>

    **1.** First, you must authenticate your Speckle account.<br />
    Currently, this can only be done via an **auth token** (aka personal access token).<br />
    To generate one, head to your profile page <a href="https://app.speckle.systems/profile">[https://app.speckle.systems/profile](https://app.speckle.systems/profile)</a>, and under "Access Token", generate a new token **with all scopes**.

    <Frame>
      <img src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/generate_auth_token.png?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=44b04f09c038540432e82979a8e506d4" width="75%" alt="screen shot of profile page, with arrow pointing towards the new token button" data-path="images/legacy/unreal/generate_auth_token.png" />
    </Frame>

    **2.** Paste the auth token into your `Speckle Unreal Manager` actor (also, ensure the `ServerUrl` is correct)

    **3.** Deselect the "specify by object id" option, and, assuming the url + token is valid, the drop down selections for `project`, `model`, and `version` will be available.

    <Frame>
      <video width="66%" loop controls autoplay muted src="https://mintcdn.com/speckle-assistant/2EmalpcbVGQpx8bs/images/legacy/unreal/stream.branch.commit.selection.mp4?fit=max&auto=format&n=2EmalpcbVGQpx8bs&q=85&s=b34d85b196ffde34f61c39d63d1c3580" type="video/mp4" data-path="images/legacy/unreal/stream.branch.commit.selection.mp4" />
    </Frame>

    (optional notes) The number of project/model/versions is capped, by default at 15, but this value can be adjusted under the advanced settings `options limit` value.
    If no options appear, then try deselecting, and reselecting the actor, and check the `Output Log` for warnings.
  </Accordion>
</Tip>

<Warning>
  Treat your Personal Access Token **as a password**. If someone else has access to your auth token, they can access your Speckle data!
</Warning>

***

4. After you set up the receive parameters, just click the `Receive` button. The specified object and all its children will be imported as Actors.<br />
   To set options on how the objects are converted, see the [object-conversion secion](./unreal.html#object-conversion).

## Usage (Blueprint)

Blueprint can be a powerful tool for implementing your own custom behaviours for receiving objects.

The receiving process can be performed using blueprint, doing it this way can allow for **extra flexibility** for performing additional actions with received data/converted actors.

Using blueprint to do this requires some basic understanding of how the plugin works.

* A `ServerTransport` is used to make a HTTP request to a Speckle server for the object (and its children).
  It fetches JSON objects from the server, which are then stored in a local `Memory Transport`.
* The `ReceiveOperation` node handles the received objects, and deserializes them into Object Models (objects inheriting `UBase`).
* The `SpeckleConverterComponent` converts these objects into native actors/components.

An example of this process in Blueprint is provided in the `Plugins\speckle-unreal\Content\Examples` directory and looks like this:

<Frame>
  <img src="https://mintcdn.com/speckle-assistant/2EmalpcbVGQpx8bs/images/legacy/unreal/receiving_bp.png?fit=max&auto=format&n=2EmalpcbVGQpx8bs&q=85&s=09f883b94abd49cf1ef0bf1bdab39587" width="100%" alt="receiving bp" data-path="images/legacy/unreal/receiving_bp.png" />
</Frame>

Additionally, a number of Blueprint macro nodes are provided to fetch details about project/model/version/users.

## Object conversion

The `SpeckleConverterComponent` provides the conversion functionality for converting **Speckle objects to native UE Actors**.
However, this class does not contain specific conversion logic.<br />
Instead, the **converter logic is modularised**, such that the conversion functions and settings for specific types are encapsulated **in their own class** implementing `ISpeckleConverter`.

> Please note that `ISpeckleConverter` here, is not the same as the `Speckle.​Core.​Kits.​ISpeckleConverter` in the .NET SDK.

Out of the box, the plugin provides converters for the following conversions:

|                                                                                                                      Speckle Type |     | Native Type                                                                                                                                                                                                                                                       |
| --------------------------------------------------------------------------------------------------------------------------------: | :-: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|             [`Objects.Geometry.Mesh`](https://github.com/specklesystems/speckle-sharp/blob/main/Objects/Objects/Geometry/Mesh.cs) |  →  | [Static Mesh Component](https://docs.unrealengine.com/4.27/en-US/API/Runtime/Engine/Components/UStaticMeshComponent/) /<br /> [Procedural Mesh Component](https://docs.unrealengine.com/4.27/en-US/API/Plugins/ProceduralMeshComponent/UProceduralMeshComponent/) |
| [`Objects.Geometry.PointCloud`](https://github.com/specklesystems/speckle-sharp/blob/main/Objects/Objects/Geometry/Pointcloud.cs) |  →  | [LiDAR Point Cloud](https://docs.unrealengine.com/4.27/en-US/WorkingWithContent/LidarPointCloudPlugin/LidarPointCloudPluginReference/)                                                                                                                            |
|         [`Objects.Other.BlockInstance`](https://github.com/specklesystems/speckle-sharp/blob/main/Objects/Objects/Other/Block.cs) |  →  | Actor with Transform                                                                                                                                                                                                                                              |
|   [`Objects.BuiltElements.View`](https://github.com/specklesystems/speckle-sharp/blob/main/Objects/Objects/BuiltElements/View.cs) |  →  | Camera                                                                                                                                                                                                                                                            |
|      [`Speckle.Core.Models.Collection`](https://github.com/specklesystems/speckle-sharp/blob/main/Core/Core/Models/Collection.cs) |  →  | EmptyActor                                                                                                                                                                                                                                                        |

> `StaticMeshConverter` and `ProceduralMeshConverter` are mutually exclusive, and for most users we recommend using static meshes (default).

Due to the nature of Unreal Engine, it is necessary to offer **options/settings for how objects are converted**.
So each `ISpeckleConverter` can also expose **properties that can be set** from within the editor, or from BP/C++.
This structure is distinctly different from other connectors, which often have one large conversion class that holds many conversions, and provide few (if any) settings.

Using the `StaticMeshConverter` as an example, you can see that it exposes several settings, such as the type of actor to create, and mesh build settings.

<Frame>
  <video width="100%" loop controls autoplay muted src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/converter-settings.mp4?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=21abc5878b374cb63fe82601ee64cddd" type="video/mp4" data-path="images/legacy/unreal/converter-settings.mp4" />
</Frame>

Out of the box, `SpeckleConverterComponent`s will be setup with a set of default converters.
For most users, there is no further configuration required.
However you can create your own instances of specific `ISpeckleConverter`s through the assets in the Content, and then assign them to the converter component.
This can be done by right clicking and creating a new converter of a specified type.

<center>
  <img src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/create_converter.png?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=87f086968a4800028f50b978dc297a83" width="66.66%" data-path="images/legacy/unreal/create_converter.png" />
</center>

You can create your own custom converters in BP/C++ (see [Creating Custom Conversion](./unreal.html#creating-custom-conversion) docs)

### Mesh converters

Speckle-Unreal provides two types of mesh converters:

1. `ProceduralMeshConverter`([https://github.com/specklesystems/speckle-unreal/blob/main/Source/SpeckleUnreal/Public/Conversion/Converters/ProceduralMeshConverter.h](https://github.com/specklesystems/speckle-unreal/blob/main/Source/SpeckleUnreal/Public/Conversion/Converters/ProceduralMeshConverter.h)):
   * Creates a `UProceduralMeshComponent`.
   * Slightly faster to convert, and allow run-time editing of vertices/faces.
   * Slowest to render, can't use baked lighting.
2. `StaticMeshConverter`([https://github.com/specklesystems/speckle-unreal/blob/main/SpeckleUnrealProject/Plugins/SpeckleUnreal/Source/SpeckleUnreal/Public/SpeckleUnrealStaticMesh.h](https://github.com/specklesystems/speckle-unreal/blob/main/SpeckleUnrealProject/Plugins/SpeckleUnreal/Source/SpeckleUnreal/Public/SpeckleUnrealStaticMesh.h)):
   * Creates a `UStaticMeshComponent`.
   * Mesh vertices/faces/etc can't be edited easily (needs to be rebuilt).
   * Faster to render.
   * Built meshes can be saved as assets, allowing levels to be reloaded.
   * Additional Editor only build process allows for baked lighting, extra path-tracing options, and optimised lighting.

For most users we recommend using Static Meshes because they are more optimised for rendering and can be saved to a level.
Static Meshes can be used during runtime or editor mode, but editor only build process will only be available with editor access.

### Material converter

As a tool, Unreal shines when it comes to producing **beautiful, photorealistic renders** of scenes.
This has significant value for Speckle users as a tool for producing high quality and real-time demonstrations, animations, and XR experiences.

For some users, the simple flat shaded PBR materials converted using an object's `RenderMaterial`([https://github.com/specklesystems/speckle-sharp/blob/main/Objects/Objects/Other/RenderMaterial.cs](https://github.com/specklesystems/speckle-sharp/blob/main/Objects/Objects/Other/RenderMaterial.cs)) will be all they want.

Many users, however, want to use **textured materials**, after all, Unreal excels in photorealism, and high quality materials are a significant part of that.

**The Material Overrides feature** of the `MaterialConverter` addresses this need, as it enables a semi-automated workflow for applying textured materials to received geometry.

Speckle's `Objects`([https://speckle.guide/developers/objects.html](https://speckle.guide/developers/objects.html)) kit supports PBR materials through
the `RenderMaterial`([https://github.com/specklesystems/speckle-sharp/blob/main/Objects/Objects/Other/RenderMaterial.cs](https://github.com/specklesystems/speckle-sharp/blob/main/Objects/Objects/Other/RenderMaterial.cs)) property of Speckle meshes.
When receiving meshes with a `RenderMaterial`, the `MaterialConverter` will create a [`MaterialInstance`](https://docs.unrealengine.com/4.26/en-US/API/Runtime/Engine/Materials/UMaterialInstance/)s which are applied to converted meshes.

<Tip>
  Unreal has integration with [Quixel](https://quixel.com/)'s Megascans, a library of high-quality materials and assets that are free to use inside of Unreal Engine.
</Tip>

#### How are materials converted

The `MaterialConverter` exposes a few properties for defining the base/parent material of the materials created.
Opaque materials will be converted as instances of `BaseMeshOpaqueMaterial`.
And transparent materials will be converted as instances of `BaseMeshTransparentMaterial`.

By default, these base materials are simple materials with opaque/translucent shader models respectively.
Both have several properties exposed (see screenshot), and during the conversion process,
these properties are set with the values from the `RenderMaterial`.

The default opaque material "SpeckleMaterial", looks like this:

<Frame>
  <img src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/SpeckleMaterial.png?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=a8a570041a161ea248226b8228303b58" width="50%" alt="speckle material" data-path="images/legacy/unreal/SpeckleMaterial.png" />
</Frame>

And the default translucent material "SpeckleGlassMaterial", looks like this:

<Frame>
  <img src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/SpeckleGlassMaterial.png?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=a49998e1773cea0a91bfa2b0c13529df" width="50%" alt="speckle glass material" data-path="images/legacy/unreal/SpeckleGlassMaterial.png" />
</Frame>

These base materials are exposed as properties of the converter, and can be changed from within the editor (or from BP/C++) to a custom material.

#### Overriding/Substituting converted materials

Speckle does **not currently** support sending/receiving textured materials.
However, we do provide a way to automatically apply native Unreal materials while receiving objects from Speckle.

Converted materials can be overridden with custom materials in two ways.

* **By Name** - The `RenderMaterial.name` will be matched against materials in the `MaterialsOverridesByName` array.
* **By Id** - The `RenderMaterial.id` will be by key with materials in the `MaterailOverridesById` map.

<Frame>
  <img src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/OverridesById.png?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=3693eec4cb08d9dd7eb199824ac9f612" width="66.66%" alt="overrides by id" data-path="images/legacy/unreal/OverridesById.png" />
</Frame>

Screenshot of material overrides **By ID** in the details panel of the default `MaterialConverter` instance.
Materials with the ID `f5f7ebd4a...` will use this material instead of converting one from the object's `RenderMaterial`.

<Frame>
  <img src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/OverridesByName.png?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=2067ce626afa2af53c0df0052545e6e7" width="66.66%" alt="overrides by name" data-path="images/legacy/unreal/OverridesByName.png" />
</Frame>

Screenshot of material overrides **By Name** in the details panel of the default `MaterialConverter` instance..
Materials with the name `Mossy_Grass` will use this material instead of converting one from the object's `RenderMaterial`.

#### Material priorities

Material priority (high to low).

1. A material in `OverridesById` that matches by Id.
2. A material in `OverridesByName` that matches by Name.
3. A material cached from a previous receive operation.
4. A material asset in the `/Game/Speckle/Materials/{id}` package. (i.e. from a previous receive, but not cached, or from a strategically placed asset)
5. A material converted from `RenderMaterial` of the Mesh.
6. Finally, if all else fails, the `DefaultMaterial` set in the `MaterialConverter` will be used.

> Note: If there is no material on an object, we do not fall back to the parent's material like previous versions of this connector.
> We are aware this may cause unexpected behaviour. This issue will be addressed.

#### Limitations

* In order to use textured materials, meshes need to have **Texture coordinates** (UV coordinates). Currently, Texture coordinates are only outputted from Rhino, Blender, and Sketchup connectors. (More connectors will receive support shortly! see [issue](https://github.com/specklesystems/speckle-sharp/issues/797). The Unreal Connector does **not** generate texture coordinates for you.
  Having UV coordinates also has other advantages for baked lighting.
* **Textures cannot be sent/received through Speckle**, only flat colours and simple PBR properties. Texture support is on our roadmap, but there are several techincal chalanges to overcome before this is possible.

### Developing custom conversion logic

As previously mentioned, `ISpeckleConverter` classes can expose properties, such as the type of Actor to create, whether to create an asset, or build settings etc.

If this doesn't satisfy your needs, there are a few ways to further customise conversion.

1. You can extend an existing converter, and re-implement specific functions.
2. You can write a completely custom `ISpeckleConverter` class and add an instance to your `SpeckleConverterComponent`
3. You can extend the `SpeckleConverterComponent` to customise more generally how objects are converted and actors attached.

Converters can be created in either C++ or Blueprint.

#### Custom object models

Object Models in the Unreal plugin function the same as the Object Models in .NET.

Out of the box, the Speckle for Unreal plugin provides several Object Models.
These classes can be found in `speckle-unreal\Source\SpeckleUnreal\Public\Objects` and are all subclasses of the `UBase` type.
For the most part, these classes are direct ports of the corresponding .NET classes from our Objects kit.
For example `Mesh`, and `BlockInstance`.

An Object Model is required in order to convert Speckle objects.
If you are looking to convert a type that we don't provide an Object Model, creating one is simple.

This process is very similar to defining an object model in the .NET and PY SDKs,
But be aware of certain limitations:

1. The UE plugin **does not provide a reflection based (de)serializer**.
   Object Models implement their own (de)serialization logic in the form of manually parsing JSON properties.
2. **Only certain Object Models are provided** out of the box, while most are direct ports of Objects kit, some are not!
3. The Speckle Type is defined in the Object Model's constructor, not by its Namespace like in .NET.
4. Units are applied while parsing (rather than ToNative conversion - subject to change)

To implement your own Unreal Object Model, simply create a new class inheriting from `UBase`.
Add your properties, and implement the `Parse` method to set these properties from the JSON object.

```cpp theme={null}
bool UMyObjectModel::Parse(const TSharedPtr<FJsonObject> Obj, const TScriptInterface<ITransport> ReadTransport)
{
	if(!Super::Parse(Obj, ReadTransport)) return false;

	// Add your own JSON parsing here!
	// Remove explicit properties from DynamicProperties array
	
	// Simple example of parsing an optional number property:
	if(Obj->TryGetNumberField("myProperty", MyProperty)) DynamicProperties.Remove("myProperty");
	
	// Simple example of parsing an required number property:
	if(!Obj->TryGetNumberField("myProperty", MyProperty)) return false; // Return false on error, rather than fatal assertions
	DynamicProperties.Remove("myProperty");
	
	//Return true if parsed successfully
	return true;
}
```

For further reference, see `URenderMaterial` for an example, see `UMesh` for a more advanced example.
`UConversionUtils` provides helper methods for dechunking / dereferencing Speckle objects.

> Currently, Unit scaling is applied during Parsing (not conversion). This is subject to change!

In the future, we may consider creating a proper deserializer that uses reflection, this would mean Object Models can be deserialized  without developers having to write these Parse methods.
There are several technical challenges for us to solve before this is possible. <br />
Feel free to open a discussion on [our forums](https://speckle.community).

#### Creating converters (C++)

A custom converter can be defined by creating a `UObject` class that implements `ISpeckleConverter`.
You must implement the `ConvertToNative` and `CanConverToNative` methods.

```cpp theme={null}

UCLASS(BlueprintType, Blueprintable)
class SPECKLEUNREAL_API UMyConverter : public UObject, public ISpeckleConverter
{
	GENERATED_BODY()

public:
	virtual UObject* ConvertToNative_Implementation(const UBase* SpeckleBase, UWorld*, TScriptInterface<ISpeckleConverter>&) override;
	
	virtual bool CanConvertToNative_Implementation(TSubclassOf<UBase> BaseType) override;

}
```

Most likely, instead of jamming the actual conversion code in the `ConvertToNative` function, it is best to contain that in a separate function.
But this class can be implemented however you want!
The `AvailableConverters` parameter object is a reference to the master aggregate  converter, and we can use this if we need to convert other Speckle Objects, and want to reuse conversion logic from another converter.
The `StaticMeshConverter` for example, will use the `AvailableConverters` to convert a `RenderMaterial`.

```cpp theme={null}
UObject* UMyConverter::ConvertToNative_Implementation(const UBase* SpeckleBase, UWorld* World, TScriptInterface<ISpeckleConverter>& AvailableConverters)
{
	const UMyObjectModel* m = Cast<UMyObjectModel>(SpeckleBase);
	
	if(m == nullptr) return nullptr;
	
	return MyObjectToNative(m);
}

AActor* UMyConverter::MyObjectToNative(const UMyObjectModel* MyObject, UWorld* World)
{
	// Conversion logic here!!
	// Convert MyObject into an Actor that we return
}
```

An optional `CleanUp` method can be implemented, which is used to clear any cached objects / any additional clean up that needs to be done between receive operations.

#### Creating converters (Blueprint)

In the same way as with C++, converters can also be implemented using Blueprint.
First create a new Blueprint Inheriting `UObject`

<Frame>
  <img src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/new_blueprint.png?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=b958cc33487331e5f1ada04aa025dcff" width="50%" alt="Screenshot of the blueprint creation menu, creating a new blueprint of type UObject" data-path="images/legacy/unreal/new_blueprint.png" />
</Frame>

Under *Class Settings* add `ISpeckleConverter` to the *Implemented Interfaces* list.

<Frame>
  <img src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/bp_speckle_converter_interface.png?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=30c3ac6374f6e6de8fc3674962db5319" width="50%" alt="Screenshot of the blueprint details, showing adding ISpeckleConverter as an implemented interface" data-path="images/legacy/unreal/bp_speckle_converter_interface.png" />
</Frame>

Finally, implement your conversion logic in the required functions.

<Frame>
  <img src="https://mintcdn.com/speckle-assistant/fqa23GjG0dFWAgwW/images/legacy/unreal/bp_functions.png?fit=max&auto=format&n=fqa23GjG0dFWAgwW&q=85&s=0060609f9a8aa5001744c55ee4c08c74" width="50%" alt="Screenshot of blueprint editor, showing the interface functions" data-path="images/legacy/unreal/bp_functions.png" />
</Frame>
