# 从 Unity C# 脚本调用 JavaScript 函数

> Call functions from your JavaScript plug-in or browser in your Unity project.

您可以在 Unity C# 代码中使用 JavaScript 插件中的函数。在 Unity 中使用 JavaScript 代码可能很有用，因为可能需要与网页或 Web API 上的其他元素通信。

要了解文件类型以及如何设置 JavaScript 插件以便与 Unity 脚本交互，请参阅[设置 JavaScript 插件](/engine/6000.0/manual/platform-specific/webgl/develop/interactingwithbrowserscripting/web-interacting-browser-js.md)。要了解如何改用 C/C++/C# 插件进行交互，请参阅[从 Unity C# 脚本调用 C/C++/C# 函数](/engine/6000.0/manual/platform-specific/webgl/develop/interactingwithbrowserscripting/web-interacting-browsers-c-to-unity.md)。

| 主题                                                        | 描述                                    |
| --------------------------------------------------------- | ------------------------------------- |
| [将不同的变量从 JavaScript 传递到 Unity](#pass-different-variables) | 关于如何在 Unity 和 JavaScript 之间传递不同变量的提示。 |
| [在作用域内执行构建代码](#make-code-visible)                         | 关于如何提高 Unity 和 JavaScript 之间代码可见性的提示。 |
| [调用 JavaScript 函数的 Unity C# 代码的示例](#example-unity-code)   | 此示例代码展示了如何在 Unity 中调用 JavaScript 函数。  |
| [使用 Unity 插件作为参考](#plugin-ref)                            | 显示 Unity 包含且可用作参考的插件的列表。              |

## 将不同的变量从 JavaScript 传递到 Unity##pass-different-variables-from-javascript-to-unity

要将 JavaScript 与 Unity 集成，需要在两者之间实现高效的通信。参考以下提示，了解如何将各种类型的数据从 JavaScript 传递到 Unity。

### 数值类型##numeric-types

可以将简单的数值类型以函数参数的形式传递给 JavaScript，无需对其进行转换。

例如，JavaScript 中的此函数：

```js
AddNumbers: function (x, y) {
    return x + y;
  },
```

接收来自 C# 的整数值，期间无需转换：

```cs
int result = AddNumbers(5, 7);
```

可以在 Emscripten 堆中将其他数据类型作为指针传递。Emscripten 堆只是 JavaScript 内存中的一个大型数组。

### 字符串##strings

要将字符串转换成 JavaScript 字符串，可使用 `UTF8ToString` helper 函数。

```js
var stringMessage = UTF8ToString("Hello World");
```

要返回字符串值，可调用 `_malloc` 来分配一些内存，并调用 `stringToUTF8` helper 函数向内存写入 JavaScript 字符串。如果字符串是返回值，则 IL2CPP 运行时将自动为您释放内存。

```js
 var returnStr = "Hello World";
    var bufferSize = lengthBytesUTF8(returnStr) + 1;
    var buffer = _malloc(bufferSize);
    stringToUTF8(returnStr, buffer, bufferSize);
```

### 数组##arrays

对于原始类型的数组，Emscripten 针对内存的不同大小的整数、无符号整数或浮点数表示形式，提供其堆的不同 `ArrayBufferViews`：`HEAP8`、`HEAPU8`、`HEAP16`、`HEAPU16`、`HEAP32`、`HEAPU32`、`HEAPF32`、`HEAPF64`。

以下函数在 `HEAPF32` 数组中循环并输出每个索引处的值。

```js
PrintFloatArray: function (array, size) {
    for(var i = 0; i < size; i++)
    console.log(HEAPF32[(array >> 2) + i]);
  },
```

### 纹理 (Textures)##textures

为了在 WebGL 中访问纹理，Emscripten 提供了 `GL.textures` 数组，该数组将本机纹理 ID 从 Unity 映射到 WebGL 纹理对象。可在 Emscripten 的 WebGL 上下文 `GLctx` 中调用 WebGL 函数。

例如，以下函数将 WebGL 纹理从 GL 纹理数组绑定到 2D 纹理。

```js
 BindWebGLTexture: function (texture) {
    GLctx.bindTexture(GLctx.TEXTURE_2D, GL.textures[texture]);
  },
```

## 在作用域内执行构建代码##execute-build-code-in-its-own-scope

建议您在构建代码自己的作用域内执行所有构建代码。如果代码在其自己的作用域内运行，则可以将内容嵌入到页面上，而不会与嵌入页面代码发生冲突，并且可以在同一页面上嵌入多个构建。

### .jslib 插件中的代码##code-in-.jslib-plug-ins

如果项目中的所有 JavaScript 代码都以 `.jslib` 插件的形式存在，则此 JavaScript 代码将在与编译后的构建相同的作用域内运行，并且代码的工作方式应与 Unity 以前版本中的工作方式相同。JavaScript 插件代码中直接可见的一些对象和函数包括：

* `Module`
* `SendMessage`
* `HEAP8`
* `ccall`

### 从全局作用域调用 JavaScript 函数##call-javascript-functions-from-global-scope

如果要在 Web 模板 `index.html` 中从嵌入页面的全局作用域调用内部 JavaScript 函数，必须使用 `unityInstance` 变量。

在 Unity 引擎实例化成功后使用 `unityInstance`，例如：

```js
  var MyGameInstance = null;
  script.onload = () => {
    createUnityInstance(canvas, config, (progress) => { /*...*/ }).then((unityInstance) => {
      MyGameInstance = unityInstance;
```

然后可以使用 `MyGameInstance.SendMessage()` 向构建发送消息，或使用 `MyGameInstance.Module` 访问构建模块对象。

## 调用 JavaScript 函数的 Unity C# 代码的示例##example-unity-c-code-that-calls-javascript-functions

以下 JavaScript 代码会创建一个名为 `Hello` 的函数。对于此示例，请在 JavaScript 插件中使用此代码，以便在 Unity C# 脚本中调用此代码。

```js
mergeInto(LibraryManager.library, {

  Hello: function () {
	window.alert("Hello, world!");
  },
});
```

然后，在 Unity 项目中使用此 C# 代码，以便从 JavaScript 代码调用 `Hello` 函数：

```cs
using UnityEngine;
using System.Runtime.InteropServices;

public class NewBehaviourScript : MonoBehaviour {

    [DllImport("__Internal")]
    private static extern void Hello();

    void Start() {
        Hello();
    }
}
```

有关具有不同函数类型的较大代码示例，请参阅 [代码示例：在 Unity 中调用 JavaScript 和 C/C++/C# 函数](/engine/6000.0/manual/platform-specific/webgl/develop/interactingwithbrowserscripting/web-interacting-code-example.md)。

## 使用 Unity 插件作为参考##use-unity-plug-ins-as-a-reference

在 Unity 安装文件夹中有几个插件可用作参考：

* `PlaybackEngines/WebGLSupport/BuildTools/lib`

* `PlaybackEngines/WebGLSupport/BuildTools/Emscripten/src/library*`

## 其他资源##additional-resources

* [与浏览器脚本交互](/engine/6000.0/manual/platform-specific/webgl/develop/interactingwithbrowserscripting.md)

* [设置 JavaScript 插件](/engine/6000.0/manual/platform-specific/webgl/develop/interactingwithbrowserscripting/web-interacting-browser-js.md)

* [从 JavaScript 调用 Unity C# 脚本函数](/engine/6000.0/manual/platform-specific/webgl/develop/interactingwithbrowserscripting/web-interacting-browser-unity-to-js.md)

* [从 Unity C# 脚本调用 C/C++/C# 函数](/engine/6000.0/manual/platform-specific/webgl/develop/interactingwithbrowserscripting/web-interacting-browsers-c-to-unity.md)

* [在 Unity C#、JavaScript 和 C/C++/C# 代码之间创建回调](/engine/6000.0/manual/platform-specific/webgl/develop/interactingwithbrowserscripting/web-interacting-browser-example.md)
