【问题标题】:Importing a Unity WebGL-project into an Angular2 component将 Unity WebGL 项目导入 Angular2 组件
【发布时间】:2017-05-11 15:02:57
【问题描述】:

我希望将 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>

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

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

然后我将 javascript 移到组件 .ts 文件中:

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 });
  }

}

然后对于 .html 模板,我留下了这个:

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

但是,无论我尝试什么方法(比如在 JS 文件上使用“require”),ngAfterViewInit 中的行总是给出错误:“参考错误:未定义 UnityLoader”。

这应该如何正确完成才能发挥作用?

【问题讨论】:

  • './webgl-app/Build/UnityLoader.js' 被导入了,但不应该声明为变量吗?如import { UnityLoader } from './webgl-app/Build/UnityLoader.js';
  • 感谢您的建议!我对此进行了测试,但我得到了 UnityLoader/UnityProgress 不是模块的错误。
  • TemplateData/UnityProgress.js 是否有任何export 声明的函数? afaik 只能导入 export-ed 函数/变量。
  • 我设法通过将导出添加到相应的 .json 文件中来完成导入工作。在将一些 webgl-app 移动到公共资产文件夹后,我几乎可以运行它,但随后页面在模式对话框中显示:在此页面上运行 Unity 内容时发生错误。有关更多信息,请参阅您的浏览器 JavaScript 控制台。错误是:ReferenceError: UnityLoader is not defined 这个对话框似乎是由 Unity 而不是 Angular 启动的,所以我猜它几乎运行了,因为加载时间很长。但仍然没有运气,它需要在某处声明 UnityLoader。
  • @JuhanaPietariLehtiniemi 您应该将您的解决方案发布为答案,以便可以将此问题标记为完成。

标签: javascript angular typescript unity3d unity-webgl


【解决方案1】:

将 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"
],

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"
],

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>

5) 最后,在 component.ts 中实例化 unityContainer

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");
  }

}

【讨论】:

    【解决方案2】:

    所以我一直在搞砸这个......

    我使用 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);
     });
    }
    

    }

    在 typings.d.ts 中我扩展了 window 元素。

    interface Window {
      unity: any;
    }
    

    所以,当我从 unity 拨打电话时,我会这样称呼它

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

    我现在缺少的只是团结的呼唤……也许你对这个有想法?

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

    【讨论】:

      【解决方案3】:

      我将 Unity WebGL 输出简化为

      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>
      

      并将其加载到 iframe 中。这给了你一个

      unsafe value used in a resource URL context
      

      错误。这可以通过使用特殊的 iframe Angular 组件来解决。

      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>
      

      感谢 Lrodriguez84: https://stackoverflow.com/a/50863439/719528

      然后只需添加那个特殊的 iframe 组件,将那个 HTML 文件传递​​给你希望 Unity 项目出现的任何地方!

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

      【讨论】:

        【解决方案4】:

        我也陷入了困境。

        好像你的上下文没有设置

        $.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
        });
        

        解决方案:

        $.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));
        

        更多信息:https://docs.unity3d.com/2018.3/Documentation/Manual/webgl-interactingwithbrowserscripting.html

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-01-07
          • 2018-06-20
          • 2015-03-15
          • 1970-01-01
          • 2017-01-23
          • 1970-01-01
          • 1970-01-01
          • 2017-01-09
          相关资源
          最近更新 更多