Importing a Unity WebGL-project into an Angular2 component

天大地大妈咪最大 提交于 2019-12-05 10:16:32

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.

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>

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

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:

"scripts": [
  "unity/TemplateData/UnityProgress.js",
  "unity/Build/UnityLoader.js"
],

3) (optional) Add style.css to your angular.json styles

"styles": [
  "node_modules/font-awesome/css/font-awesome.css",
  "src/assets/theme.scss",
  "src/styles.scss",
  "unity/TemplateData/style.css"
],

4) Add the base Unity HTML to your component.html:

<div class="webgl-content">
  <div id="unityContainer" style="width: 960px; height: 600px"></div>
  <div class="footer">
    <div class="webgl-logo"></div>
    <div class="fullscreen" (click)="unityInstance.SetFullscreen(1)"></div>
    <div class="title">UnityProject</div>
  </div>
</div>

5) Lastly, instantiate your unityContainer in your component.ts:

import { Component, OnInit, AfterViewInit } from '@angular/core';
declare var UnityLoader: any;

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit, AfterViewInit {
  unityInstance: any;

  constructor() { }

  ngOnInit() { }

  ngAfterViewInit() {
    this.unityInstance = UnityLoader.instantiate("unityContainer", "assets/unity/unity.json");
  }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!