【问题标题】:Unity WebGL External AssetsUnity WebGL 外部资产
【发布时间】:2016-07-31 12:08:03
【问题描述】:

我正在 Unity 中开发一些 webGL 项目,该项目必须从目录中加载一些外部图像,它在编辑器中运行良好,但是当我构建它时,它在 web 控制台中抛出一个未找到目录的异常。我将图像放在 Assets/StreamingAssets 文件夹中,它将成为构建项目中的 StreamingAssets 文件夹(在根目录下,与 index.html 相同)。图像位于那里,但浏览器仍然抱怨无法找到该目录。 (我是在自己的电脑上打开的,没有运行网络服务器)

我想我遗漏了一些非常明显的东西,但似乎我可以使用一些帮助,我一周前刚刚开始学习统一,而且我对 C# 或 JavaScript 不是很好(我正在尝试变得更好......)这是否与某些javascript安全问题有关?

谁能指出我正确的方向,我应该如何在 Unity WebGL 中读取图像(无需编写)?

string appPath = Application.dataPath;
string[] filePaths = Directory.GetFiles(appPath, "*.jpg");

根据 webGL 中的 unity3d.com 构建了除线程和反射之外的所有内容,因此 IO 应该可以正常工作 - 或者我认为:S

我正在解决一些问题,现在我正在尝试加载一个包含图像路径的文本文件(由';'分隔):

    TextAsset ta = Resources.Load<TextAsset>("texManifest");
    string[] lines = ta.text.Split(';');

然后我将所有行转换为正确的路径,并将它们添加到列表中:

    string temp = Application.streamingAssetsPath + "/textures/" + s;
    filePaths.Add(temp);

Debug.Log 告诉我它看起来像这样:

file://////Downloads/FurnitureDresser/build/StreamingAssets/textures/79.jpg

所以除了那些斜线之外似乎没问题(这对我来说有点奇怪)

最后创建纹理:

    WWW www = new WWW("file://" + filePaths[i]);
    yield return www;
    Texture2D new_texture = new Texture2D(120, 80);
    www.LoadImageIntoTexture(new_texture);

围绕最后一部分(不确定:webgl 项目似乎不容易调试)它告诉我:NS_ERROR_DOM_BAD_URI:访问受限 URI 被拒绝

有人可以告诉我发生了什么吗?最重要的是,创建一个可以在运行时加载图像的目录的解决方案是什么?

【问题讨论】:

    标签: javascript c# unity3d unity-webgl


    【解决方案1】:

    我意识到这个问题现在已经有几年了,但是,由于这似乎仍然是常见的问题,这里有一个解决方案(对不起,代码是 C#,但我猜 javascript 实现是相似的)。基本上你需要使用 UnityWebRequest 和 Coroutines 来访问 StreamingAssets 文件夹中的文件。

    1) 创建一个新的加载场景(除了查询文件什么都不做;你可以让它显示一些状态文本或进度条让用户知道发生了什么)。

    2) 在 Loading 场景的 Main Camera 中添加一个名为 Loader 的脚本。

    3) 在Loader脚本中,添加一个变量来表示是否已经成功读取了asset:

    private bool isAssetRead;
    

    4) 在 Loading 脚本的 Start() 方法中:

    void Start ()
    {
      // if webGL, this will be something like "http://..."
      string assetPath = Application.streamingAssetsPath;
    
      bool isWebGl = assetPath.Contains("://") || 
                       assetPath.Contains(":///");
    
      try
      {
        if (isWebGl)
        {
          StartCoroutine(
            SendRequest(
              Path.Combine(
                assetPath, "myAsset")));
        }
        else // desktop app
        {
          // do whatever you need is app is not WebGL
        }
      }
      catch
      {
        // handle failure
      }
    }
    

    5) 在 Loading 脚本的 Update() 方法中:

    void Update ()
    {
      // check to see if asset has been successfully read yet
      if (isAssetRead)
      {
        // once asset is successfully read, 
        // load the next screen (e.g. main menu or gameplay)
        SceneManager.LoadScene("NextScene");
      }
    
      // need to consider what happens if 
      // asset fails to be read for some reason
    }
    

    6) 在 Loading 脚本的 SendRequest() 方法中:

    private IEnumerator SendRequest(string url)
    {
      using (UnityWebRequest request = UnityWebRequest.Get(url))
      {
        yield return request.SendWebRequest();
    
        if (request.isNetworkError || request.isHttpError)
        {
          // handle failure
        }
        else
        {
          try
          {
            // entire file is returned via downloadHandler
            //string fileContents = request.downloadHandler.text;
            // or
            //byte[] fileContents = request.downloadHandler.data;
    
            // do whatever you need to do with the file contents
            if (loadAsset(fileContents))
              isAssetRead = true;
          }
          catch (Exception x)
          {
            // handle failure
          }
        }
      }
    }
    

    【讨论】:

    • 谢谢,这对我很有用。我的文件内容是一个图像,我将它加载到一个精灵上,如下所示:Texture2D tex = new Texture2D(2, 2); tex.LoadImage(fileContents); //根据 Texture2D 创建一个新的 Sprite var rect = new Rect(0, 0, 700f, 700f); var sprite = Sprite.Create(tex, rect, new Vector2(0.5f, 0.5f));
    【解决方案2】:

    把你的图片放到Resources文件夹,用Resources.Load打开文件就可以使用了。

    例如:

    Texture2D texture = Resources.Load("images/Texture") as Texture2D;
    if (texture != null) 
    {
        GetComponent<Renderer>().material.mainTexture = texture;
    }
    

    目录列表和文件 API 在 webgl 构建中不可用。

    基本上不支持低级IO操作。

    【讨论】:

    • 我必须能够在不重建项目的情况下修改文件夹的内容。现在我正在尝试创建一个文本文件,它充当所有图像的清单。我加载该文本文件(作为资源 - textasset)并从从文本文件获得的路径加载图像。但是它给了我 NS_ERROR_DOM_BAD_URI: Access to restricted URI denied 。我会在问题中添加更多代码,也许会有所帮助。
    • 感谢 Doug 的帮助,看来我的头痛是由 file:// 前缀引起的...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    相关资源
    最近更新 更多