🏣 An easy solution for embedding Unity WebGL builds in webApp or Vue.js project, with two-way communication between your webApp and Unity.

Overview

unity-webgl

Unity WebGL provides an easy solution for embedding Unity WebGL builds in your webApp or Vue.js project, with two-way communication between your webApp and Unity application with advanced API's.

UnityWebgl.js 提供了一种简单的解决方案,用于在 webApp 或 Vue.js (支持Vue2.x & Vue3.x) 项目中嵌入 Unity WebGL,并通过API在 webApp 和 Unity 之间进行双向通信。

based on react-unity-webgl

Features

Install

npm & ESM

npm install unity-webgl

To make unity-webgl/vue work for Vue 2 (<2.7.0), you need to have @vue/composition-api installed:

npm i -D @vue/composition-api

browser

https://cdn.jsdelivr.net/npm/unity-webgl/dist/UnityWebgl.min.js

# vue component
https://cdn.jsdelivr.net/npm/unity-webgl/dist/VueUnity.min.js

Usage

in example.html
">
<canvas id="canvas" style="width: 100%; height: 100%">canvas>

<button onclick="onDestroy()">Destroybutton>
<button onclick="onLoad()">Reloadbutton>
<button onclick="onFullscreen()">Fullscreenbutton>

<script>
var Unity = new UnityWebgl('#canvas', {
  loaderUrl: '/Build/unity.loader.js',
  dataUrl: "/Build/unity.data",
  frameworkUrl: "/Build/unity.framework.js",
  codeUrl: "/Build/unity.wasm"
})

Unity
  .on('progress', percent => console.log('Unity Loaded: ', percent))
  .on('created', () => console.log('Unity Instance: created.'))
  .on('destroyed', () => console.log('Unity Instance: Destroyed.'))

function postMessage() {
  Unity.send('objectName', 'methodName', {
    id: 'B0001',
    name: 'Building#1',
    location: [150, 75]
  })
}

function onDestroy() {
  Unity.destroy()
}

function onLoad() {
  Unity.create('#canvas')
}

function onFullscreen() {
  Unity.setFullscreen(true)
}
script>

You can also:

var Unity = new UnityWebgl({
  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",
})

Unity.create(document.querySelector('#canvas'))

Vue

Vue 2.x
">
<template>
  <VueUnity :unity="unityContext" width="800" heighht="600" />
template>

<script>
  import UnityWebgl from 'unity-webgl'
  import VueUnity from 'Unity-webgl/vue'

  const Unity = new UnityWebgl({
    loaderUrl: '/Build/OUT_BIM.loader.js',
    dataUrl: "/Build/OUT_BIM.data",
    frameworkUrl: "/Build/OUT_BIM.framework.js",
    codeUrl: "/Build/OUT_BIM.wasm",
  })

  Unity.on('device', () => alert('click device ...'))

  export default {
    components: {
      VueUnity
    },
    data() {
      return {
        unityContext: Unity
      }
    }
  }
script>
Vue 3.x
import UnityWebgl from 'Unity-webgl'; import VueUnity from 'Unity-webgl/vue' const Unity = new UnityWebgl({ loaderUrl: '/Build/OUT_BIM.loader.js', dataUrl: "/Build/OUT_BIM.data", frameworkUrl: "/Build/OUT_BIM.framework.js", codeUrl: "/Build/OUT_BIM.wasm", }) Unity.on('device', () => alert('click device ...')) ">
<script setup lang="ts">
import UnityWebgl from 'Unity-webgl';
import VueUnity from 'Unity-webgl/vue'

const Unity = new UnityWebgl({
  loaderUrl: '/Build/OUT_BIM.loader.js',
  dataUrl: "/Build/OUT_BIM.data",
  frameworkUrl: "/Build/OUT_BIM.framework.js",
  codeUrl: "/Build/OUT_BIM.wasm",
})

Unity.on('device', () => alert('click device ...'))
script>

<template>
  <VueUnity :unity="Unity" width="800" heighht="600" />
template>

API

