# Integrate with Unity Editor

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

The Cloud Code Authoring module (installed with the Cloud Code package) allows you to optionally author and modify scripts directly within the Unity Editor. You can then upload scripts from the Unity Editor to the Unity Dashboard with the [Deployment package](https://docs.unity3d.com/Packages/com.unity.services.deployment@latest).

> **Note:**
>
> Authoring of scripts in the Unity Editor is only supported in Unity 2021.3 or later.

Scripts existing in the Unity Editor allow users to treat their source control as the single source of truth (instead of the version in the cloud), simplifying actions such as rollbacks, bisection, and other common operations. For example, the Cloud Code Authoring module facilitates tasks like keeping client C# scripts in sync with Cloud Code scripts.

## Prerequisites

To use Cloud Code in the Unity Editor, you must first install the Cloud Code SDK and link your [Unity Gaming Services project](/cloud/projects.md) to the Unity Editor.

### Link project

Link your [Unity Gaming Services project](/cloud/projects.md) with the Unity Editor. You can find your UGS project ID in the Unity Dashboard.

1. In Unity Editor, select **Edit** > **Project Settings** > **Services**.

2. Link your project.

   * If your project doesn't have a Unity project ID:

     1. Select **Create a Unity Project ID** > **Organizations**, then select an organization from the dropdown menu.
     2. Select **Create project ID**.

   * If you have an existing Unity project ID:

     1. Select **Use an existing Unity project ID**.
     2. Select an organization and a project from the dropdown menus.
     3. Select **Link project ID**.

Your Unity Project ID appears, and the project is now linked to Unity services. You can also access your project ID in a Unity Editor script using `UnityEditor.CloudProjectSettings.projectId`.

### Install required packages

To create Cloud Code scripts within the Editor, you must install the following packages:

* Deployment (`com.unity.services.deployment`)
* Cloud Code (`com.unity.services.cloudcode`), version 2.1.1 or later

To install each package, follow the steps in [Install a UPM package by name](https://docs.unity3d.com/Manual/upm-ui-quick.html), and enter the package name from the preceding list.

## Authoring within Unity Editor

The Cloud Code Authoring module allows you to create, edit, and deploy Cloud Code scripts directly within the Unity Editor.

### Create a script

Follow these steps to create a Cloud Code script using the Cloud Code Authoring module:

1. In the Unity Editor, right-click in the Project window, then select **Create** > **Services** > **Cloud Code Js Script**.
2. Name the script as you would a C# script. Cloud Code scripts use their file name as the identifier when uploading to the service.
3. Press **Enter**.

> **Note:**
>
> Cloud Code restricts the possible identifier names that you can use. To make sure your file uploads correctly, refer to [Script creation](./unity-dashboard.md#create-a-script).

The new script is now visible in the Project window, and in the Deployment window, accessible by selecting **Window** > **Deployment**.

### Edit a script

There are two methods to edit an existing Cloud Code Authoring script:

* In the Project tab, double-click the existing script.
* In the Deployment window, find the existing script then, from the right-click menu, select **Open**.

By default, your Cloud Code script opens in your default JavaScript editor.

To set your default JavaScript editor:

1. In the Unity Editor, select **Edit** > **Preferences…** > **Cloud Code**.
2. In the Javascript Editor section, choose the application path for your preferred JS editor.
3. Select **Apply**.

For advanced cases, you can specify the following arguments:

* `$(File)`: File path of the asset
* `$(ProjectPath)`: Project directory
* `$(SolutionPath)`: Solution path
* `$(EditorExePath)`: Editor executable path (chosen within the Unity Editor by selecting **Edit** > **Preferences…** > **External Tools**)

The following represents a few examples of possible setups:

* JetBrains Rider (on Windows):

  * Application: `cmd.exe`
  * Args: `/C "$(EditorExePath) $(ProjectPath) $(File)"`

* Microsoft Visual Studio Code:

  * Application: `Code.exe`
  * Args: `$(ProjectPath) $(File)"`

### Deploy a script

You can deploy a script through the Deployment window. Check the [Deployment package manual](https://docs.unity3d.com/Packages/com.unity.services.deployment@latest) for more information.

## Modify script parameters

You can access and modify Cloud Code scripts parameters in the Unity Editor.

### Access parameters in the Editor’s Inspector window

You can modify a Cloud Code script’s parameters by selecting the script in the Unity Editor’s Project window. The script’s parameters open in the Editor’s Inspector window.

> **Important:**
>
> Changing the parameters of a script might make existing game clients incompatible. The client might send parameters that are incompatible, or not send required parameters.

The possible parameter types are:

* String
* Boolean
* Numeric
* JSON
* Any

> **Note:**
>
> The [Inspector](https://docs.unity3d.com/Manual/UsingTheInspector.html) has limited support for editing parameters; the UGS CLI can't read these parameters. If you want to use both the Editor and the CLI, use [parameters in the script](#declare-parameters-in-the-script-body).

### Declare parameters in the script body

For a more seamless experience in your Cloud Code scripts, you can declare your parameters directly in the script by exporting the `params` object, containing each parameter name as a key, and its type as a value.

> **Warning:**
>
> You must assign the `module.exports` property before setting the parameters.

> **Warning:**
>
> You must setup your Cloud Code JS dev environment with NodeJS in order to enable inline script parameters. Refer to the [JavaScript Project Authoring guide](https://docs.unity3d.com/Packages/com.unity.services.cloudcode@latest/index.html?subfolder=/manual/Authoring/javascript_project.html) for further details.

> **Warning:**
>
> In-script parameters are currently unsupported by the Unity Dashboard.

For example:

*JavaScript*

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

Alternatively, if you'd like to specify that a parameter is required, you may specify an object containing both the `type` and `required` properties.

*JavaScript*

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

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

By default, parameters aren't required.

Both formats can be combined as desired:

*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 },
};
```

If you're using in-script parameters, they override previously defined inspector parameters.

In-script parameters offer a simpler alternative to declaring parameters, but the Unity Dashboard doesn't currently parse in-script parameters if you try to update them without using the Deployment package.

## JS bundles

> **Note:**
>
> JS bundling is available in with com.unity.services.cloudcode\@2.3.0+, and isn't yet supported by the UGS command-line interface.

Your JS scripts can import local scripts or external modules with the `import` or `require` keywords.
The bundling process uses your script as the input and feeds the bundled result to the Unity Dashboard.
This process doesn't modify your local files.

To enable bundling on a script, export the `bundling` object and set the value to true.
This process is on a per-script basis. By default, scripts aren't bundled.
If you have enabled bundling, your scripts are bundled before deployment via the [Deployment window](#deployment-window).

> **Important:**
>
> You must assign the module.exports property before setting the bundling option.

*JavaScript*

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

The following example demonstrates what bundling could look like in a sample project.

*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 window

The Deployment window is a core feature of the Deployment package. It allows all services to have a single cohesive interface for deployment needs, and allows you to upload cloud assets to their respective cloud services.

Check the [Deployment package manual](https://docs.unity3d.com/Packages/com.unity.services.deployment@latest) for more information.

## Cloud Code JavaScript projects in the Unity Editor

A Cloud Code JavaScript project in the Unity Editor sits at the root of the Unity project and has the following structure:

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

`package.json` stores the project configuration. This file is used by JavaScript (JS) editors and NPM, and operates similarly to how C# uses the .csproj file type to define information for the Unity Editor. Note that these `package.json` files used within the JavaScript project system aren't Unity packages; they're NPM packages. It's a coincidence that Unity and NodeJS use the same package management system.

`package-lock.json` is generated by NPM, and is used for dependency resolution. It's recommended to keep this file in source control so that dependencies would always be resolved the same way.

### NodeJS

To support more tooling for developers, developers must install [NodeJS](https://nodejs.org/en/). NodeJS allows support for autocomplete and other expected features of a development environment.

### Autocomplete

The majority of autocomplete for JS is handled by the [typings](https://github.com/typings/registry) project. You can augment any JavaScript file by using a `.d.ts` file to define the typed API. Most public JS libraries either include their own `.d.ts` files or have some defined within typings.

For an editor to enable autocomplete for a dependency, it needs to be able to locate the type definitions for the dependency. It does this by looking in `node_modules`. To enable autocomplete, you must use the `package.json` file to install the correct files to `node_modules`.

### External tools

You can add external tools by running the appropriate `npm install ...` command from within the JS project. You can then set up these tools following their official tool guidelines.

Consider the following examples for ESLint and Jest:

#### ESLint

1. Run `npm i -D eslint`. This command adds ESLint to the project dependencies.

2. Create an `.eslint.json` file at the project root containing:\\

   *JSON*

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

3. Configure your IDE to run ESLint. This is automatic for Visual Studio Code but might need additional settings depending on the IDE.

4. ESLint should now be configured and working.

To test that ESLint is working, add some code that's valid but breaks the `eslint:recommended` ruleset. For example, `if (something == -0)` should show an ESLint warning in your IDE.

#### Jest

Jest is a framework for JavaScript testing. The following is an example of how you can create unit tests for your Cloud Code scripts.

1. Run `npm install --save-dev jest`. This command installs the Jest package.

2. Configure Jest to run with `.es10` scripts.

3. Add the following code snippet to your `package.json`:\\

   *JSON*

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

The `moduleFileExtensions` entry makes `js` and `es10` files valid for testing, and the `testMatch` entry makes files ending in `.test.es10` valid as test files.

#### Unit testing example

The following JS unit testing example returns an object then verifies whether the result in the test script is the same. More advanced options are available with mocking.

##### **The script to be tested**

Cloud Code expects the following signature:

*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

Run your tests in the command line with the following command: `npm run test`.
