Data transfer objects (DTOs)

You can define data transfer objects in your modules. You can use DTOs to transfer data between the client and the server.

For example, you can use DTOs to serialize your module data to JSON, and deserialize it into the same structure on the client side.

Important: You can generate bindings from the Unity Editor to call the module endpoints using type-safe client code. For most use cases, you don't need to manually create DTOs in your Unity project. For more information, refer to Using editor bindings.

Prerequisites

Before you get started with DTOs, create a Cloud Code module.

Manage DTOs

You can define DTOs to capture data types for your module endpoint functions.

Create and configure your DTO project

To get started, create a C# project to store your DTOs in, and add a reference to it from your main project. Refer to the Microsoft documentation on how to Manage references in a project.

For more information on modules, refer to module structure.

Next, you have to configure your DTO C# project to use a supported runtime .NET version in Unity Editor, which is netstandard.

Open the <project_name>.csproj file, and change the TargetFramework. If you use Unity 2021.2.0, this is netstandard.2.1.

For more information, refer to the Unity manual supported .NET versions.

You also need to disable implicit usings. Refer to the example C# project configuration below:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>netstandard2.1</TargetFramework>
        <ImplicitUsings>disable</ImplicitUsings>
        <RootNamespace>DTOSample</RootNamespace>
    </PropertyGroup>

</Project>

Add the DTOs to your module

To add DTOs to your module, you need to define a new class in your project to store your DTOs. This can be similar to the following example:

namespace DTOSample
{
    public class DiceRollDto
    {
        public DiceRollDto(int roll, int sides)
        {
            Roll = roll;
            Sides = sides;
        }

        public int Roll { get; set; }
        public int Sides { get; set; }
    }
}

Use DTOs in your module logic

In your main project with module functions, define your game logic, and use the defined DTO as the function return type.

The following is an example of a simple module endpoint:

using DTOSample;
using Unity.Services.CloudCode.Core;

namespace Sample;

public class HelloWorld
{
    [CloudCodeFunction("RollDice")]
    public async Task<DiceRollDTO> RollDice(int diceSides)
    {
        var random = new Random();
        var roll = random.Next(1, diceSides);

        return new DiceRollDTO(roll, diceSides);
    }

}

Note: You can also use DTOs for input as function parameters.

Extract the DLLs

To use the DTOs in your Unity project to match the response type, you need to extract the DLLs from the module C# project.

You should deploy your module for this step to be able to call the module function later.

For manual packaging, refer to package code for more information on how to generate the assemblies.

If you generate the assemblies when you deploy your module, by default, you can find the DLLs in the bin/Debug/Release/net6.0/linux-x64/publish folder of your module project.

Your assemblies be similar to the following example:

├─ Main.csproj
    └─ bin
        └─ Debug
            └─ Release
                └─ net6.0
                    └─ linux-x64
                        └─ publish
                            └─ Main.dll
                            └─ Main.pdb
                            └─ DTOs.dll
                            └─ DTOs.pdb
                            ...

Copy the DTOs.dll file.

Import the DLLs to Unity project

To use an external DLL in your game, place the DLL inside your Unity project in the Assets directory.

The next time the Unity Editor synchronizes the project, the Editor adds the necessary references to the DLLs.

For more information, refer to Managed plug-ins in the Unity manual.

Reuse the DTOs in a Unity MonoBehaviour script

You can call out to Cloud Code SDK and use the same DTOs to deserialize the response:

using DTOSample;
using UnityEngine;
using Unity.Services.Authentication;
using Unity.Services.CloudCode;
using Unity.Services.Core;

public class Test : MonoBehaviour
{
    // Call this method to roll the dice (use a button)
    public async void Awake()
    {
        await UnityServices.InitializeAsync();
        // Sign in anonymously to the Authentication service
        if (!AuthenticationService.Instance.IsSignedIn) await AuthenticationService.Instance.SignInAnonymouslyAsync();

        // Call out to the Roll Dice script in Cloud Code
        var response = await CloudCodeService.Instance.CallModuleEndpointAsync<DiceRollDto>("Main", "RollDice", new Dictionary<string, object>()
        {
            {"diceSides", 6}
        });

        // Log the response of the script in console
        Debug.Log($"You rolled {response.Roll} / {response.Sides}");
    }
}

Use the following example of a successful response for reference:

"You rolled 5 / 6"

For more information, refer to running modules from Unity Runtime.