Search Unity

Question stacksave error trying to integrate webgl build with Angular 14

Discussion in 'Web' started by JohnParkerIngramBarge, Feb 9, 2024.

  1. JohnParkerIngramBarge

    JohnParkerIngramBarge

    Joined:
    May 11, 2023
    Posts:
    3
    Hi folks

    Let me say first that I am basically a noob with Angular.

    Anyway I've been trying for weeks to get a minimal Unity app running inside Angular 14. It works great when I just use the index.html and javascript that was output by the webgl build.

    Here's the output from Chrome's console log:

    upload_2024-2-9_13-29-16.png
    Code (CSharp):
    1. unitymap.loader.js:1 Assertion failed
    2. printErr @ unitymap.loader.js:1
    3. abort @ unitymap.framework.js:114
    4. assert @ unitymap.framework.js:951
    5. demangle @ unitymap.framework.js:2030
    6. (anonymous) @ unitymap.framework.js:2060
    7. demangleAll @ unitymap.framework.js:2058
    8. ErrnoError @ unitymap.framework.js:6985
    9. (anonymous) @ unitymap.framework.js:6992
    10. ensureErrnoError @ unitymap.framework.js:6991
    11. staticInit @ unitymap.framework.js:6996
    12. (anonymous) @ unitymap.framework.js:15600
    13. (anonymous) @ unitymap.loader.js:1
    14. invoke @ zone-evergreen.js:372
    15. onInvoke @ core.js:28591
    16. invoke @ zone-evergreen.js:371
    17. run @ zone-evergreen.js:134
    18. (anonymous) @ zone-evergreen.js:1275
    19. invokeTask @ zone-evergreen.js:406
    20. onInvokeTask @ core.js:28578
    21. invokeTask @ zone-evergreen.js:405
    22. runTask @ zone-evergreen.js:178
    23. drainMicroTaskQueue @ zone-evergreen.js:585
    24. invokeTask @ zone-evergreen.js:491
    25. invokeTask @ zone-evergreen.js:1661
    26. globalCallback @ zone-evergreen.js:1692
    27. globalZoneAwareCallback @ zone-evergreen.js:1725
    28. load (async)
    29. customScheduleGlobal @ zone-evergreen.js:1809
    30. scheduleTask @ zone-evergreen.js:393
    31. onScheduleTask @ zone-evergreen.js:283
    32. scheduleTask @ zone-evergreen.js:386
    33. scheduleTask @ zone-evergreen.js:221
    34. scheduleEventTask @ zone-evergreen.js:247
    35. (anonymous) @ zone-evergreen.js:1964
    36. desc.set @ zone-evergreen.js:825
    37. (anonymous) @ unitymap.loader.js:1
    38. ZoneAwarePromise @ zone-evergreen.js:1429
    39. x @ unitymap.loader.js:1
    40. (anonymous) @ unitymap.loader.js:1
    41. ZoneAwarePromise @ zone-evergreen.js:1429
    42. createUnityInstance @ unitymap.loader.js:1
    43. initializeUnityMap @ demo.component.ts:90
    44. ngAfterViewInit @ demo.component.ts:42
    45. callHook @ core.js:2573
    46. callHooks @ core.js:2542
    47. executeInitAndCheckHooks @ core.js:2493
    48. refreshView @ core.js:9551
    49. refreshComponent @ core.js:10651
    50. refreshChildComponents @ core.js:9277
    51. refreshView @ core.js:9530
    52. renderComponentOrTemplate @ core.js:9594
    53. tickRootContext @ core.js:10825
    54. detectChangesInRootView @ core.js:10850
    55. detectChanges @ core.js:22853
    56. tick @ core.js:29572
    57. _loadComponent @ core.js:29610
    58. bootstrap @ core.js:29546
    59. (anonymous) @ core.js:29245
    60. _moduleDoBootstrap @ core.js:29245
    61. (anonymous) @ core.js:29215
    62. invoke @ zone-evergreen.js:372
    63. onInvoke @ core.js:28591
    64. invoke @ zone-evergreen.js:371
    65. run @ zone-evergreen.js:134
    66. (anonymous) @ zone-evergreen.js:1275
    67. invokeTask @ zone-evergreen.js:406
    68. onInvokeTask @ core.js:28578
    69. invokeTask @ zone-evergreen.js:405
    70. runTask @ zone-evergreen.js:178
    71. drainMicroTaskQueue @ zone-evergreen.js:585
    72. Promise.then (async)
    73. nativeScheduleMicroTask @ zone-evergreen.js:561
    74. scheduleMicroTask @ zone-evergreen.js:572
    75. scheduleTask @ zone-evergreen.js:396
    76. scheduleTask @ zone-evergreen.js:221
    77. scheduleMicroTask @ zone-evergreen.js:241
    78. scheduleResolveOrReject @ zone-evergreen.js:1265
    79. then @ zone-evergreen.js:1461
    80. bootstrapModule @ core.js:29240
    81. zUnb @ main.ts:11
    82. __webpack_require__ @ bootstrap:79
    83. 0 @ main.js:11
    84. __webpack_require__ @ bootstrap:79
    85. checkDeferredModules @ bootstrap:45
    86. webpackJsonpCallback @ bootstrap:32
    87. (anonymous) @ main.js:1
    88. Show 59 more frames
    89. Show less
    90.  
    91. unitymap.loader.js:1 ERROR Error: Uncaught (in promise): TypeError: stackSave is not a function
    92. TypeError: stackSave is not a function
    93.     at withStackSave (unitymap.framework.js:2019:19)
    94.     at demangle (unitymap.framework.js:2031:14)
    95.     at unitymap.framework.js:2060:19
    96.     at String.replace (<anonymous>)
    97.     at demangleAll (unitymap.framework.js:2058:19)
    98.     at new ErrnoError (unitymap.framework.js:6985:26)
    99.     at unitymap.framework.js:6992:36
    100.     at Array.forEach (<anonymous>)
    101.     at Object.ensureErrnoError (unitymap.framework.js:6991:14)
    102.     at Object.staticInit (unitymap.framework.js:6996:12)
    103.     at unitymap.framework.js:15600:6
    104.     at unitymap.loader.js:1:20047
    105.     at _ZoneDelegate.invoke (zone-evergreen.js:372:1)
    106.     at Object.onInvoke (core.js:28591:1)
    107.     at _ZoneDelegate.invoke (zone-evergreen.js:371:1)
    108.     at Zone.run (zone-evergreen.js:134:1)
    109.     at zone-evergreen.js:1275:1
    110.     at _ZoneDelegate.invokeTask (zone-evergreen.js:406:1)
    111.     at Object.onInvokeTask (core.js:28578:1)
    112.     at _ZoneDelegate.invokeTask (zone-evergreen.js:405:1)
    113.     at Zone.runTask (zone-evergreen.js:178:1)
    114.     at drainMicroTaskQueue (zone-evergreen.js:585:1)
    115.     at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:491:1)
    116.     at invokeTask (zone-evergreen.js:1661:1)
    117.     at globalCallback (zone-evergreen.js:1692:1)
    118.     at HTMLScriptElement.globalZoneAwareCallback (zone-evergreen.js:1725:1)
    119.     at resolvePromise (zone-evergreen.js:1211:1)
    120.     at zone-evergreen.js:1282:1
    121.     at _ZoneDelegate.invokeTask (zone-evergreen.js:406:1)
    122.     at Object.onInvokeTask (core.js:28578:1)
    123.     at _ZoneDelegate.invokeTask (zone-evergreen.js:405:1)
    124.     at Zone.runTask (zone-evergreen.js:178:1)
    125.     at drainMicroTaskQueue (zone-evergreen.js:585:1)
    126.     at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:491:1)
    127.     at invokeTask (zone-evergreen.js:1661:1)
    128.     at globalCallback (zone-evergreen.js:1692:1)
    129.     at HTMLScriptElement.globalZoneAwareCallback (zone-evergreen.js:1725:1)
    Thank you in advance for any help.
     
  2. JohnParkerIngramBarge

    JohnParkerIngramBarge

    Joined:
    May 11, 2023
    Posts:
    3
    I just noticed that I didn't summarize and explicitly point out the error:


    unitymap.loader.js:1 ERROR Error: Uncaught (in promise): TypeError: stackSave is not a function
    TypeError: stackSave is not a function
     
  3. JohnParkerIngramBarge

    JohnParkerIngramBarge

    Joined:
    May 11, 2023
    Posts:
    3
    I was able to get it working. In case anyone else needs the solution, here are the important parts:

    Update to 2023.2.9

    Check Project Settings/Player/Use WebAssembly.Table true

    in your component html:

    Code (CSharp):
    1.  
    2. <div #unitycontainer id="unity-container">
    3. <canvas
    4.     #unitycanvas
    5.     id="unity-canvas"
    6.     width="960"
    7.     height="600"
    8.     tabindex="-1"
    9.   ></canvas>
    10.   <div #unityloadingbar id="unity-loading-bar">
    11.     <div #unitylogo id="unity-logo"></div>
    12.     <div #unityprogressbarempty id="unity-progress-bar-empty">
    13.       <div #unityprogressbarfull id="unity-progress-bar-full"></div>
    14.     </div>
    15.   </div>
    16.   <div #unitywarning id="unity-warning"></div>
    17.   <div #unityfooter id="unity-footer">
    18.     <div #unitylogotitlefooter id="unity-logo-title-footer"></div>
    19.     <div #unityfullscreenbutton id="unity-fullscreen-button"></div>
    20.     <div #unitybuildtitle id="unity-build-title">Unity Map</div>
    21.   </div>
    22. </div>
    in typings.d.ts:

    Code (CSharp):
    1.  
    2. declare var createUnityInstance: any;
    3.  
    4.  
    in your component class file:

    Code (CSharp):
    1.  
    2. export class UnityComponent implements OnInit, AfterViewInit {
    3.   @ViewChild('unitycontainer') unitycontainer: ElementRef;
    4.   @ViewChild('unitycanvas') unitycanvas: ElementRef;
    5.   @ViewChild('unityloadingbar') unityloadingbar: ElementRef;
    6.   @ViewChild('unityprogressbarfull') unityprogressbarfull: ElementRef;
    7.   @ViewChild('unityfullscreenbutton') unityfullscreenbutton: ElementRef;
    8.   @ViewChild('unitywarning') unitywarning: ElementRef;
    9.  
    10.   mUnityInstance: any = undefined;
    11.  
    and

    Code (CSharp):
    1.  
    2.   async ngAfterViewInit() {
    3.       this.InitializeUnity();
    4.   }
    5.  
    6.   InitializeUnity() {
    7.  
    8.     var buildUrl = 'assets/unityproject/Build';
    9.     var config = {
    10.       dataUrl: buildUrl + '/unityproject.data',
    11.       frameworkUrl: buildUrl + '/unityproject.framework.js',
    12.       codeUrl: buildUrl + '/unityproject.wasm',
    13.       streamingAssetsUrl: 'StreamingAssets',
    14.       companyName: 'some company',
    15.       productName: 'unityproject
    16.      productVersion: '0.1',
    17.      devicePixelRatio: 0
    18.    };
    19.    let container: HTMLElement = this.unitycontainer
    20.      .nativeElement as HTMLElement;
    21.    var canvas: HTMLElement = this.unitycanvas.nativeElement as HTMLElement;
    22.    var loadingBar: HTMLElement = this.unityloadingbar
    23.      .nativeElement as HTMLElement;
    24.    var progressBarFull: HTMLElement = this.unityprogressbarfull
    25.      .nativeElement as HTMLElement;
    26.    var fullscreenButton: HTMLElement = this.unityfullscreenbutton
    27.      .nativeElement as HTMLElement;
    28.    var mobileWarning: HTMLElement = this.unitywarning
    29.      .nativeElement as HTMLElement;
    30.    if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
    31.      console.log('log: mobile environment');
    32.      container.className = 'unity-mobile';
    33.      config.devicePixelRatio = 1;
    34.      mobileWarning.style.display = 'block';
    35.      setTimeout(() => {
    36.        mobileWarning.style.display = 'none';
    37.      }, 5000);
    38.    } else {
    39.      console.log('log: non-mobile environment');
    40.      canvas.style.width = '640px';
    41.      canvas.style.height = '320px';
    42.    }
    43.    loadingBar.style.display = 'block';
    44.    //@ts-ignore
    45.    createUnityInstance(canvas, config, (progress: any) => {
    46.      progressBarFull.style.width = 100 * progress + '%';
    47.    })
    48.      .then((unityInstance: any) => {
    49.        loadingBar.style.display = 'none';
    50.        fullscreenButton.onclick = () => {
    51.          unityInstance.SetFullscreen(1);
    52.        };
    53.        this.mUnityInstance = unityInstance;
    54.      })
    55.      .catch((message: any) => {
    56.        //alert(message);
    57.        console.error(message);
    58.      });
    59.  }
    60.  
     
    BlackSpider likes this.