Search Unity

User image download from in webgl app

Discussion in 'Web' started by andyz, Jun 7, 2017.

  1. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,269
    Looking to let a user export a screenshot or other image from within a webgl app so I want to give a user the contents of a Texture2D in effect.
    As much a js/php question as Unity really

    Now I can save image to a server and then direct them to the URL but seems very wasteful when the data is to hand so can it be done another way?
     
  2. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    242
    I use megagrab for this. Aviable in the asset store. Works perfect for HiRes screenshot downloads, or upload them direct to a defined location.
     
  3. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,269
    Yes but does not handle download through webgl right? It is not hard to do the grab part with a Render Texture, its offering to download.
    Guess it may have to be uploaded to a URL and the user pointed to that
     
  4. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    242
    my solution for webGL: Megagrab to create the screenshot, and following code to download it:
    Code (CSharp):
    1.     [DllImport("__Internal")]
    2.     private static extern void ImageDownloader(string str, string fn);
    3.  
    4.     public static byte[] ssData = null;
    5.     public static string imageFilename = "";
    6.     void DownloadScreenshot ()
    7.     {
    8.         if(ssData != null)
    9.         {
    10.             Debug.Log("Downloading..."+imageFilename);
    11.             ImageDownloader(System.Convert.ToBase64String(imageData), imageFilename);
    12.         }
    13.     }

    .jslib in the Assets/Plugins folder: (ImageDownloader.jslib)
    Code (JavaScript):
    1. var ImageDownloaderPlugin = {
    2.   ImageDownloader: function(str, fn) {
    3.       var msg = Pointer_stringify(str);
    4.       var fname = Pointer_stringify(fn);
    5.       var contentType = 'image/jpeg';
    6.       function fixBinary (bin)
    7.       {
    8.         var length = bin.length;
    9.         var buf = new ArrayBuffer(length);
    10.         var arr = new Uint8Array(buf);
    11.         for (var i = 0; i < length; i++)
    12.         {
    13.               arr[i] = bin.charCodeAt(i);
    14.         }
    15.         return buf;
    16.       }
    17.       var binary = fixBinary(atob(msg));
    18.       var data = new Blob([binary], {type: contentType});
    19.       var link = document.createElement('a');
    20.     link.download = fname;
    21.     link.innerHTML = 'DownloadFile';
    22.     link.setAttribute('id', 'ImageDownloaderLink');
    23.     if(window.webkitURL != null)
    24.     {
    25.         link.href = window.webkitURL.createObjectURL(data);
    26.     }
    27.     else
    28.     {
    29.         link.href = window.URL.createObjectURL(data);
    30.         link.onclick = function()
    31.         {
    32.             var child = document.getElementById('ImageDownloaderLink');
    33.             child.parentNode.removeChild(child);
    34.         };
    35.         link.style.display = 'none';
    36.         document.body.appendChild(link);
    37.     }
    38.     link.click();
    39.   }
    40. };
    41. mergeInto(LibraryManager.library, ImageDownloaderPlugin);
     
    Last edited: Jun 8, 2017
    Alex-CG and andyz like this.
  5. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,269
    thanks was having trouble finding something like that, will give it a try
     
  6. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    340
    Thanks A LOT for the heads up, sumpfkraut, you just saved me a lot of headaches !
     
  7. guneyozsan

    guneyozsan

    Joined:
    Feb 1, 2012
    Posts:
    99
    Thanks for the solution. Does anyone have an idea to convert/expand this to a generic file downloader to cover other content types like doc, pdf...etc.? I'm not a Javascript coder but when I skimmed the code I couldn't find anything image specific except the content type. Any ideas?
     
  8. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    214
    This is the one I use personally for different file types. You simply pass it a byte[] array, the length of the byte array and the desired file name.

    The mouse event is a little bit of a hack to get it to download but otherwise it's fairly simple code.

    Code (JavaScript):
    1. DownloadFile : function(array, size, fileNamePtr)
    2. {
    3.     var fileName = UTF8ToString(fileNamePtr);
    4.  
    5.     var bytes = new Uint8Array(size);
    6.     for (var i = 0; i < size; i++)
    7.     {
    8.        bytes[i] = HEAPU8[array + i];
    9.     }
    10.  
    11.     var blob = new Blob([bytes]);
    12.     var link = document.createElement('a');
    13.     link.href = window.URL.createObjectURL(blob);
    14.     link.download = fileName;
    15.  
    16.     var event = document.createEvent("MouseEvents");
    17.     event.initMouseEvent("click");
    18.     link.dispatchEvent(event);
    19.     window.URL.revokeObjectURL(link.href);
    20. }
    C# example in case of a screenshot (CaptureScreenshotAsTexture introduced in 2018.1 function I believe):

    Code (CSharp):
    1. [DllImport("__Internal")]
    2. private static extern void DownloadFile(byte[] array, int byteLength, string fileName);
    3.  
    4. var texture = ScreenCapture.CaptureScreenshotAsTexture();
    5. byte[] textureBytes = texture.EncodeToPNG();
    6. DownloadFile(textureBytes, textureBytes.Length, "screenshot.png");
    7. Destroy(texture);

    I used a PNG here but it works for any file type. No base64 string conversion needed.
     
    Last edited: Jan 31, 2020
    mgear, Nyanpas, quarksrule and 7 others like this.
  9. Malkyne

    Malkyne

    Joined:
    Nov 18, 2009
    Posts:
    39
    I just tested JJJohan's solution, and I give it high marks. I was replacing a hacky no-longer-working solution from 2015, and this simplified my code substantially.
     
  10. brnkhy

    brnkhy

    Joined:
    Oct 12, 2015
    Posts:
    6
    I tried both solutions, even in an empty project using 2018.3.5f1 and my images comes up pitch black (I believe transparent if it's png). sumpfkraut , JJJohan do you have any ideas what might be wrong?
    I tried a lot of stuff past few hours but couldn't get it to work so had to ask at this point :(
     
  11. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    242
    both examples are still working. you are sure your byte array is correct?
     
  12. brnkhy

    brnkhy

    Joined:
    Oct 12, 2015
    Posts:
    6
    I just tried again using exact same js you posted and;
    Code (CSharp):
    1. public void DownloadScreenshot()
    2.         {
    3.             var texture = ScreenCapture.CaptureScreenshotAsTexture();
    4.             byte[] textureBytes = texture.EncodeToJPG();
    5.             ImageDownloader(System.Convert.ToBase64String(textureBytes), imageFilename);
    6.         }
    byte array looks good in editor, I mean I see some values which shouldn't be the case with pitch black image. I'm using .net 4.x runtime and api compatibility level. managed stripping level is low. tried using both asm and web assembly.

    edit: this is an empty project so there is no other scripts, post processing or fancy camera stuff.
     
    Last edited: Mar 9, 2019
  13. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    214
    I see that you are encoding the data as base64 before sending it to the jslib. If you're using the jslib snippet I posted then that won't work, as it expects you to just pass the byte array as such:

    Code (CSharp):
    1. [DllImport("__Internal")]
    2. private static extern void DownloadFile(byte[] array, int byteLength, string fileName);
    3.  
    4. private void DownloadScreenshot()
    5. {
    6.     Texture2D texture = ScreenCapture.CaptureScreenshotAsTexture();
    7.     byte[] textureBytes = texture.EncodeToJPG();
    8.     DownloadFile(textureBytes, textureBytes.Length, "screenshot.jpg");
    9.     Destroy(texture);
    10. }
    I've slightly modified my jslib snippet a few posts above so it cleans up better and uses Utf8ToString since it looks like Pointer_Stringify is deprecated in newer Emscripten versions.
     
  14. brnkhy

    brnkhy

    Joined:
    Oct 12, 2015
    Posts:
    6
    I tried your version before and again today but I'm getting same results. At this point I'm pretty sure it's not code related but there's something else (locale? unity/build settings? version?). Thanks a lot to you both for responding guys, I really appreciate it. I'll post again if I can find the issue :(

    Edit: actually I just tried it on a totally different machine with EN-US locale (I'm saying this as I had problems with that before) and had the same result. I'm totally confused now.
     
    Last edited: Mar 10, 2019
  15. brnkhy

    brnkhy

    Joined:
    Oct 12, 2015
    Posts:
    6
    Edit: It all works now, I think it was because of my wrong wait till end of frame part I never checked. Can't believe how many hours I wasted on that :( Thanks again for all the help!
     
    Last edited: Mar 11, 2019
  16. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    242
    and if you want a upscaled screenshot, you can try this:
    Code (CSharp):
    1.     IEnumerator RecordUpscaledFrame(int screenshotUpscale)
    2.     {
    3.         yield return new WaitForEndOfFrame();
    4.         int resWidthN = Camera.main.pixelWidth * screenshotUpscale;
    5.         int resHeightN = Camera.main.pixelHeight * screenshotUpscale;
    6.         string dateFormat = "dd-MM-yyyy-HH-mm-ss";
    7.  
    8.         RenderTexture rt = new RenderTexture(resWidthN, resHeightN, 24);
    9.         Camera.main.targetTexture = rt;
    10.         TextureFormat tFormat = TextureFormat.RGB24;
    11.         Texture2D screenShot = new Texture2D(resWidthN, resHeightN, tFormat, false);
    12.         Camera.main.Render();
    13.         RenderTexture.active = rt;
    14.         screenShot.ReadPixels(new Rect(0, 0, resWidthN, resHeightN), 0, 0);
    15.         Camera.main.targetTexture = null;
    16.         RenderTexture.active = null;
    17.         byte[] bytes = screenShot.EncodeToJPG();
    18.         string filename = resWidthN.ToString() + "x" + resHeightN.ToString() + "px_" + System.DateTime.Now.ToString(dateFormat);
    19.         Object.Destroy(rt);
    20.         Object.Destroy(screenShot);
    21.     }
     
  17. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    214
    Alternatively, Screenshot.CaptureScreenshotAsTexture has an integer parameter overload to set the resolution scale ;).
     
  18. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    242
  19. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    214
    Interesting, I figured it'd be a bit more useful than simply scaling the existing output. Good to know, thanks.
     
  20. tersi

    tersi

    Joined:
    Feb 2, 2018
    Posts:
    4
    boa noite pessoal alguem tem um passo a passo de como fazer isso, estou começando
     
  21. creeperart

    creeperart

    Joined:
    Jan 9, 2020
    Posts:
    1
    Hi,

    thank you very much for these informations! Exactly what I was looking for and very useful!
    Unfortunately I can't make it work for me. Are these examples still working?

    But maybe I'm just too stupid to make it work, I've never dealt with jslib files or anything like that :D

    So this is how I'm trying to make it work:


    1. I'm creating a .jslib file called DownloadFile.jslib which I place under /assets/plugins and which looks like this :

    Code (JavaScript):
    1. var DownloadFile = {
    2.     DownloadFile : function(array, size, fileNamePtr)
    3.     {
    4.         var fileName = UTF8ToString(fileNamePtr);
    5.    
    6.         var bytes = new Uint8Array(size);
    7.         for (var i = 0; i < size; i++)
    8.         {
    9.            bytes[i] = HEAPU8[array + i];
    10.         }
    11.    
    12.         var blob = new Blob([bytes]);
    13.         var link = document.createElement('a');
    14.         link.href = window.URL.createObjectURL(blob);
    15.         link.download = fileName;
    16.    
    17.         var event = document.createEvent("MouseEvents");
    18.         event.initMouseEvent("click");
    19.         link.dispatchEvent(event);
    20.         window.URL.revokeObjectURL(link.href);
    21.         link.parentNode.removeChild(link);
    22.     }
    23. };
    2. I create a C# Script in Unity which looks like this:

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Runtime.InteropServices;
    5. using UnityEngine;
    6.  
    7. public class DownloadImage : MonoBehaviour
    8. {
    9.     public Texture2D img;
    10.  
    11.  
    12.     void Start()
    13.     {
    14.         img = this.GetComponent<CreateColorShapePC>().img;
    15.     }
    16.  
    17.  
    18.     [DllImport("__Internal")]
    19.     private static extern void DownloadFile(byte[] array, int byteLength, string fileName);
    20.  
    21.     public void DownloadSaved()
    22.     {
    23.         Texture2D texture = img;
    24.         byte[] textureBytes = texture.EncodeToJPG();
    25.         DownloadFile(textureBytes, textureBytes.Length, "image.jpg");
    26.         Destroy(texture);
    27.     }
    28.  
    29. }
    (I want to let the user download an image (img) which is created in another script (CreateColorShapePC)).


    3. I create a button which calls the function DownloadSaved().

    Is this how you make it work? Because in my case it always gives me an Error, when I try it online.


    I'm very thankful for any help!! :)
     
    Last edited: Jan 15, 2020
  22. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    214
    We'd have to know what the error is to figure out the problem. If your texture doesn't exist (is null) that'll definitely be a problem. It might also be a problem if you intend to keep using the texture after you hit the button and you might want to remove the Destroy(texture) line in that case.
     
  23. ignus2

    ignus2

    Joined:
    Jan 31, 2020
    Posts:
    1
    Thanks for the script, it works wonderfully, with a small change. The last line
    Code (JavaScript):
    1. link.parentNode.removeChild(link);
    had to be removed, link.parentNode was null. I suppose because the link was never added to the DOM, it was detached, hence had no parent.
     
  24. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    214
    Ah, nice find. Interestingly my browser must have silently ignored it - I've edited my original post to prevent confusing anyone else.
     
  25. roypon11

    roypon11

    Joined:
    Feb 5, 2018
    Posts:
    4
  26. jra8908

    jra8908

    Joined:
    Apr 1, 2018
    Posts:
    7
    Currently trying to get the sample by JJJohan to work. Been debugging for a while now and my problem is that the picture downloaded is the right size, but all black? The data just before sending it to the jslib is correct. I've tried printing out the image data and displaying it in the browser as Base64 which works (not using Base64 in the code).

    Any ideas?

    EDIT: Interestingly, when I run the game in the Editor and print the Base64 of the image in C#, it gets one value. But when I run it in the browser using WebGL the exact same printout is suddenly a completely different Base64 string... The first string can be put in a data string and the image can be viewed, while the other one is black.

    EDIT2: In the end I couldn't solve it and had to resolve to using a package from the Asset Store so I could progress. Will have to back to this issue at another time. The package did resolve it however (Screenshot Companion).
     
    Last edited: Mar 18, 2020
  27. Realgar

    Realgar

    Joined:
    Sep 30, 2012
    Posts:
    52
    Hi jra8908, I have the same problem than you, and I 'm going to use the same asset; Screenshot Companion. Did you managed to use it to solve the black screen ? How did you get the picture from the asset API ?
    Thank's a lot if you can help me !
     
  28. nateonus

    nateonus

    Joined:
    Mar 20, 2018
    Posts:
    3
    I created a free-to-use plugin for anyone wanting to save/download a generic file in WebGL. It works seamlessly with all major browsers and operating systems, and is as simple as calling 'WebGLFileSaver.SaveFile()'.

    Get it here: https://github.com/nateonusapps/WebGLFileSaverForUnity
     
    mgear likes this.
  29. NuclearFriend

    NuclearFriend

    Joined:
    Aug 13, 2015
    Posts:
    14
    I just solved this myself and so wanted to respond to you (and also jra8908), I think the issue you were running into was that WebGL was not rendering the image out properly with CaptureScreenshotAsTexture. It's better to put it in a coroutine and do a WaitForEndOfFrame yield. I've fixed JJJohan's code for you below:

    Code (CSharp):
    1. [DllImport("__Internal")]
    2. private static extern void DownloadFile(byte[] array, int byteLength, string fileName);
    3.  
    4. public IEnumerator DownloadScreenshot()
    5. {
    6.     yield return new WaitForEndOfFrame();
    7.     Texture2D texture = ScreenCapture.CaptureScreenshotAsTexture(1);
    8.     byte[] textureBytes = texture.EncodeToJPG();
    9.     DownloadFile(textureBytes, textureBytes.Length, "screenshot.jpg");
    10.     Destroy(texture);
    11. }
    12.  
    13. void Update()
    14. {
    15.     // Example of how to call the coroutine
    16.     if (Input.GetKeyDown(KeyCode.S))
    17.     {
    18.         StartCoroutine(DownloadScreenshot());
    19.     }
    20. }
     
    CeciRuiz likes this.
  30. daphifluffi

    daphifluffi

    Joined:
    Dec 19, 2020
    Posts:
    3
    This plugin works like a charm! Thank you very much for making it available! I managed to export an .fbx file of my gameobject that is instantiated at runtime in my WebGL build. This works like
    Code (CSharp):
    1. EditorUtility.SaveFilePanel($"Export {objectToExport} as .fbx", "", objectToExport.name + ".fbx", "fbx");
    in Editor.
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityFBXExporter;
    3.  
    4. public class WebGLBuildFBXExportAtRuntime : MonoBehaviour
    5. {
    6. //fbx exporter package by https://github.com/KellanHiggins/UnityFBXExporter
    7. // webgl file saver plugin by https://github.com/nateonusapps/WebGLFileSaverForUnity
    8. //make sure that the objectToExport has a MeshFilter and MeshRenderer Component with some Material assigned to it
    9. // it does not have to have its own mesh, the meshes of children will be exported with their respective material colors
    10. [SerializeField] private GameObject objectToExport;
    11. [SerializeField] private Material someMaterial;
    12.  
    13. public void DownloadFBX()
    14. {
    15. // to assign a material, skip this if you already have one
    16. objectToExport.GetComponent<MeshRenderer>().material = someMaterial;
    17. string content = FBXExporter.MeshToString(objectToExport, null, true, true);
    18. // octet-stream is the right MIME Type for fbx files
    19. WebGLFileSaver.SaveFile(content, "myAmazingObject.fbx", "application/octet-stream");
    20. }
    21. }
    To use it with a UI Download Button, you can attach this class to your button and access the public "DownloadFBX()" function in the OnClick event.

    It took me a couple of days to figure this out. I hope it benefits someone in the same situation :)
     
    Blarp likes this.
  31. DustyofPodunk

    DustyofPodunk

    Joined:
    Feb 28, 2013
    Posts:
    12
    Would you know by chance how to get this setup to download a Png? I keep getting nothing when I try and use this
     
  32. DustyofPodunk

    DustyofPodunk

    Joined:
    Feb 28, 2013
    Posts:
    12
    I have been bashing my head against this for hours how do you set up the MegaGrab portion
     
  33. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    242
    byte[] bytes = screenShot.EncodeToJPG(); //JPG
    byte[] bytes = screenShot.EncodeToPNG(); // PNG

    c#
    Code (CSharp):
    1. [DllImport("__Internal")]
    2. public static extern void DownloadFile(byte[] array, int byteLength, string fileName);
    3.  
    4. IEnumerator RecordUpscaledFrame(int screenshotUpscale)
    5. {
    6. yield return new WaitForEndOfFrame();
    7. int resWidthN = Camera.main.pixelWidth * screenshotUpscale;
    8. int resHeightN = Camera.main.pixelHeight * screenshotUpscale;
    9. string dateFormat = "yyyy-MM-dd-HH-mm-ss";
    10. string filename = resWidthN.ToString() + "x" + resHeightN.ToString() + "px_" + System.DateTime.Now.ToString(dateFormat);
    11. Texture2D screenShot = ScreenCapture.CaptureScreenshotAsTexture(screenshotUpscale);
    12. byte[] texture = screenShot.EncodeToPNG();
    13. DownloadFile(texture, texture.Length, filename + ".png");
    14. Object.Destroy(screenShot);
    15. }
    16.  
    DownloadFile.jslib
    Code (JavaScript):
    1. var DownloadFilePlugin = {
    2.     DownloadFile : function(array, size, fileNamePtr)
    3.     {
    4.         var fileName = UTF8ToString(fileNamePtr);
    5.  
    6.         var bytes = new Uint8Array(size);
    7.         for (var i = 0; i < size; i++)
    8.         {
    9.            bytes[i] = HEAPU8[array + i];
    10.         }
    11.  
    12.         var blob = new Blob([bytes]);
    13.         var link = document.createElement('a');
    14.         link.href = window.URL.createObjectURL(blob);
    15.         link.download = fileName;
    16.  
    17.         var event = document.createEvent("MouseEvents");
    18.         event.initMouseEvent("click");
    19.         link.dispatchEvent(event);
    20.         window.URL.revokeObjectURL(link.href);
    21.     }
    22. };
    23. mergeInto(LibraryManager.library, DownloadFilePlugin);
     
    ROBYER1 likes this.
  34. DustyofPodunk

    DustyofPodunk

    Joined:
    Feb 28, 2013
    Posts:
    12
     
  35. DustyofPodunk

    DustyofPodunk

    Joined:
    Feb 28, 2013
    Posts:
    12
    I tried what you posted and am getting nothing
    https://fracturedroguestudios.com/PrintTest31/index.html

    I made a simple script that houses the Ienumerator and has a call in it to startthe coroutine


    [DllImport("__Internal")]
    public static extern void DownloadFile(byte[] array, int byteLength, string fileName);

    IEnumerator RecordUpscaledFrame(int screenshotUpscale)
    {
    yield return new WaitForEndOfFrame();
    int resWidthN = Camera.main.pixelWidth * screenshotUpscale;
    int resHeightN = Camera.main.pixelHeight * screenshotUpscale;
    string dateFormat = "yyyy-MM-dd-HH-mm-ss";
    string filename = resWidthN.ToString() + "x" + resHeightN.ToString() + "px_" + System.DateTime.Now.ToString(dateFormat);
    Texture2D screenShot = ScreenCapture.CaptureScreenshotAsTexture(screenshotUpscale);
    byte[] texture = screenShot.EncodeToPNG();
    DownloadFile(texture, texture.Length, filename + ".png");
    Object.Destroy(screenShot);
    }

    public void RunRecordUpscaledFrame()
    {
    StartCoroutine("RecordUpscaledFrame(1)");
    }

    than a button calls the runrecordupscaledframe on click



     
  36. DustyofPodunk

    DustyofPodunk

    Joined:
    Feb 28, 2013
    Posts:
    12
    How would you set this up for a PNG or a JPG I got it downloading but when I open the downloaded file there is nothing there
     
    DrSharky likes this.
  37. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    242
  38. DustyofPodunk

    DustyofPodunk

    Joined:
    Feb 28, 2013
    Posts:
    12
    That seems to work only question I have is why the clear flag dosent come with it but thats a triffle that can be dealt with thank you so much
     
  39. HasithaCJ

    HasithaCJ

    Joined:
    May 20, 2017
    Posts:
    11
  40. erikvenhues

    erikvenhues

    Joined:
    Dec 4, 2020
    Posts:
    2

    thanks for that :)
    unfornatly that isnt working with PNG / JPG as its downloading everything only in UTF-8 String.
    Anyway i would like to give you my little upgrade for exporting FBX with all Childrens.


    using UnityEngine;
    using UnityFBXExporter;
    using System.IO;
    using System.Runtime.InteropServices;
    using System;
    using System.Text;


    public class EXPORTFBX1 : MonoBehaviour
    {

    public GameObject objectToExport;


    public void DownloadFBX()
    {


    string path = Path.Combine(Application.streamingAssetsPath, "data");
    path = Path.Combine(path, "eled-screen"+ ".fbx");




    if (!Directory.Exists(Path.GetDirectoryName(path)))
    {
    Directory.CreateDirectory(Path.GetDirectoryName(path));
    }

    FBXExporter.ExportGameObjToFBX(objectToExport, path, false, false);

    //string content = FBXExporter.MeshToString(objectToExport, null, true, true);

    var bytes = System.IO.File.ReadAllBytes(path);

    string encodedText = Encoding.UTF8.GetString (bytes);
    //most important, cause Base64 Conversation doesnt work with this WEBGLFileSaver Plugin.

    Debug.Log (encodedText);

    // octet-stream is the right MIME Type for fbx files
    WebGLFileSaver.SaveFile(encodedText, "eled-screen-3dmodel.fbx", "application/octet-stream");

    }
    }
     
  41. Davon92

    Davon92

    Joined:
    Oct 24, 2014
    Posts:
    17
    im looking to create and download a zip file that contains an image and a text file could webglfilesaver do that? how?
     
  42. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,454
    Worked a treat for me, thanks!
     
  43. Blarp

    Blarp

    Joined:
    May 13, 2014
    Posts:
    269
    User customizes an Avatar on WebGL Mobile, clicks download, model converts to GLTF, then you can load it natively in Augmented Reality or share the gltf model through native share.

    This could be a really powerful tool for that. @jonas-echterhoff tagging you, because this use case could really bring in a lot of eyeballs with AR.