# TransportSurface

The TransportSurface component simulates conveyor belts and transport systems for moving objects through industrial automation processes. It provides physics-based movement of objects along defined transport paths, supporting both linear conveyors and rotational systems like turntables.

For modeling conveyor systems with [MU](https://doc.realvirtual.io/components-and-scripts/mu-movable-unit) (Movable Units), TransportSurface provides the essential physics foundation.

> ⚠️ **Note**:\
> For **standard speed-controlled accumulation conveyor systems**, you should use the **purely physics-based approach** with `TransportSurface`.
>
> \
> However, if this approach becomes unstable or imprecise—especially in **position-controlled systems** (e.g., driven by PLCs)—consider switching to a **guided transport** setup:
>
> * Use [`GuidedTransport`](https://doc.realvirtual.io/components-and-scripts/motion/guided-transport) for force-based control.
> * Use [`KinematicMU`](https://doc.realvirtual.io/components-and-scripts/motion/kinematicmu-pro) for fully position-controlled, kinematic movement without violating physics constraints.

A Transport Surface is always connected to a [Drive](https://doc.realvirtual.io/components-and-scripts/motion/drive) which controls the speed and position. The TransportSurface automatically detects and connects to Drive components in the parent hierarchy.

{% hint style="info" %}
If you are seeing instability with drives please check [#physic-solver-settings](https://doc.realvirtual.io/basics/physics#physic-solver-settings "mention") as well as [#stability-of-transportsurfaces](https://doc.realvirtual.io/basics/physics#stability-of-transportsurfaces "mention")in Section [physics](https://doc.realvirtual.io/basics/physics "mention").
{% endhint %}

## Setup

### Basic Configuration

1. Add your conveyor GameObject with geometry (mesh or simple box)
2. Add a [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) component to control movement direction and speed
3. Add `TransportSurface` component - it automatically connects to the Drive

The TransportSurface automatically detects and connects to [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) components in parent objects.

{% embed url="<https://youtu.be/9tHzIFpkDnI>" %}

## Properties

### Core Properties

**Drive Reference** ([`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive)): Optional override for automatic drive detection. Leave empty (null) for standard usage - the system automatically finds parent [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) components. Use for special cases requiring specific drive connections.

**Layer** (string): Physics layer assignment (default: "rvTransport") for transport simulation physics calculations.

**Use Mesh Collider** (boolean): Controls collision precision vs performance. BoxCollider (default) provides better performance. MeshCollider enables precise collision for complex geometry. Changes apply immediately in Unity Inspector.

### Visual Properties

**Advanced Surface** (boolean): Enables belt visualization with animated textures. Works with all geometry configurations including kinematic groups.

**Animate Surface** (boolean): Enables texture animation synchronized with transport speed.

**Texture Scale** (float): Texture animation speed multiplier in texture units per meter.

### Constraint Management

**Change Constraints On Enter/Exit** (boolean): Modifies rigidbody constraints when objects enter/leave the transport surface.

### Hierarchical Systems

**Parent Drive** ([`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive)): For multi-axis systems where the transport surface moves relative to a parent drive (turntables, lifting conveyors).

## Collider Handling

TransportSurface handles collision detection automatically - it uses existing colliders when available, or creates them automatically when needed.

### Collider Management

**Existing Colliders**: If the TransportSurface GameObject already has colliders (BoxCollider or MeshCollider), they are used directly.

**Kinematic Group Integration**: If the TransportSurface has a [`Kinematic`](https://github.com/game4automation/doc/blob/doc/components-and-scripts/kinematic.md) component with group integration enabled:

* First searches for existing colliders within the kinematic group
* If existing group colliders are found, they are reused for optimal performance
* If no group colliders exist, creates a combined MeshCollider based on all meshes in the entire kinematic group

**Automatic Creation**: If no colliders exist and no kinematic groups are configured, TransportSurface automatically creates them at runtime using this system:

1. **Standard Collision**
   * **BoxCollider** (Default): Fast, reliable collision for most conveyors
   * **MeshCollider** (Precise): Accurate collision matching for complex shapes
   * Automatically calculates the right size from your geometry
2. **Fallback**
   * Creates basic collision even when geometry is missing
   * Keeps your simulation running with warnings
   * Prevents common "objects fall through" issues

{% hint style="info" %}
**Collider Strategy**: TransportSurface respects your existing collider setup. If you've manually added colliders to the GameObject, they will be used as-is. Automatic creation only happens when no colliders are found.
{% endhint %}

### Editor-Time Collider Switching

When you toggle the **Use Mesh Collider** property in the Unity Inspector, the collider type switches immediately:

* Provides visual feedback during development
* Only affects the TransportSurface GameObject
* Automatically handles component cleanup and creation

### Layer Management

All transport surface colliders are automatically assigned to the **rvTransport** layer for physics calculations. The system validates layer assignments and warns about configuration issues that could affect performance.

{% hint style="success" %}
**Best Practice**: For complex CAD-imported conveyor systems, use the [`Kinematic`](https://github.com/game4automation/doc/blob/doc/components-and-scripts/kinematic.md) component with group integration. This improves performance by sharing colliders across grouped objects.
{% endhint %}

## Advanced Surface

The **Advanced Surface** option enables enhanced visual representation that now works with all geometry configurations:

**Universal Geometry Support:**

* **Simple Objects**: Uses direct MeshRenderer/MeshFilter components
* **Kinematic Groups**: Automatically handles distributed geometry across grouped objects using [`Kinematic`](https://github.com/game4automation/doc/blob/doc/components-and-scripts/kinematic.md) components
* **Complex Hierarchies**: Works with any renderer configuration in child objects

When **Advanced Surface** is enabled, a child GameObject named **Belt** is created under the `TransportSurface`. This includes the `ConveyorBelt` component with animated texture effects that accurately follow surface geometry—including curves.

The system automatically:

* Calculates bounds from any geometry configuration (direct mesh, kinematic groups, or child renderers)
* Hides original renderers appropriately based on the geometry setup
* Provides error recovery if the ConveyorBelt prefab is missing
* Handles both editor and runtime scenarios safely

<figure><img src="https://260262196-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpYxFg97YnJX96UzNNTSd%2Fuploads%2Fgit-blob-a6b52da0c01d085ebf3a1386ae2fee383723ced5%2FTransportSurface-Advanced.gif?alt=media" alt=""><figcaption><p>Advanced Surface with enhanced geometry support</p></figcaption></figure>

<figure><img src="https://260262196-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpYxFg97YnJX96UzNNTSd%2Fuploads%2Fgit-blob-ad82228fdf05d5375e36774508cd1b3b145382fd%2FTextrueTransportSurface.gif?alt=media" alt=""><figcaption><p>Advanced Surface texture animation</p></figcaption></figure>

## Connecting Drives to Transport Surfaces

TransportSurface features **automatic Drive detection** that makes setup effortless and intuitive:

### Automatic Drive Connection

When you add a TransportSurface component:

1. **Flexible Drive Placement**: [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) component can be on the same GameObject as TransportSurface or on any parent GameObject in the hierarchy
2. **Automatic Discovery**: The system automatically searches the current GameObject and then up the hierarchy for [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) components
3. **Connection**: Found [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) components are linked to the TransportSurface
4. **Visual Feedback**: The connection is visible in the Unity Inspector
5. **Automatic Setup**: Works for standard conveyor configurations

{% hint style="info" %}
**Drive Placement Options**:

* **Same Level**: [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) and TransportSurface on the same GameObject (simplest setup)
* **Hierarchical**: [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) on parent GameObject, TransportSurface on child GameObject (common for complex systems)
  {% endhint %}

<figure><img src="https://github.com/game4automation/doc/blob/doc/.gitbook/assets/Unity_bGxeoD3LEf.png" alt=""><figcaption><p>Automatic Drive connection shown in Unity Inspector</p></figcaption></figure>

### Drives above the TransportSurface Drive - using parent Drives <a href="#transport-surfaces-and-unity-physics" id="transport-surfaces-and-unity-physics"></a>

{% hint style="info" %}
*ParentDrives* is only needed if *IsKinematic* Drives are moving *TransportSurfaces* in a linear direction or rotational direction, e.g. for turn tables or lifting devices.
{% endhint %}

Sometimes Unity Physics is very difficult and the solution to master it is a little bit weird. As described in [Physics](https://doc.realvirtual.io/basics/physics) normal movements of a linear or rotational axis are not done based *IsKinematic* Rigidbodies. The transformation is done based on the Unity hierarchy and the position of [Unity’s Transform](https://docs.unity3d.com/ScriptReference/Transform.html) because this is usually much more stable.

{% hint style="info" %}
The Transport Surface is different from normal linear or rotational movements of an axis. It is using pure Unity physics functions for transporting the [MUs](https://doc.realvirtual.io/components-and-scripts/mu-movable-unit).
{% endhint %}

This causes one problem. If it is for example necessary to combine a linear or rotational movement with the Transport Surface itself this will cause problems. Unity will not move the Transport Surface [Collider](https://docs.unity3d.com/ScriptReference/Collider.html) as expected.

To prevent this the option *ParentDrive* is available on the Transport Surface:

<div align="left"><figure><img src="https://260262196-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpYxFg97YnJX96UzNNTSd%2Fuploads%2Fgit-blob-7563e51995dce70e1cd192f5e2e398788c23ef60%2FTransportSurfaceParent.png?alt=media" alt=""><figcaption></figcaption></figure></div>

This option will automatically decouple the Transport Surface upon simulation start and will make a function as expected possible. During simulation, the Transportsurface will be without a parent in the top level of the hierarchy. You can see an example in the Demo model TurningAndLiftingTransportSurface which can be found under *realvirtual.io > Scenes*:

<figure><img src="https://260262196-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpYxFg97YnJX96UzNNTSd%2Fuploads%2Fgit-blob-740cfdb0e0212654ad4181d9c5ed6096facbce99%2Ftransportsurface-decoupled.png?alt=media" alt=""><figcaption></figcaption></figure>

When you build up more complex kinematic structures, make sure to always keep the gameobject with the component transport surface parallel to the kinematic structure of the other drive belonging to the surface. An further expample model is MovingTransportSurface which can also be found under *realvirtual.io > Scenes.* The picture below shows how to define such a structure. The parent drive of the transport surface is the one which is the lowest in the kinematic structure.

<figure><img src="https://260262196-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpYxFg97YnJX96UzNNTSd%2Fuploads%2Fgit-blob-71b2d885d68a4a2b7e7995da07a217ffff505dce%2FTransportSurfaceParent2.png?alt=media" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If the parent drive of the transport surface is rotating, the pivot points (centre of rotation) of both objects must be in the same position for the movement to be transmitted correctly. If necessary, an empty GameObject must be inserted to achieve this.
{% endhint %}

### Constraints of transported Objects

You can choose if the constraints of objects which enter the transportsurface have to be changed or not. Setting the boolean *ChangeConstraintsOnEnter* or *ChangeConstraintsOnExit* to true will give the possibility to that.

<div align="left"><figure><img src="https://260262196-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpYxFg97YnJX96UzNNTSd%2Fuploads%2Fgit-blob-32201fcb8857c139e260966d0bf14b06f600e645%2FTransportSurfaceConstraint.png?alt=media" alt=""><figcaption></figcaption></figure></div>

{% hint style="warning" %}
*When you change the constraints they will not be set back automatically to the former settings when the object leaves the transport surface. There you have to set ChangeConstraintsOnExit* true and define the values. Choosing *"None"* all contraints will be removed from the object.
{% endhint %}

## Troubleshooting

### Objects Fall Through Transport Surface

**Symptoms**: [MUs](https://doc.realvirtual.io/components-and-scripts/mu-movable-unit) pass through the conveyor instead of being transported

**Solution**: Check the layer assignment in the Inspector - should be "rvTransport"

**Causes and Solutions**:

* **Layer Mismatch**: Click on the TransportSurface GameObject, check Layer dropdown in Inspector
* **Missing Collider**: Enable "Use Mesh Collider" for complex geometry, or verify BoxCollider exists
* **Kinematic Group Issues**: Ensure all CAD parts use the same `GroupName` in their [`Group`](https://github.com/game4automation/doc/blob/doc/components-and-scripts/group.md) components

**Note**: Use automatic setup to avoid manual collider creation which can cause layer issues

### Poor Performance with Complex CAD Models

**Symptoms**: Frame drops, sluggish physics, or slow conveyor response

**Solution**: Add [`Kinematic`](https://github.com/game4automation/doc/blob/doc/components-and-scripts/kinematic.md) component and enable `IntegrateGroupEnable`

**Performance Optimization Steps**:

1. Add [`Kinematic`](https://github.com/game4automation/doc/blob/doc/components-and-scripts/kinematic.md) component to the TransportSurface GameObject
2. Set `IntegrateGroupEnable = true`
3. Assign the same `GroupName` to all related CAD objects
4. Switch to BoxCollider if MeshCollider isn't essential

**Performance Impact**: Can improve simulation speed by 10x for complex CAD assemblies

### AdvancedSurface Not Working

**Symptoms**: Enhanced belt visuals don't appear or have wrong dimensions

**Diagnosis**: Check Console for "ConveyorBelt prefab not found" errors

**Solutions by Cause**:

* **Missing Prefab**: ConveyorBelt prefab must exist in Resources folder
* **No Geometry Bounds**: Add Renderer components or verify kinematic group setup
* **Kinematic Group Issues**: Check that group names match across all [`Group`](https://github.com/game4automation/doc/blob/doc/components-and-scripts/group.md) components

**Note**: Test AdvancedSurface with simple geometry first, then apply to complex models

### Drive Connection Issues

**Symptoms**: Conveyor doesn't move, speed not synchronized, or no movement response

**Solution**: Check that [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) component exists on the same GameObject or parent GameObjects

**Connection Troubleshooting**:

1. **Drive Placement**: [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) must be on the same GameObject as TransportSurface OR on a parent GameObject (not sibling objects)
2. **Multiple Drives**: Set **Drive Reference** property to specify which [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) to use
3. **Drive Configuration**: Verify [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) component is enabled and properly configured
4. **Hierarchy Check**: Ensure TransportSurface can "see" the [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) in its hierarchy path

**Note**: Use supported hierarchy structures:

* **Simple**: [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) + TransportSurface on same GameObject
* **Hierarchical**: [`Drive`](https://doc.realvirtual.io/components-and-scripts/motion/drive) (parent) → TransportSurface (child or descendant)

{% hint style="success" %}
**Performance Tip**: For large-scale transport systems, group related CAD objects using the [`Kinematic`](https://github.com/game4automation/doc/blob/doc/components-and-scripts/kinematic.md) component. This eliminates individual colliders and can improve performance by 10x.
{% endhint %}

© 2025 realvirtual [https://realvirtual.io](https://realvirtual.io/) - All rights reserved. No part of this publication may be reproduced, distributed, or transmitted in any form or by any means, including printing, saving, photocopying, recording, or other electronic or mechanical methods, without the prior written permission of the publisher.
