# 数据传输对象 (DTO)

> Define data transfer objects to transfer data between client and server.

您可以在模块中定义数据传输对象。DTO 可用于在客户端和服务器之间传输数据。

例如，可以使用 DTO 将模块数据序列化为 JSON，并在客户端将其反序列化为相同的结构。

> **Important:**
>
> **重要**：您可以从 Unity 编辑器生成绑定，以使用类型安全 (type-safe) 的客户端代码调用模块终端。对于大多数用例，您不需要在 Unity 项目中手动创建 DTO。如需了解更多信息，请参阅[使用编辑器绑定](../run-modules/unity-runtime#use-editor-bindings)。

## 先决条件##prerequisites

在开始使用 DTO 之前，请创建一个 [Cloud Code 模块](../../getting-started)。

## 管理 DTO##manage-dtos

您可以定义 DTO 来捕获模块终端函数的数据类型。

### 创建和配置 DTO 项目##create-and-configure-your-dto-project

首先，请创建一个 C# 项目来存储 DTO，并在主项目中添加对该项目的引用。请参阅 Microsoft 文档，了解如何[管理项目中的引用](https://learn.microsoft.com/en-us/visualstudio/ide/managing-references-in-a-project?view=vs-2022)。

如需了解有关模块的更多信息，请参阅[模块结构](../module-structure)。

接下来，必须将 DTO C# 项目配置为在 Unity 编辑器中使用受支持的运行时 .NET 版本，即 `netstandard`。

打开 `<project_name>.csproj` 文件，然后更改 `TargetFramework`。如果使用 Unity 2021.2.0，则为 `netstandard.2.1`。

如需了解更多信息，请参阅 Unity 手册中的[支持的 .NET 版本](https://docs.unity3d.com/2021.2/Documentation/Manual/dotnetProfileSupport.html)。

您还需要禁用隐式使用。请参阅下面的 C# 项目配置示例：

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

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

</Project>
```

### 将 DTO 添加到模块##add-the-dtos-to-your-module

要将 DTO 添加到您的模块，您需要在项目中定义一个新类来存储您的 DTO。这可能类似于以下示例：

```csharp
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; }
    }
}
```

### 在模块逻辑中使用 DTO##use-dtos-in-your-module-logic

在包含模块函数的主项目中，定义游戏逻辑，并使用定义的 DTO 作为函数返回类型。

下面是简单模块终端的一个示例：

```csharp
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:**
>
> **注意**：还可以使用 DTO 作为函数参数进行输入。

### 提取 DLL##extract-the-dlls

为了在 Unity 项目中使用 DTO 来匹配响应类型，需要从模块 C# 项目中提取 DLL。

应为此步骤[部署模块](../../getting-started#deploy-the-module)，以便以后能够调用模块函数。

如果是手动打包，请参阅[打包代码](../package-code)以了解更多有关如何生成程序集的信息。

如果在部署模块时生成程序集，默认情况下，您可以在模块项目的 `bin/Debug/Release/net6.0/linux-x64/publish` 文件夹中找到 DLL。

您的程序集类似于以下示例：

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

复制 `DTOs.dll` 文件。

### 将 DLL 导入 Unity 项目##import-the-dlls-to-unity-project

要在游戏中使用外部 DLL，请将 DLL 放在 Unity 项目的 `Assets` 目录中。

Unity 编辑器下次在同步项目时将添加必要的 DLL 引用。

如需了解更多信息，请参阅 Unity 手册中的[托管插件](https://docs.unity3d.com/Manual/UsingDLL.html)。

### 在 Unity MonoBehaviour 脚本中重用 DTO##reuse-the-dtos-in-a-unity-monobehaviour-script

您可以调用 Cloud Code SDK，并使用相同的 DTO 对响应进行反序列化：

```csharp
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}");
    }
}
```

请参考以下成功响应的示例：

```text
"You rolled 5 / 6"
```

如需了解更多信息，请参阅[从 Unity Runtime 运行模块](../run-modules/unity-runtime)。
