EditorUtility.OpenFilePanel for Unity WebGL (Runtime)

I want the user to select an image from a computer in a Unity WebGL game, but I cannot get any library or code for this thing. I want the exact functionality of EditorUtility.OpenFilePanel for UnityWebGL (Runtime).

string path = EditorUtility.OpenFilePanel ("Overwrite with png", "," png ");

Is there any way to open this open dialog in Unity WebGL build? Or can I do this in a java script? How do I get an image in java-script from a user and pass it to my C # code.

+5
source share
2 answers

It may seem simple, but it’s actually quite difficult to do, and the reason is that the WebGL assembly works in the browser and is subject to many security restrictions, among other things, restricts its access to the local file system. This can be done in a hacked way.

The idea is to use HTML file input to open a file view dialog box. We can call it from Unity code using ExternalEval, see here: http://docs.unity3d.com/Manual/UnityWebPlayerandbrowsercommunication.html http://docs.unity3d.com/ScriptReference/Application.ExternalEval.html

, . , , , .

, , , ? . - , Unity , , , javascript. , , http://docs.unity3d.com/Manual/webgl-cursorfullscreen.html, , Unity .

, : + , ? - HTML-, . , , UP , HTML, . , , . javascript, , Unity SendMessage http://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html. -.

, . , . , , . , , URL- blob URL.CreateObjectURL, , http://caniuse.com/#search=createobjecturl

WWW , , URL .

, , . , .

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;

public class OpenFileDialog : MonoBehaviour, IPointerDownHandler {

    public Renderer preview;
    public Text text;

    void Start() {
        Application.ExternalEval(
            @"
document.addEventListener('click', function() {

    var fileuploader = document.getElementById('fileuploader');
    if (!fileuploader) {
        fileuploader = document.createElement('input');
        fileuploader.setAttribute('style','display:none;');
        fileuploader.setAttribute('type', 'file');
        fileuploader.setAttribute('id', 'fileuploader');
        fileuploader.setAttribute('class', 'focused');
        document.getElementsByTagName('body')[0].appendChild(fileuploader);

        fileuploader.onchange = function(e) {
        var files = e.target.files;
            for (var i = 0, f; f = files[i]; i++) {
                window.alert(URL.createObjectURL(f));
                SendMessage('" + gameObject.name +@"', 'FileDialogResult', URL.createObjectURL(f));
            }
        };
    }
    if (fileuploader.getAttribute('class') == 'focused') {
        fileuploader.setAttribute('class', '');
        fileuploader.click();
    }
});
            ");
    }

    public void OnPointerDown (PointerEventData eventData)  {
        Application.ExternalEval(
            @"
var fileuploader = document.getElementById('fileuploader');
if (fileuploader) {
    fileuploader.setAttribute('class', 'focused');
}
            ");
    }

    public void FileDialogResult(string fileUrl) {
        Debug.Log(fileUrl);
        text.text = fileUrl;
        StartCoroutine(PreviewCoroutine(fileUrl));
    }

    IEnumerator PreviewCoroutine(string url) {
        var www = new WWW(url);
        yield return www;
        preview.material.mainTexture = www.texture;
    }
}

- , , . , .

+10

. , , . : WWW-, ExternalEval .

( ), .

, , :

Javascript- .jslib "Plugins".   :

mergeInto(
  LibraryManager.library,
  {
    AddClickListenerForFileDialog: function () {
      document.addEventListener('click', function () {

        var fileuploader = document.getElementById('fileuploader');
        if (!fileuploader) {
          fileuploader = document.createElement('input');
          fileuploader.setAttribute('style', 'display:none;');
          fileuploader.setAttribute('type', 'file');
          fileuploader.setAttribute('id', 'fileuploader');
          fileuploader.setAttribute('class', '');
          document.getElementsByTagName('body')[0].appendChild(fileuploader);

          fileuploader.onchange = function (e) {
            var files = e.target.files;
            for (var i = 0, f; f = files[i]; i++) {
              window.alert(URL.createObjectURL(f));
              SendMessage('BrowserFileLoading', 'FileDialogResult', URL.createObjectURL(f));
            }
          };
        }
        if (fileuploader.getAttribute('class') == 'focused') {
          fileuploader.setAttribute('class', '');
          fileuploader.click();
        }
      });
    }
  }
);

, : ) "". :

   fileuploader.setAttribute('class', '');

) Unity GameObject . , GameObject, (unity-) :

   SendMessage('BrowserFileLoading', 'FileDialogResult', URL.createObjectURL(f));

, :

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
using UnityEngine.Networking;
using System.Runtime.InteropServices;
public class BrowserFileLoadingDialog : MonoBehaviour
{
  [DllImport("__Internal")] private static extern void AddClickListenerForFileDialog();

  void Start()
  {
    AddClickListenerForFileDialog();
  }

  public void FileDialogResult(string fileUrl)
  {
    Debug.Log(fileUrl);
    UrlTextField.text = fileUrl;
    StartCoroutine(LoadBlob(fileUrl));
  }

  IEnumerator LoadBlob(string url)
  {
    UnityWebRequest webRequest = UnityWebRequest.Get(url);
    yield return webRequest.SendWebRequest();

    if (!webRequest.isNetworkError && !webRequest.isHttpError)
    {
      // Get text content like this:
      Debug.Log(webRequest.downloadHandler.text);

    }
}

( .jslib) :

mergeInto(
  LibraryManager.library,
  {
    FocusFileUploader: function () {
      var fileuploader = document.getElementById('fileuploader');
      if (fileuploader) {
          fileuploader.setAttribute('class', 'focused');
      }
    }
  }
);

, , , ( , ) CursorDown.

0

Source: https://habr.com/ru/post/1618773/


All Articles