# 快速上手

WARNING

运行方式:网页(WebGL)

# unity-webgl

UnityWebgl.js 提供了一种简单的解决方案,用于将 Unity WebGL 构建嵌入到 Web 应用程序中,同时为 UnityWebApp 应用之间的双向通信和交互提供 API。

无框架限制,可用于任何 web 项目。
目前仅内置 vue 组件,支持vue2.xvue3.x

based on react-unity-webgl

# Features

  • 📦 无框架限制,支持任何 web 项目;
  • 📬 支持在WebAppUnity 之间双向通信和交互;
  • 💌 使用事件监听机制,调用简单灵活;
  • 🧲 按需引入 vue 组件,兼容Vue@2.xVue@3.x

# Install

# npm

npm install unity-webgl
1

# 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
1
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>
1
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'))
1
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>
1
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
)
1
2
3
4
5

// 1. 初始化 UnityWebgl
unityContext = new UnityWebgl(
  config: IUnityConfig,
  bridge?: string
)

// 2. 创建unity实例,并在canvas上渲染
unityContext.create(canvas: HTMLCanvasElement | string)
1
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) => {})
1
# progress

Unity 资源加载中。(显示加载进度)

unityContext.on('progress', (number) => {})
1
# mounted

Unity 实例创建成功,并完成渲染。(此时 webApp 与 Unity 可以相互通信)

unityContext.on('mounted', (unityContext) => {})
1
# beforeUnmount

Unity 实例退出之前。

unityContext.on('beforeUnmount', (unityContext) => {})
1
# unmounted

Unity 实例已退出并将其从内存中清除。

unityContext.on('unmounted', () => {})
1
# reload

Unity 实例开始重新载入。

unityContext.on('reload', (unityContext) => {})
1
# error

Unity 实例在创建过程中捕获的错误信息

unityContext.on('error', (error) => {})
1

# Vue component

Vue 组件,兼容 vue2.xvue3.x

# props

  • unity : UnityWebgl 实例
  • width : canvas 元素宽度, default: 100%
  • height : canvas 元素高度, default: 100%
  • tabindex : 设置 Canvas 元素 tabindex

# Communication

# 从 Unity 脚本调用 JavaScript 函数

  1. 先在前端项目中通过 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)
1
2
3
4
5
6
7
8
9
10
11
  1. 在 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!')
  }
})
1
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.");
  }
}
1
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
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 参考网站

上次更新: 8/21/2024, 4:45:11 PM