Importing a Unity WebGL-project into an Angular2 component

unity with angular
unityloader js
unity webgl javascript
pointer_stringify

I'm looking to integrate a Unity WebGL-project into an Angular2 app. What's the proper way to move all this script into an Angular2 component?

First, the Unity WebGL exports an index.html like this:

<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Unity WebGL Player | Espoo web manager (Prefab preview)</title>
    <link rel="shortcut icon" href="TemplateData/favicon.ico">
    <link rel="stylesheet" href="TemplateData/style.css">
    <script src="TemplateData/UnityProgress.js"></script>  
    <script src="Build/UnityLoader.js"></script>
    <script>
      var gameInstance = UnityLoader.instantiate("gameContainer", "Build/builds.json", {onProgress: UnityProgress});
    </script>
  </head>
  <body>
    <div class="webgl-content">
      <div id="gameContainer" style="width: 960px; height: 600px"></div>
      <div class="footer">
        <div class="webgl-logo"></div>
        <div class="fullscreen" onclick="gameInstance.SetFullscreen(1)"></div>
        <div class="title">Espoo web manager (Prefab preview)</div>
      </div>
    </div>
  </body>
</html>

I started to split this and first I moved the stylesheet into the template .css file:

@import './webgl-app/TemplateData/style.css';

Then I moved the javascript into the component .ts-file:

import { Component, AfterViewInit } from '@angular/core';
import './webgl-app/TemplateData/UnityProgress.js';
import './webgl-app/Build/UnityLoader.js';

declare var UnityLoader: any;
declare var UnityProgress: any;

@Component({
  selector: 'app-unity-prefab-preview',
  templateUrl: './unity-prefab-preview.component.html',
  styleUrls: ['./unity-prefab-preview.component.css']
})
export class UnityPrefabPreviewComponent implements AfterViewInit {
  constructor() {}

  gameInstance: any;

  ngAfterViewInit() {
    this.gameInstance = UnityLoader.instantiate("gameContainer", "./webgl-app/Build/builds.json", { onProgress: UnityProgress });
  }

}

And then for the .html template I left this:

<div class="webgl-content">
  <div id="gameContainer" style="width: 960px; height: 600px"></div>
</div>

However, whatever approach I try (like using 'require' on the JS-files instead), the line in the ngAfterViewInit always gives an error: "Reference error: UnityLoader is not defined".

How should this be done properly so it would work?

so I was messing around with this quite a time...

I have it up and running using the angular/cli@latest 1.6.5

here my app.component.ts

import { Component, NgZone, OnInit } from '@angular/core';
import * as $ from 'jquery';
declare const UnityLoader;
@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
public gameObject: any;

constructor(private ngZone: NgZone) {
  window.unity = window.unity || {};
  window.unity.GetUnityNumber = this.randomNumberFromUnity.bind(this);
}

public ngOnInit(): void {
 this.init();
}
public helloUnity() {
 console.log(this.gameObject); // <-- always undefined ?
 this.gameObject.SendMessage('SetText', 'HELLO?');
 }

private init() {
 $.getScript('assets/UnityLoader.js').done(function ( bla , text) {
   this.gameObject = 
   UnityLoader.instantiate('gameContainer','assets/test.json');
   //gameObject not undefined at this stage..
  });
}
private randomNumberFromUnity(input: string) {
  this.ngZone.run(() => {
      console.log('call from unity', input);
 });
}

}

In the typings.d.ts i have extended the window element.

interface Window {
  unity: any;
}

So when I do a call from unity I call it like

Application.ExternalCall("unity.GetUnityNumber", rnd);

All I'm missing right now is the call into unity... maybe you have an idea on this one?

I have the unity-build as a private npm package. When building everything is copied into the assets folder.

Create a d.ts file to UnityLoader.js (Unity3D) · Issue #13340 , I have to import UnityLoader.js in Angular using TypeScript. -a-unity-webgl-​project-into-an-angular2-component/48368812#48368812. To add Unity WebGL to your project: 1) Export WebGL project to a /unity folder in your Angular project root (same level as src). Copy the following files from your Build folder to /src/assets/unity: unity.json unity.data.unityweb unity.wasm.code.unityweb unity.wasm.framework.unityweb 2) Add UnityProgress.js and UnityLoader.js to your angular.json scripts:

ng-unity, this project is purposed to allow an integration with unity webgl application in component angular 4 easily. import this module npm install ng-unity. use the directive to add your app in your dom model. copy build.json  When you build The process of compiling your Project into a format that is ready to run on a specific platform or platforms. More info See in Glossary a WebGL project, Unity creates a folder with the following files: An index.html file which browsers can navigate to load your content.

I simplified the Unity WebGL output to

unity-game.html

<body style="margin: 0px">
    <script src="TemplateData/UnityProgress.js"></script>
    <script src="Build/UnityLoader.js"></script>
    <script>
      var gameInstance = UnityLoader.instantiate("gameContainer", "Build/Browser.json", {onProgress: UnityProgress});
    </script>
    <div class="webgl-content">
      <div id="gameContainer" style="width: 800px; height: 600px;"></div>
    </div>
 </body>

