# 与 Unity 编辑器集成

> Author and modify Cloud Code scripts directly within the Unity Editor using the Cloud Code Authoring module.

Cloud Code Authoring 模块（随 Cloud Code 包一起安装）允许您选择直接在 Unity 编辑器中创作和修改脚本。然后，您可以使用 [Deployment 包](https://docs.unity3d.com/Packages/com.unity.services.deployment@latest)将脚本从 Unity 编辑器上传到 Unity Dashboard。

> **Note:**
>
> 仅 Unity 2021.3 及更高版本支持在 Unity 编辑器中创作脚本。

Unity 编辑器中存在的脚本允许用户将他们的源代码管理系统视为单一数据源（而不是使用云中的版本），从而简化回滚、两等分和其他常见操作。例如，Cloud Code Authoring 模块有助于执行诸如使客户端 C# 脚本与 Cloud Code 脚本保持同步等任务。

## 先决条件##prerequisites

要在 Unity 编辑器中使用 Cloud Code，必须先安装 Cloud Code SDK，并将 [Unity Gaming Services（Unity 游戏服务）项目](/cloud/projects.md)关联到 Unity 编辑器。

### 关联项目##link-project

将 [Unity Gaming Services（Unity 游戏服务）项目](/cloud/projects.md)与 Unity 编辑器关联。您可以在 Unity Dashboard 中找到您的 UGS Project ID。

1. 在 Unity 编辑器中，选择 **Edit（编辑）**> **Project Settings（项目设置）**> **Services（服务）**。

2. 关联您的项目。

   * 如果项目没有 Unity Project ID：

     1. 选择 **Create a Unity Project ID（创建 Unity Project ID）**> **Organizations（组织）**，然后从下拉菜单中选择一个组织。
     2. 选择 **Create project ID（创建 Project ID）**。

   * 如果已有 Unity Project ID：

     1. 选择 **Use an existing Unity project ID（使用现有 Unity Project ID）**。
     2. 从下拉菜单中选择组织和项目。
     3. 选择 **Link project ID（关联 Project ID）**。

此时将显示您的 Unity Project ID，并且项目现在已关联到 Unity 服务。此外，还可以使用 `UnityEditor.CloudProjectSettings.projectId` 在 Unity 编辑器脚本中访问您的 Project ID。

### 安装所需的包##install-required-packages

要在编辑器中创建 Cloud Code 脚本，必须安装以下包：

* Deployment
* Cloud Code（2.1.1 或更高版本）

> **Note:**
>
> 请查看 [Unity - 手册：Package Manager（包管理器）窗口](https://docs.unity3d.com/Manual/upm-ui.html)，熟悉 Unity Package Manager（包管理器）界面。

安装这些包并将它们添加到可用包列表中：

1. 在 Unity 编辑器的 Package Manager（包管理器）窗口中，选择 **+（添加）**> **Add package by name...（按名称添加包...）**。
2. 输入 `com.unity.services.deployment`。
3. 选择 **Add（添加）**。
4. 对 `com.unity.services.cloudcode` 重复以上步骤。

## 在 Unity 编辑器中创作##authoring-within-unity-editor

借助 Cloud Code Authoring 模块，您可以直接在 Unity 编辑器中创建、编辑和部署 Cloud Code 脚本。

### 创建脚本##create-a-script

按照以下步骤使用 Cloud Code Authoring 模块创建 Cloud Code 脚本：

1. 在 Unity 编辑器的 Project（项目）窗口中右键单击，然后选择 **Create（创建）**> **Services（服务）**> **Cloud Code Js Script（Cloud Code Js 脚本）**。
2. 像命名 C# 脚本一样命名该脚本。上传到服务时，Cloud Code 脚本会使用其文件名作为标识符。
3. 按 **Enter（输入）**。

> **Note:**
>
> Cloud Code 对您可以使用的标识符名称有限制。要确保您的文件正确上传，请参阅[创建脚本](./unity-dashboard.md#create-a-script)。

现在，新脚本会显示在 Project（项目）窗口和 Deployment（部署）窗口中；可通过选择 **Window（窗口）**> **Deployment（部署）** 来访问 Deployment（部署）窗口。

### 编辑脚本##edit-a-script

有两种方法可以编辑现有的 Cloud Code Authoring 脚本：

* 在 Project（项目）选项卡中，双击现有脚本。
* 在 Deployment（部署）窗口中，找到现有脚本，然后从右键单击菜单中选择 **Open（打开）**。

默认情况下，您的 Cloud Code 脚本会在默认的 JavaScript 编辑器中打开。

要设置默认的 JavaScript 编辑器，请执行以下操作：

1. 在 Unity 编辑器中，选择 **Edit（编辑）**> **Preferences...（偏好设置...）**> **Cloud Code**。
2. 在 Javascript Editor（Javascript 编辑器）部分中，选择所需的 JS 编辑器的应用程序路径。
3. 选择 **Apply（应用）**。

在进阶情况下，可以指定以下参数：

* `$(File)`：资源的文件路径
* `$(ProjectPath)`：项目目录
* `$(SolutionPath)`：解决方案路径
* `$(EditorExePath)`：编辑器可执行文件路径（在 Unity 编辑器中选择 **Edit（编辑）**> **Preferences...（偏好设置...）**> **External Tools（外部工具）**）

下面列出了一些可能的设置示例：

* JetBrains Rider（在 Windows 上）：

  * 应用程序：`cmd.exe`
  * 参数：`/C "$(EditorExePath) $(ProjectPath) $(File)"`

* Microsoft Visual Studio Code：

  * 应用程序：`Code.exe`
  * 参数：`$(ProjectPath) $(File)"`

### 部署脚本##deploy-a-script

您可以通过 Deployment（部署）窗口部署脚本。请查看 [Deployment 包手册](https://docs.unity3d.com/Packages/com.unity.services.deployment@latest)以了解更多信息。

## 修改脚本参数##modify-script-parameters

您可以在 Unity 编辑器中访问和修改 Cloud Code 脚本参数。

### 在编辑器的 Inspector（检视面板）窗口中访问参数##access-parameters-in-the-editors-inspector-window

您可以通过在 Unity 编辑器的 Project（项目）窗口中选择 Cloud Code 脚本来修改脚本的参数。脚本的参数会在编辑器的 Inspector（检视面板）窗口中打开。

> **Important:**
>
> 更改脚本的参数可能会使现有游戏客户端不兼容。客户端可能会发送不兼容的参数，或者不发送必需的参数。

可能的参数类型包括：

* String（字符串）
* Boolean（布尔值）
* Numeric（数值）
* JSON
* Any（任意）

> **Note:**
>
> [Inspector（检视面板）](https://docs.unity3d.com/Manual/UsingTheInspector.html)对参数编辑功能的支持有限；UGS CLI 无法读取这些参数。如果要同时使用编辑器和 CLI，请[在脚本中使用参数](#declare-parameters-in-the-script-body)。

### 在脚本正文中声明参数##declare-parameters-in-the-script-body

为了获得更顺畅的 Cloud Code 脚本使用体验，您可以直接在脚本中声明参数，方法是导出 `params` 对象，然后在其中添加每个参数名称作为键，并将参数类型作为值。

> **Warning:**
>
> **重要**：在设置参数之前，必须分配 `module.exports` 属性。

> **Warning:**
>
> **重要**：您必须使用 NodeJS 设置您的 Cloud Code JS 开发环境才能启用内联脚本参数。如需更多详细信息，请参阅 [JavaScript 项目创作指南](https://docs.unity3d.com/Packages/com.unity.services.cloudcode@latest/index.html?subfolder=/manual/Authoring/javascript_project.html)。

> **Warning:**
>
> **重要**：Unity Dashboard 目前不支持脚本内参数。

例如：

*JavaScript*

```js
module.exports.params = { "echo" : "Boolean" }
```

或者，如果要指定某个参数为必需参数，可以指定一个同时包含 `type` 和 `required` 属性的对象。

*JavaScript*

```js
module.exports = async ({ params, context, logger }) => {
    return {
        "value": params["aParam"]
    };
};

module.exports.params = { "aParam" : { "type": "String", "required": true } }
```

默认情况下，参数不是必需参数。

两种格式可以根据需要组合使用：

*JavaScript*

```js
module.exports = async ({ params, context, logger }) => {
    var value = params["echo"] ? params["aParam"] : "default";
    return {
        "value": value
    };
};

module.exports.params = {
  "echo" : "Boolean",
  "aParam" : { "type": "String", "required": true }
 }
```

如果使用脚本内参数，这些参数会覆盖以前定义的 Inspector（检视面板）参数。

脚本内参数提供了一种比声明参数更简单的替代方法，但如果您尝试在不使用 Deployment 包的情况下更新脚本内参数，Unity Dashboard 目前不会解析这些参数。

## JS 捆绑包##js-bundles

> **Note:**
>
> com.unity.services.cloudcode\@2.3.0 支持 JS 捆绑，但 UGS 命令行界面尚不支持。

JS 脚本可以导入带有 `import` 或 `require` 关键字的本地脚本或外部模块。捆绑过程使用脚本作为输入，并将捆绑结果提供给 Unity Dashboard。此过程不会修改本地文件。

要在脚本上启用捆绑，请导出 `bundling` 对象并将值设置为 true。此过程是根据每个脚本进行的。默认情况下不会捆绑脚本。如果已启用捆绑，则会在部署之前通过 [Deployment（部署）窗口](#deployment-window)捆绑脚本。

> **Important:**
>
> 在设置捆绑选项之前，必须分配 module.exports 属性。

*JavaScript*

```js
module.exports.bundling = true;
```

以下示例演示了在示例项目中使用捆绑的情况。

*lib.js*

```js
module.exports.helloWorld = "Hello world!";

```

*scriptToBundle.js*

```js
const lib = require("./lib");

module.exports = async ({ params, context, logger }) => {
    return {
        "value": lib.helloWorld
    };
};

module.exports.bundling = true;
```

## Deployment（部署）窗口##deployment-window

Deployment（部署）窗口是 Deployment 包的一项核心功能。此窗口旨在让所有服务使用一个统一的界面来满足部署需求，并可以将云资源上传到其各自的云服务。

请查看 [Deployment 包手册](https://docs.unity3d.com/Packages/com.unity.services.deployment@latest)以了解更多信息。

## Unity 编辑器中的 Cloud Code JavaScript 项目##cloud-code-javascript-projects-in-the-unity-editor

Unity 编辑器中的 Cloud Code JavaScript 项目位于 Unity 项目的根目录下，具有以下结构：

├── `Assets`\
│ └── `CloudCode`\
│ └── `cloud_script.js`\
├── `node_modules`\
├── `package.json`\
└── `package-lock.json`

`package.json` 中存储项目配置。此文件由 JavaScript (JS) 编辑器和 NPM 使用，其作用类似于 C# 使用 .csproj 文件类型来定义 Unity 编辑器的信息。请注意，JavaScript 项目系统中使用的这些 `package.json` 文件不是 Unity 包，而是 NPM 包。Unity 和 NodeJS 使用相同的包管理系统只是巧合。

`package-lock.json` 由 NPM 生成，用于解析依赖项。建议将此文件保留在源代码管理系统中，以便始终以相同的方式解析依赖项。

### NodeJS##nodejs

为了支持更多开发者工具，开发者必须安装 [NodeJS](https://nodejs.org/en/)。借助 NodeJS 可以支持自动补全功能和开发环境的其他预期功能。

### 自动补全##autocomplete

JS 的大部分自动补全功能由 [typings](https://github.com/typings/registry) 项目处理。您可以使用 `.d.ts` 文件来定义 typed API，从而扩充 JavaScript 文件。大多数公共 JS 库要么包含自己的 `.d.ts` 文件，要么在 typings 中定义了一些文件。

要使编辑器为依赖项启用自动补全功能，编辑器需要能够找到依赖项的类型定义。为此，编辑器会查看 `node_modules`。要启用自动补全功能，必须使用 `package.json` 文件将正确的文件安装到 `node_modules`。

### 外部工具##external-tools

您可以通过从 JS 项目中运行相应的 `npm install ...` 命令来添加外部工具。然后，可以按照相应的官方工具指南来设置这些工具。

请参考 ESLint 和 Jest 的以下示例：

#### ESLint##eslint

1. 运行 `npm i -D eslint`。此命令会将 ESLint 添加到项目依赖项。

2. 在项目根目录下创建一个包含以下内容的 `.eslint.json` 文件：

   *JSON*

   ```js
   {
       "env": {
       "commonjs": true,
       "es2021": true
       },
       "extends": "eslint:recommended",
       "parserOptions": {
       "ecmaVersion": 13
       },
       "rules": {
       }
   }
   ```

3. 配置集成开发环境以运行 ESLint。对于 Visual Studio Code，这是自动进行的，但可能还需要其他设置，具体取决于集成开发环境。

4. ESLint 现在应该已经配置完成并可以正常工作。

要测试 ESLint 是否正常工作，请添加一些有效但违反 `eslint:recommended` 规则集的代码。例如，`if (something == -0)` 应该会在集成开发环境中显示 ESLint 警告。

#### Jest##jest

Jest 是一种用于 JavaScript 测试的框架。以下示例说明了如何为 Cloud Code 脚本创建单元测试。

1. 运行 `npm install --save-dev jest`。此命令将安装 Jest 包。

2. 配置 Jest 以使用 `.es10` 脚本运行。

3. 向 `package.json` 添加以下代码片段：

   *JSON*

   ```js
   "jest": {
       "moduleFileExtensions": ["es10", "js"],
       "testMatch": ["**/*.test.es10"]
   }
   ```

`moduleFileExtensions` 条目使 `js` 和 `es10` 文件对测试有效，`testMatch` 条目使以 `.test.es10` 结尾的文件作为有效的测试文件。

#### 单元测试示例##unit-testing-example

以下 JS 单元测试示例返回一个对象，然后验证测试脚本中的结果是否相同。通过模拟功能可以提供更高级的选项。

##### **要测试的脚本**：##the-script-to-be-tested

Cloud Code 需要以下签名：

*JavaScript*

```js
module.exports = async ({ params, context, logger }) => {
    return {value: "1"};
};
```

##### **测试脚本**：##the-test-script

*JavaScript*

```js
const test = require("./jest_01.es10")
it("test",async () =>{
    expect(await test({})).toMatchObject({value:"1"});
});
```

##### 运行您的测试##running-your-tests

使用以下命令在命令行中运行测试：`npm run test`。