unityContext = new UnityWebgl(canvasElement: HTMLCanvasElement | string, options: IUnityConfig)

Options

  • loaderUrl: string
    The url to the build json file generated by Unity
  • dataUrl: string
    The url to the build data file generated by Unity
  • frameworkUrl: string
    The url to the framework file generated by Unity
  • codeUrl: string
    The url to the unity code file generated by Unity
  • streamingAssetsUrl?: string
    The url where the streaming assets can be found
  • companyName?: string
    The applications company name
  • productName?: string
    The applications product name
  • productVersion?: string
    The applications product version
  • webglContextAttributes?: IWebGLContextAttributes
    This object allow you to configure WebGLRenderingContext creation options. see [email protected]
  • devicePixelRatio?: number
    Uncomment this to override low DPI rendering on high DPI displays. see [email protected]
  • matchWebGLToCanvasSize?: boolean
    Uncomment this to separately control WebGL canvas render size and DOM element size. see [email protected]

Methods

  • create(canvasElement: HTMLCanvasElement | string)
  • send(objectName: string, methodName: string, params?: any)
    Sends a message to the UnityInstance to invoke a public method.
  • setFullscreen(enabled: boolean)
    Enables or disabled the fullscreen mode of the UnityInstance.
  • destroy()
    Quits the Unity Instance and clears it from memory.

  • on(eventName: string, eventListener: Function)
    Use instance.on() to register a method for Unity-script call.
  • once(eventName: string, eventListener: Function)
  • off(eventName: string)
  • clear()
  • emit(eventName: string)

Events

  • progress
    loading progress.
     unityContext.on('progress', (number) => {})
  • loaded
    loading completed.
     unityContext.on('loaded', () => {})
  • created
    Unity Instance is created.
     unityContext.on('created', () => {})
  • destroyed
    Quits the Unity Instance and clears it from memory.
     unityContext.on('destroyed', () => {})

Vue component

props

  • unity: UnityWebgl
  • width?: string|number , default: 100%
  • height?: string|number , default: 100%

Communication

1. Calling JavaScript functions from Unity scripts

从 Unity 脚本调用 JavaScript 函数

  1. First, you should register a showDialog method, which be bind to the __UnityLib__ global object by default.

    先在前端项目中通过 Unity.on() 注册 showDialog 方法,该方法会默认绑定在全局对象__UnityLib__上。

// # in webApp

const Unity = new UnityWebgl()
// Register functions
Unity.on('showDialog', (data) => {
  console.log(data)
  $('#dialog').show()
})

// you also can call function.
Unity.emit('showDialog', data)
// or
window[Unity.global_name].showDialog(data) // 📢 Unity.global_name = __UnityLib__
  1. In the Unity project, add the registered showDialog method to the project, and then call those functions directly from your script code. To do so, place files with JavaScript code using the .jslib extension under a “Plugins” subfolder in your Assets folder. The plugin file needs to have a syntax like this:

    在Unity项目中,将注册的showDialog方法添加到项目中。注意 📢 :请使用 .jslib 扩展名将包含 JavaScript 代码的文件放置在 Assets 文件夹中的“Plugins”子文件夹下。插件文件需要有如下所示的语法:

// javascript_extend.jslib

mergeInto(LibraryManager.library, {
  // this is you code
  showDialog: function (str) {
    var data = Pointer_stringify(str);
    // '__UnityLib__' is a global function collection.
    __UnityLib__.showDialog(data);
  },
  
  Hello: function () {
    window.alert("Hello, world!");
  }
});

Then you can call these functions from your C# scripts like this:

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. Calling Unity scripts functions from JavaScript