and loaded it into an iframe. This gives you an

unsafe value used in a resource URL context

error. This can be addressed by using a special iframe Angular component.

unity-game.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';

@Component({
  selector: 'app-unity-game',
  templateUrl: './unity-game.component.html',
  styleUrls: ['./unity-game.component.css']
})
export class UnityGameComponent implements OnInit {
  @Input()
  url: string;
  urlSafe: SafeResourceUrl;

  constructor(public sanitizer: DomSanitizer) { }

  ngOnInit() {
    this.urlSafe= this.sanitizer.bypassSecurityTrustResourceUrl(this.url);
  }

}

unity-game.component.html

<iframe width="800" height="600" frameBorder="0" [src]="urlSafe"></iframe>

credit to Lrodriguez84: https://stackoverflow.com/a/50863439/719528

Then just add that special iframe component, passing it that HTML file wherever you would like the Unity project to appear!

<app-unity-game url="assets/unity-game.html"></app-unity-game>

Unity WebGL build + Angular integration, Hi all, is there an easy way to integrate a Unity WebGL build into an Angular 8 project, If you just want a unity instance in a component, that should be easy You will need to import the UnityLoader.js file in your template. Then in your component, import ; declare var MY_APP: any; class HomeComponent() { ngAfterViewInit() { MY_APP.init(); } } But the bottom line is still that you don't have an angular2 app - your script.js is basically an old-school jquery page. You could turn most of it into NG2 components. – Zlatko Aug 9 '16 at 8:30

I've got stuck on this aswell.

it seems to be your context is not set

$.getScript('assets/UnityLoader.js').done(function ( bla , text) {
   this.gameObject = 
   UnityLoader.instantiate('gameContainer','assets/test.json');
   //gameObject not undefined at this stage..
   // this does not point towards your container
});

solution :

$.getScript('assets/UnityLoader.js').done(function ( bla , text) {
    this.gameObject = 
    UnityLoader.instantiate('gameContainer','assets/test.json');
    //gameObject not undefined at this stage and this points to container
}.bind(this));

more info : https://docs.unity3d.com/2018.3/Documentation/Manual/webgl-interactingwithbrowserscripting.html

Getting Unity Webgl to work with Angular (9.0.2), - Had to add "export" before "var UnityLoader" so the components can import it. these changes sounds quite logical given how Angular treat  Unity compiles your sources into JavaScript from C/C++ code using emscripten, so you can also write plugins in C/C++ code, and call these functions from C#. So, instead of the jslib file in the example above, you could have a C/C++ file in your project - it will automatically get compiled with your scripts, and you can call functions from it

Unityloader react, how with angular2 rc.6 disable sanitize on embed html tag which display pdf This one works for me. import { Component,Input,OnInit} from '@angular/core';  Add the Build folder of your Unity WebGL build inside the assets folder (or wherever you want). The library assets folder mmight not been added in the project's assets on build. If it happens just copy the projects/unity-angular/src/assets folder inside the project and merge it with your assets.

How to set <iframe src=“…”> without causing `unsafe value`, What I need to be able to do is communicate from Unity to Angular2. The function I am trying to call is inside of a service that looks like this: import Following the example from this SO question: Angular2 - how to call component function from outside the app I've I am new in Struts2 and and working on one project. import { SafePipeModule } from 'safe-pipe'; @NgModule({ imports: [ SafePipeModule ] }) export class AppModule { } Add the safe pipe to an element in the template for the Angular component you are importing into your NgModule this way: <element [property]="value | safe: sanitizationType"></element>

Call an Angular2 Function from Unity WebGL - c# - csharp, NET Core 3.0 to Build a React Client (Global Weather) - Part 1 In this article, we will convert our Angular 2 application to Angular 4 and replace the traditional Introduction to 3D with the HTML, CSS, JavaScript and three.js Net Core 2.0 and Angular 4 projects using CLI and Visual Studio Code - Beginners Tutorial  Hi ! I have to import UnityLoader.js in Angular using TypeScript. However, that lib don&#39;t have ts declaration and need configuration variable (array) to work (See below) . Link to UnityLoader.j

Comments
  • The './webgl-app/Build/UnityLoader.js' is imported, yet shouldn't it be declared as a variable? Such as import { UnityLoader } from './webgl-app/Build/UnityLoader.js';
  • Thanks for the suggestion! I tested this but I get the error on both that UnityLoader/UnityProgress is not a module.
  • Does the TemplateData/UnityProgress.js have any export declared functions? Only export-ed functions/variables can be imported afaik.
  • I managed to get the import work by adding export into the corresponding .json-files. After moving some of the webgl-app into the public assets-folder, I got it to almost run, but then the page says in a modal dialog: An error occured running the Unity content on this page. See your browser JavaScript console for more info. The error was: ReferenceError: UnityLoader is not defined It seems this dialog is launched by Unity and not Angular, so I guess it almost runs, since there's a long load time. But still no luck, it needs the UnityLoader declared somewhere.
  • @JuhanaPietariLehtiniemi You should post your solve as an answer so that this question can be marked complete.