# 快速上手
WARNING
运行方式:网页(WebGL)
# unity-webgl
UnityWebgl.js 提供了一种简单的解决方案,用于将 Unity WebGL 构建嵌入到 Web 应用程序中,同时为 Unity 和 WebApp 应用之间的双向通信和交互提供 API。
无框架限制,可用于任何 web 项目。
目前仅内置 vue 组件,支持vue2.x和vue3.x。
based on react-unity-webgl
# Features
- 📦 无框架限制,支持任何 web 项目;
 - 📬 支持在
WebApp和Unity之间双向通信和交互; - 💌 使用事件监听机制,调用简单灵活;
 - 🧲 按需引入 vue 组件,兼容Vue@2.x 和 Vue@3.x。
 
# Install
# npm
npm install unity-webgl
 # browser
https://cdn.jsdelivr.net/npm/unity-webgl/dist/index.global.js
# vue component
https://cdn.jsdelivr.net/npm/unity-webgl/vue/index.global.js
 2
3
4
# Usage
🚨 提醒:
只有当Unity实例创建成功之后(即触发mounted事件)才能和 web 应用程序进行通信和交互。
建议在打开页面时添加一个 loading,等待 Unity 资源加载完毕后关闭即可。
# html
html demo
<canvas id="canvas" style="width: 100%; height: 100%"></canvas>
<button onclick="postMessage()">postMessage</button>
<button onclick="onFullscreen()">Fullscreen</button>
<button onclick="onUnload()">Unload</button>
<button onclick="onReload()">Reload</button>
<script>
  var unityContext = new UnityWebgl('#canvas', {
    loaderUrl: '/Build/unity.loader.js',
    dataUrl: '/Build/unity.data',
    frameworkUrl: '/Build/unity.framework.js',
    codeUrl: '/Build/unity.wasm',
    streamingAssetsUrl: 'StreamingAssets',
    companyName: 'DefaultCompany',
    productName: 'Unity',
    productVersion: '0.1'
  })
  unityContext
    .on('progress', (progress) => console.log('Loaded: ', progress))
    .on('mounted', () => {
      // ⚠️ 资源加载完成,可与unity进行通信
      unityContext.send('mainScene', 'init', {})
      console.log('Unity Instance created.')
    })
    .on('unmounted', () => console.log('Unity Instance unmounted.'))
  function postMessage() {
    unityContext.send('objectName', 'methodName', {
      id: 'B0001',
      name: 'Building#1',
      location: [150, 75]
    })
  }
  function onUnload() {
    unityContext.unload()
  }
  function onReload() {
    unityContext.reload({
      loaderUrl: '/Build2/unity.loader.js',
      dataUrl: '/Build2/unity.data',
      frameworkUrl: '/Build2/unity.framework.js',
      codeUrl: '/Build2/unity.wasm'
    })
  }
  function onFullscreen() {
    unityContext.setFullscreen(true)
  }
</script>
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
You can also:
var unityContext = new UnityWebgl({
  loaderUrl: '/Build/unity.loader.js',
  dataUrl: '/Build/unity.data',
  frameworkUrl: '/Build/unity.framework.js',
  codeUrl: '/Build/unity.wasm'
})
unityContext.create(document.querySelector('#canvas'))
 2
3
4
5
6
7
8
# Vue
Vue demo
<script setup>
  import UnityWebgl from 'unity-webgl'
  import VueUnity from 'unity-webgl/vue'
  const unityContext = new UnityWebgl({
    loaderUrl: '/Build/OUT_BIM.loader.js',
    dataUrl: '/Build/OUT_BIM.data',
    frameworkUrl: '/Build/OUT_BIM.framework.js',
    codeUrl: '/Build/OUT_BIM.wasm'
  })
  unityContext.on('device', () => alert('click device ...'))
</script>
<template>
  <VueUnity :unity="unityContext" width="800" height="600" />
</template>
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# API
unityContext = new UnityWebgl(
  canvas: HTMLCanvasElement | string,
  config: IUnityConfig,
  bridge?: string
)
 2
3
4
5
或
// 1. 初始化 UnityWebgl
unityContext = new UnityWebgl(
  config: IUnityConfig,
  bridge?: string
)
// 2. 创建unity实例,并在canvas上渲染
unityContext.create(canvas: HTMLCanvasElement | string)
 2
3
4
5
6
7
8
备注:
unityContext: 表示UnityWebgl实例;
unityInstance: 表示 Unity 应用程序实例。
# canvas
渲染 Unity 的画布元素
- type : 
string | HTMLCanvasElement 
# bridge
与 Unity 通信的桥接名称。它挂载 window 上,用于收集已注册的方法供 Unity 调用。
- type : 
string - default : 
__UnityLib__ 
# config
初始化 Unity 应用程序的配置项。
配置项必须包含最基本的四个属性
loaderUrl,dataUrl,frameworkUrl,codeUrl,这四个属性都是初始化 Unity 应用程序所需的资源文件。
| Property | Type | Description | 
|---|---|---|
loaderUrl ⭐️ |  string | Unity 资源加载器文件 | 
dataUrl ⭐️ |  string | 包含资源数据和场景的文件 | 
frameworkUrl ⭐️ |  string | 包含运行时和插件代码的文件 | 
codeUrl ⭐️ |  string | 包含本机代码的 Web Assembly 二进制文件 | 
streamingAssetsUrl |  string | 可以找到流媒体资源的网址 | 
memoryUrl |  string | 生成的框架文件的网址 | 
symbolsUrl |  string | 生成的 unity 代码文件的网址 | 
companyName |  string | 元数据: 公司名称 | 
productName |  string | 元数据: 产品名称 | 
productVersion |  string | 元数据: 产品版本 | 
devicePixelRatio |  number | 设置画布的设备像素比率. @详见MDN@devicePixelRatio | 
matchWebGLToCanvasSize |  boolean | 禁用 WebGL 画布的渲染尺寸自动同步标识。@详见unity3d@matchWebGLToCanvasSize | 
webglContextAttributes |  object | 配置 WebGLRenderingContext 创建选项。@详见MDN@WebGLRenderingContext | 
# Methods
UnityWebgl 实例方法
# create(canvasElement: HTMLCanvasElement | string): void
 创建 Unity 实例并在画布上渲染。