使用 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
})
Comments
  • Compile Error: Component name

    Compile Error: Component name "Unity" should always be multi-word

    您好,首先感谢您开源一个vue社区唯一的untiy webgl库!

    不幸的是我按照 example.vue 里的代码编译会报错,复现步骤如下 1.新建一个vue2项目 2. 安装npm install unity-webgl 3. 把自带的 HelloWorld.vue 改成说明文档里的例子

    <template>
      <Unity :unity="unityContext" width="800px" height="600px" />
    </template>
    
    <script>
    import UnityWebgl from 'unity-webgl'
    
    const Unity = new UnityWebgl({
      loaderUrl: 'Build/OUT_BIM.loader.js',
      dataUrl: "Build/OUT_BIM.data",
      frameworkUrl: "Build/OUT_BIM.framework.js",
      codeUrl: "Build/OUT_BIM.wasm"
    })
    
    export default {
      name: 'Unity',
      component: {
        Unity: UnityWebgl.vueComponent
      },
      data() {
        return {
          unityContext: Unity
        }
      }
    }
    </script>
    

    然后 npm run serve 出现这么一个错误:

    R:\html\hello-world\src\components\HelloWorld.vue
      16:9  error  Component name "Unity" should always be multi-word  vue/multi-word-
    

    请大佬不吝赐教

    opened by orangeagain 10
  • Communicaton from Unity to Vue not working

    Communicaton from Unity to Vue not working

    Hi, thanks for your great plugin!

    Everything is working fine except communication from unity to vue. I want to listen on a method listenToUnity() in Unity. My code in Vue looks like this:

    Unity.on("listenToUnity", () => console.log("I am listening to unity."));

    What do I have to do in Unity? Your docu says __UnityLib__.showDialog(data), but I dont understand what I should do..

    Can you help me please?

    ppVis

    opened by ppVis 4
  • Unity Webgl: Unityloader already exists

    Unity Webgl: Unityloader already exists

    Hello!

    I use UnityWebGL with Vue. I have a wrapper component for it.

    In mounted hook:

    this.UnityContext = new UnityWebgl('#canvas', {
          loaderUrl: '/unity/test-customizer/BuildWA.loader.js',
          dataUrl: '/unity/test-customizer/BuildWA.data',
          frameworkUrl: '/unity/test-customizer/BuildWA.framework.js',
          codeUrl: '/unity/test-customizer/BuildWA.wasm',
       })
    
    this.$once('hook:beforeDestroy', function () {
          console.log('hook:beforeDestroy');
          this.UnityContext.destroy()
          this.UnityContext = null
    })
    

    beforeDestroy hook works. But when I navigate between pages that use UnityWebGL I still have this warning:

    Unity Webgl: Unityloader already exists
    

    Could you please explain, what am I doing wrong?

    opened by OctopussyO 2
  • assign required value to attribute before event emitted.

    assign required value to attribute before event emitted.

    When I want to access unityInstace attribute in UnityWebGL instance right in created event,I found the attribute is null. I need to use setTimeout to wait 1ms to unityInstace, which doesn't make sense. So I suggest this update.

    opened by RadianSmile 1
  • setFullscreen not work

    setFullscreen not work

    Thank you for your great plugin!

    Almost works properly. But setFullscreen() is not working on My environment(Unity2020.3.24f1).

    VueCode: Unity.setFullScreen(true);

    Error: "TypeError: Unity.setFullScreen is not a function"

    Please, Can you help me ?

    ittoh0819

    opened by ittoh0819 1
A generic player for playing different types of content (questions, etc.) in a mobile-friendly webapp

Question Set Player A generic player for playing different types of questions (mcq, subjective, images, audio etc.) in a mobile-friendly webapp. Table

Avanti Fellows 2 May 11, 2022
Genshin Lyre Parser is a webapp that can parse notes from any Genshin Impact lyre video.

Genshin Lyre Parser is a webapp that can generate a playable note list from almost any Genshin Impact lyre video. You can simply pick a file, drag it in the parser, process it, and enjoy your note list.

Fülöp Tibor 4 Jul 30, 2022
Turn your Home Assistant instance into a jukebox, hassle free streaming of your favorite media to Home Assistant media players.

Turn your Home Assistant instance into a jukebox, hassle free streaming of your favorite media to Home Assistant media players.

Music Assistant 324 Sep 25, 2022
:cake: Easy-to-use music player for Vue 2.x

