将Unity WebGL项目导入Angular2组件

Juh*_*emi 5 javascript unity-game-engine typescript unity-webgl angular

我希望将Unity WebGL项目集成到Angular2应用程序中。将所有这些脚本移至Angular2组件的正确方法是什么?

首先,Unity WebGL像这样导出index.html:

<!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>
Run Code Online (Sandbox Code Playgroud)

我开始拆分,首先将样式表移动到模板.css文件中:

@import './webgl-app/TemplateData/style.css';
Run Code Online (Sandbox Code Playgroud)

然后,我将javascript移至组件.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 });
  }

}
Run Code Online (Sandbox Code Playgroud)

然后对于.html模板,我将其保留为:

<div class="webgl-content">
  <div id="gameContainer" style="width: 960px; height: 600px"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

但是,无论我尝试哪种方法(例如,在JS文件上使用'require'),ngAfterViewInit中的行始终会给出错误:“参考错误:未定义UnityLoader”。

应该如何正确地做到这一点才能起作用?

Z. *_*ley 5

要将 Unity WebGL 添加到您的项目:

1) 将 WebGL 项目导出到Angular 项目根目录中的/unity文件夹(与 src 同一级别)。将以下文件从 Build 文件夹复制到/src/assets/unity

  • unity.json
  • unity.data.unityweb
  • unity.wasm.code.unityweb
  • unity.wasm.framework.unityweb

统一构建文件

2) 将UnityProgress.jsUnityLoader.js添加到angular.json脚本中:

"scripts": [
  "unity/TemplateData/UnityProgress.js",
  "unity/Build/UnityLoader.js"
],
Run Code Online (Sandbox Code Playgroud)

3)(可选)将style.css添加到您的angular.json样式中

"styles": [
  "node_modules/font-awesome/css/font-awesome.css",
  "src/assets/theme.scss",
  "src/styles.scss",
  "unity/TemplateData/style.css"
],
Run Code Online (Sandbox Code Playgroud)

4) 将基本 Unity HTML 添加到您的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>
Run Code Online (Sandbox Code Playgroud)

5)最后,unityContainer在你的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");
  }

}
Run Code Online (Sandbox Code Playgroud)


jon*_*nny 3

所以我很长时间都在搞这个......

我使用 angular/cli@latest 1.6.5 启动并运行它

这是我的 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);
 });
}
Run Code Online (Sandbox Code Playgroud)

}

在typings.d.ts中,我扩展了窗口元素。

interface Window {
  unity: any;
}
Run Code Online (Sandbox Code Playgroud)

所以当我从统一中打电话时,我这样称呼它

Application.ExternalCall("unity.GetUnityNumber", rnd);
Run Code Online (Sandbox Code Playgroud)

我现在所缺少的就是团结起来……也许你对此有什么想法?

我将 unity-build 作为私有 npm 包。构建时,所有内容都会复制到资产文件夹中。