canvasElement: canvas 画布元素
# unload(): Promise<void>
 退出 Unity 实例并将其从内存中清除,以便从 DOM 中 Unmount。此时也会删除所有已注册的方法。
操作完成之后会触发
unmounted事件
# reload(config): void
 重新载入 Unity 资源并重建 Unit 应用实例。
config: Unity 应用程序的配置项, @详见
# send(objectName: string, methodName: string, params?: any)
 ⭐️ 向 Unity 实例对象发送消息,调用一个公共方法。
objectName: Unity 场景中对象的名称methodName: Unity 脚本中方法的名称params: 传递的参数
# on(eventName: string, eventListener: Function)
 ⭐️ 注册一个事件或方法,用于监听触发事件或供 Unity 脚本调用。
# setFullscreen(enabled: boolean): void
 启用或禁用 Unity 画布的全屏模式。
# requestPointerLock(): void
 允许您异步地请求将鼠标指针锁定在 Unity 应用的 Canvas 元素上。
# takeScreenshot(dataType: 'image/png' | 'image/jpeg' | 'image/webp', quality?: number)
 获取画布的屏幕截图并返回包含图像数据的数据 URL。
dataType: 图像数据的类型quality: 图像的质量
# once(eventName: string, eventListener: Function)
 注册事件仅执行一次
# off(eventName: string)
 取消监听事件
# emit(eventName: string)
 触发监听事件
# clear()
 清空监听事件
# Events
Unity 实例从创建到销毁过程中触发的事件。
# beforeMount
Unity 资源开始加载之前。(此时 Unity 实例还未创建)
unityContext.on('beforeMount', (unityContext) => {})
 # progress
Unity 资源加载中。(显示加载进度)
unityContext.on('progress', (number) => {})
 # mounted
Unity 实例创建成功,并完成渲染。(此时 webApp 与 Unity 可以相互通信)
unityContext.on('mounted', (unityContext) => {})
 # beforeUnmount
Unity 实例退出之前。
unityContext.on('beforeUnmount', (unityContext) => {})
 # unmounted
Unity 实例已退出并将其从内存中清除。
unityContext.on('unmounted', () => {})
 # reload
Unity 实例开始重新载入。
unityContext.on('reload', (unityContext) => {})
 # error
Unity 实例在创建过程中捕获的错误信息
unityContext.on('error', (error) => {})
 # Vue component
Vue 组件,兼容 vue2.x 和 vue3.x
# props
unity: UnityWebgl 实例width: canvas 元素宽度, default:100%height: canvas 元素高度, default:100%tabindex: 设置 Canvas 元素 tabindex
# Communication
# 从 Unity 脚本调用 JavaScript 函数
- 先在前端项目中通过 
Unity.on()注册showDialog方法,该方法会默认绑定在window['__UnityLib__']对象上。 
// # in webApp
const unityContext = new UnityWebgl()
// Register functions
unityContext.on('showDialog', (data) => {
  console.log(data)
  $('#dialog').show()
})
// you also can call function.
unityContext.emit('showDialog', data)
 2
3
4
5
6
7
8
9
10
11
- 在 Unity 项目中,将注册的
showDialog方法添加到项目中。
注意 📢 :请使用.jslib扩展名将包含 JavaScript 代码的文件放置在 Assets 文件夹中的“Plugins”子文件夹下。插件文件需要有如下所示的语法: 
// javascript_extend.jslib
mergeInto(LibraryManager.library, {
  // this is you code
  showDialog: function(str) {
    // var data = Pointer_stringify(str);
    var data = UTF8ToString(str)
    // '__UnityLib__' is a global function collection.
    __UnityLib__.showDialog(data)
  },
  Hello: function() {
    window.alert('Hello, world!')
  }
})
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
然后你可以像这样从 C#脚本中调用这些函数:
using UnityEngine;
using System.Runtime.InteropServices;
public class NewBehaviourScript : MonoBehaviour {
  [DllImport("__Internal")]
  private static extern void Hello();
  [DllImport("__Internal")]
  private static extern void showDialog(string str);
  void Start() {
    Hello();
    showDialog("This is a string.");
  }
}
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 使用 JavaScript 调用 Unity 脚本函数
const Unity = new UnityWebgl()
/**
 * Sends a message to the UnityInstance to invoke a public method.
 * @param {string} objectName Unity scene name.
 * @param {string} methodName public method name.
 * @param {any} params an optional method parameter.
 */
Unity.send(objectName, methodName, params)
// e.g. Initialize Building#001 data
Unity.send('mainScene', 'init', {
  id: 'b001',
  name: 'building#001',
  length: 95,
  width: 27,
  height: 120
})
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18