Vue-APlayer Vue implementation of APlayer prototype. Demo Features Beautiful clean UI Lyrics scroll Playlist with repeat & shuffle controls Custom the

Doma 1.3k Sep 27, 2022
:stuck_out_tongue_winking_eye: :stuck_out_tongue_winking_eye: :stuck_out_tongue_winking_eye: Easy to create custom audio player components for Vue. 一个有灵魂的进度条。 A progress bar with soul.

vue-audio-better Easy to create custom audio player components for Vue.js. 一个有灵魂的进度条。 A progress bar with soul. 简单、有趣的 audio 组件,非常感谢您的 star! Simple, f

JasonYu 104 Sep 3, 2022
A Howler.js mixin for Vue 2 that makes it easy to create custom audio player components

vue-howler A Howler.js mixin for Vue 2 that makes it easy to create custom audio player components Installation $ npm install vue-howler Usage First c

Mick Dekkers 105 Jun 4, 2022
Music playback project based on the Howlerjs and VueJs

player-vue-4 Music playback project based on the Howlerjs and VueJs library.. vista presentacion/home vista del Reproductor/player Link Prewiew Play-M

null 3 Jun 18, 2022
A modern, visual video player for Vue3. It will bring your videos to life with a customizable and powerful player!

vue3-player-video A modern, visual video player for Vue3. It will bring your videos to life with a customizable and powerful player! If you have a pro

Enzo Esteves ⚡ 34 Sep 15, 2022
Manage your videos, add any metadata to them and play them.

Manage your videos, add any metadata to them and play them.

null 76 Sep 26, 2022
🔥 Vue3 component that allows adding annotations to your videos by free drawing or adding shapes like circles, squares, and arrows.

Vue Video Annotation Vue3 component that allows adding annotations to videos by free drawing or adding shapes like circles, squares, and arrows. ?? De

Wellington 6 Jul 31, 2022
Vue-webrtc-photo-app - A simple app to take photos from your device's camera

Vue WebRTC Photo App This is a simple app to take a photo from your device's camera. This project is built with: Frontend Framework: Vuejs Created wit

Fatih 3 Apr 21, 2022
Play your own videos in background responsively in different resolutions.

Responsive Video Background Player for Vue 2 & 3 ⚡️ If you are looking to play videos in the background, you have found the best Vue package for it ??

Avido Food 220 Sep 27, 2022
A small app that generates a YouTube playlist from your Spotify playlist links

Watch My Spotify A simple app that converts your public spotify playlists to a YouTube playlist. Built with Vue, Spotify API, YouTube Data API, Netlif

Eric Kelley 9 May 14, 2022
A spotify web app that mixes the songs of your favourite artist you specify.

Vue 3 + Typescript + Vite This template should help get you started developing with Vue 3 and Typescript in Vite. The template uses Vue 3 <script setu

nana_aquasi 1 Nov 18, 2021
frontend for quwerty - your music app 🎧

frontend frontend for quwerty - your music app ?? scripts serve - start developer server build - build vue app lint - lint project (vue) beautify - RU

null 0 Jan 9, 2022
🦋 Tsubasa is a fast video compression service that runs locally on your device. Maintain the best quality while staying under MB file limits.

Tsubasa is a fast video compression service that runs locally on your device. Maintain the best quality while staying under MB file limits.

Matcha Moon 8 Aug 4, 2022
Video chat and screen sharing application based on Vue.js and WebRTC technology

webrtc A video chat and screen share made with Vue.js and SkyWay (WebRTC platform) Screenshot Project setup yarn install Modify your key sed -e 's/Yo

Max 2 May 27, 2022
Embed a YouTube player easily and lazy load the video to save resources and reduces initial load size.

Embed a YouTube player easily and lazy load the video to save resources and reduces initial load size.

Seerat Awan 28 Sep 13, 2022
Music app made with Vue, Vuex and Vue Router

Music app made with Vue, Vuex and Vue Router

Andrés Brugarolas 49 Aug 13, 2022