Search Unity

WebGL - Screenshot

Discussion in 'WebGL' started by Forseti1, Jul 3, 2019.

  1. Forseti1

    Forseti1

    Joined:
    Mar 3, 2018
    Posts:
    8
    I'm using Unity 5.6.4 and I've got a game where you've got to find a bunch of stuff and when you find them all you go to a scene where there's confetti raining down and it says "you took xx:xx:xx" I want a button at the bottom where you click and it save a screenshot of the time taken. the game will be on a site and as an .exe. I've got the screenshot for the .exe version done and working its the downloading from webGL that isn't working. I know I need a .jslib to have the download function and then call that from the unity script.

    In Assets/Plugins I've got download.jslib
    Code (JavaScript):
    1. mergeInto(LibraryManager.library, {
    2.   Download: function (data, filename, type) {
    3.     var file = new Blob([data], {type: type});
    4.     if (window.navigator.msSaveOrOpenBlob) // IE10+
    5.         window.navigator.msSaveOrOpenBlob(file, filename);
    6.     else { // Others
    7.         var a = document.createElement("a"),
    8.                 url = URL.createObjectURL(file);
    9.         a.href = url;
    10.         a.download = filename;
    11.         document.body.appendChild(a);
    12.         a.click();
    13.         setTimeout(function() {
    14.             document.body.removeChild(a);
    15.             window.URL.revokeObjectURL(url);
    16.         }, 0);
    17.     }
    18.   }
    19.  
    20. });
    This is called in the unity file save_Screenshot.cs

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.Runtime.InteropServices;
    4. using UnityEngine;
    5.  
    6. public class Save_Screenshot : MonoBehaviour {
    7.  
    8.     [DllImport("__Internal")]
    9.     private static extern void Download(byte[] data, string filename, string type);
    10.  
    11.     private static Save_Screenshot instance;
    12.  
    13.     private Camera myCamera;
    14.     private bool takeScreenshot = false;
    15.  
    16.     private void Awake () {
    17.         instance = this;
    18.         myCamera = gameObject.GetComponent<Camera> ();
    19.     }
    20.  
    21.     private void TakeScreenshot(int width, int height){
    22.         myCamera.targetTexture = RenderTexture.GetTemporary (width, height, 16);
    23.         takeScreenshot = true;
    24.     }
    25.  
    26.     IEnumerator OnPostRender() {
    27.         if (takeScreenshot) {
    28.             yield return new WaitForEndOfFrame ();
    29.             takeScreenshot = false;
    30.             RenderTexture renderTexture = myCamera.targetTexture;
    31.  
    32.             Texture2D renderResult = new Texture2D (renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false);
    33.             Rect rect = new Rect (0, 0, renderTexture.width, renderTexture.height);
    34.             renderResult.ReadPixels (rect, 0, 0);
    35.  
    36.             byte[] byteArray = renderResult.EncodeToPNG ();
    37.             Download (byteArray, "Time Taken.png", "image/png");
    38.  
    39.             RenderTexture.ReleaseTemporary (renderTexture);
    40.             myCamera.targetTexture = null;
    41.         }
    42.     }
    43.  
    44.     public static void staticScreenshot(int width, int height){
    45.         instance.TakeScreenshot (width, height);
    46.     }
    47. }
    When i run this in editor to test it I get an error


    EntryPointNotFoundException: Download
    Save_Screenshot+<OnPostRender>c__Iterator0.MoveNext () (at Assets/Scripts/Save_Screenshot.cs:38)
    UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)


    Thinking this may be because I'm trying to do it in editor not on a browser I tried to build it but I got a error saying its failed its sanity check

    LSupport\\BuildTools\\emscripten.config_sanity'
    stderr:WARNING:root:did not see a source tree above or next to the LLVM root directory (guessing based on directory of C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten_FastComp_Win\llc), could not verify version numbers match
    INFO:root:(Emscripten: Running sanity checks)
    WARNING:root:java does not seem to exist, required for closure compiler, which is optional (define JAVA in C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\emscripten.config if you want it)
    WARNING:root:closure compiler will not be available
    WARNING:root:--separate-asm works best when compiling to HTML. otherwise, you must yourself load the '.asm.js' file that is emitted separately, and must do so before loading the main '.js` file
    error: failure to execute js library "L:\unity\Test\Assets\Plugins\test.jslib": SyntaxError: Unexpected token ILLEGAL,,SyntaxError: Unexpected token ILLEGAL at Object.LibraryManager.load (eval at globalEval (C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\src\compiler.js:105:8), <anonymous>:173:14) at JSify (eval at globalEval (C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\src\compiler.js:105:8), <anonymous>:59:20) at L:\unity\Test\Assets\Plugins\test.jslib (C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\src\compiler.js:208:3) at Module._compile (module.js:460:26) at Object.Module._extensions..js (module.js:478:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12) at Function.Module.runMain (module.js:501:10) at startup (node.js:129:16) at node.js:814:3preprocessed source (you can run a js engine on this to get a clearer error message sometimes):=============��m
    UnityEditor.HostView:OnGUI()

    And another error

    L/Extensions/Unity.WebGL.extensions/BuildPostprocessor.cs:437)
    UnityEditor.WebGL.WebGlBuildPostprocessor.PostProcess (BuildPostProcessArgs args) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/BuildPostprocessor.cs:877)
    UnityEditor.PostprocessBuildPlayer.Postprocess (BuildTargetGroup targetGroup, BuildTarget target, System.String installPath, System.String companyName, System.String productName, Int32 width, Int32 height, System.String downloadWebplayerUrl, System.String manualDownloadWebplayerUrl, BuildOptions options, UnityEditor.RuntimeClassRegistry usedClassRegistry, UnityEditor.BuildReporting.BuildReport report) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/PostprocessBuildPlayer.cs:186)
    UnityEditor.HostView:OnGUI()


    Any idea what I'm doing wrong?
     
  2. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    144
    It seems you'r JS code have a error. But i can't say where.

    here is what i use to download a file:
    Code (CSharp):
    1. [DllImport("__Internal")]
    2. private static extern void DownloadFile(byte[] array, int byteLength, string fileName);
    3.  
    4. //....
    5. byte[] imageData = screenShot.EncodeToJPG(); //screenShot is Texture2D
    6. string customFileName = "MyScreenshot.jpg";
    7. DownloadFile(imageData, imageData.Length, customFileName);
    My Jslib:
    Code (JavaScript):
    1. var DownloadFilePlugin = {
    2.   DownloadFile : function(array, size, fileNamePtr)
    3.   {
    4.     var fileName = UTF8ToString(fileNamePtr);
    5.     var bytes = new Uint8Array(size);
    6.     for (var i = 0; i < size; i++)
    7.     {
    8.        bytes[i] = HEAPU8[array + i];
    9.     }
    10.     var blob = new Blob([bytes]);
    11.     var link = document.createElement('a');
    12.     link.href = window.URL.createObjectURL(blob);
    13.     link.download = fileName;
    14.     var event = document.createEvent("MouseEvents");
    15.     event.initMouseEvent("click");
    16.     link.dispatchEvent(event);
    17.     window.URL.revokeObjectURL(link.href);
    18.   }
    19. };
    20. mergeInto(LibraryManager.library, DownloadFilePlugin);
     
    Last edited: Jul 4, 2019
  3. Forseti1

    Forseti1

    Joined:
    Mar 3, 2018
    Posts:
    8
    Used your code and got slightly different error

    Failed running "C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten_Win\python\2.7.5.3_64bit\python.exe" "C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emcc" @"L:\unity\Test\Assets\..\Temp\emcc_arguments.resp"

    stdout:WARNING: sanity check failed to run [Errno 13] Permission denied: 'C:\\Program Files\\Unity\\Editor\\Data\\PlaybackEngines\\WebGLSupport\\BuildTools\\emscripten.config_sanity'
    stderr:WARNING:root:did not see a source tree above or next to the LLVM root directory (guessing based on directory of C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten_FastComp_Win\llc), could not verify version numbers match
    INFO:root: (Emscripten: Running sanity checks)
    WARNING:root:java does not seem to exist, required for closure compiler, which is optional (define JAVA in C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\emscripten.config if you want it)
    WARNING:root:closure compiler will not be available
    WARNING:root:--separate-asm works best when compiling to HTML. otherwise, you must yourself load the '.asm.js' file that is emitted separately, and must do so before loading the main '.js` file
    error: failure to execute js library "L:\unity\Test\Assets\Plugins\download.jslib": SyntaxError: Unexpected token ILLEGAL,,SyntaxError: Unexpected token ILLEGAL at Object.LibraryManager.load (eval at globalEval (C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\src\compiler.js:105:8), <anonymous>:173:14) at JSify (eval at globalEval (C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\src\compiler.js:105:8), <anonymous>:59:20) at L:\unity\Test\Assets\Plugins\download.jslib (C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\src\compiler.js:208:3) at Module._compile (module.js:460:26) at Object.Module._extensions..js (module.js:478:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12) at Function.Module.runMain (module.js:501:10) at startup (node.js:129:16) at node.js:814:3preprocessed source (you can run a js engine on this to get a clearer error message sometimes):=============��v
    UnityEditor.BuildPlayerWindow:BuildPlayerAndRun()

    and

    Exception: Failed building WebGL Player.
    UnityEditor.WebGL.ProgramUtils.StartProgramChecked (System.Diagnostics.ProcessStartInfo p) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/ProgramUtils.cs:48)
    UnityEditor.WebGL.WebGlBuildPostprocessor.EmscriptenLink (BuildPostProcessArgs args, Boolean wasmBuild, System.String sourceFiles, System.String sourceFilesHash) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/BuildPostprocessor.cs:394)
    UnityEditor.WebGL.WebGlBuildPostprocessor.LinkBuild (BuildPostProcessArgs args) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/BuildPostprocessor.cs:437)
    UnityEditor.WebGL.WebGlBuildPostprocessor.PostProcess (BuildPostProcessArgs args) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/BuildPostprocessor.cs:877)
    UnityEditor.PostprocessBuildPlayer.Postprocess (BuildTargetGroup targetGroup, BuildTarget target, System.String installPath, System.String companyName, System.String productName, Int32 width, Int32 height, System.String downloadWebplayerUrl, System.String manualDownloadWebplayerUrl, BuildOptions options, UnityEditor.RuntimeClassRegistry usedClassRegistry, UnityEditor.BuildReporting.BuildReport report) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/PostprocessBuildPlayer.cs:186)
    UnityEditor.BuildPlayerWindow:BuildPlayerAndRun()
     
    Last edited: Jul 4, 2019
  4. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    144
    Last edited: Jul 4, 2019
  5. Forseti1

    Forseti1

    Joined:
    Mar 3, 2018
    Posts:
    8
    That's the only the only plugin in there, and I've checked all the other assets and only one has a plugins folder, and that contains a .cs that doesn't have an option to disable it for certain versions like that link said. I made another project just with that .jslib and script and it did manage to build, so there must be something I'm missing, but when I tried to use it, it threw an error saying I needed emscripten's linking support to use dlopen. But when I looked at https://docs.unity3d.com/560/Documentation/Manual/webgl-gettingstarted.html it says that Unity already uses emscripten, or is this some different part of it i need to download?
     
  6. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    206
    It sounds like you have one or more rogue characters in your script that's breaking the JavaScript parser.

    error: failure to execute js library "L:\unity\Test\Assets\Plugins\download.jslib": SyntaxError: Unexpected token ILLEGAL

    I don't see any weird characters in the script block above from a quick glance but you might have some characters before or after the code - just double check you copy-pasted it correctly.

    Some tips for finding it:
    https://stackoverflow.com/a/12719860
     
  7. Forseti1

    Forseti1

    Joined:
    Mar 3, 2018
    Posts:
    8
    I put the code in codepen.io and it didn't find any invisible characters.
     
  8. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    144
    I tested your code, and i can build the app without any problems.
    using Unity2019.1.5.f1
     
  9. Forseti1

    Forseti1

    Joined:
    Mar 3, 2018
    Posts:
    8
    I've got Unity 5.6.4 the problem could be that I'm just using an old version of Unity. I think I will just have to try talk work into getting Unity 2019
     
  10. Krieger56

    Krieger56

    Joined:
    Jul 25, 2019
    Posts:
    1
    WebGL (Web Graphics Library) is a JavaScript API for rendering interactive 3D and 2D graphics within any compatible web browser without the use of plug-ins.WebGL does so by introducing an API that closely conforms to OpenGL ES 2.0 that can be used in HTML5 <canvas> elements tutuapp software.
     
    Last edited: Jul 26, 2019