Unity:Siccity.GLTFUtility 着色器未在构建中加载

问题描述 投票:0回答:1

我正在为 Windows 制作 Unity 桌面应用程序,在我的应用程序中,文件类型 glbgltf 的 3D 模型在运行时从磁盘加载到场景中。这些在 Unity 编辑器中运行良好,但当我构建它时,模型无法加载。

我使用 Siccity.GLTFUtility 加载这些文件。

这是与该问题相关的 Player.log 错误(就我而言,整个日志文件中没有其他错误):

ArgumentNullException: Value cannot be null.
Parameter name: shader
  at (wrapper managed-to-native) UnityEngine.Material.CreateWithShader(UnityEngine.Material,UnityEngine.Shader)
  at UnityEngine.Material..ctor (UnityEngine.Shader shader) [0x00008] in <ed4b14358c3a426aacd38939413c3d3b>:0 
  at Siccity.GLTFUtility.GLTFMaterial+PbrMetalRoughness+<CreateMaterial>d__5.MoveNext () [0x0006a] in <a234369d3f4e4b83afe3dc4030317985>:0 
  at Siccity.GLTFUtility.GLTFMaterial+<CreateMaterial>d__14.MoveNext () [0x000b9] in <a234369d3f4e4b83afe3dc4030317985>:0 
  at Siccity.GLTFUtility.GLTFMaterial+ImportTask+<OnCoroutine>d__4.MoveNext () [0x00114] in <a234369d3f4e4b83afe3dc4030317985>:0 
  at Siccity.GLTFUtility.Importer+ImportTask`1[TReturn].RunSynchronously () [0x0001b] in <a234369d3f4e4b83afe3dc4030317985>:0 
  at Siccity.GLTFUtility.Importer.LoadInternal (Siccity.GLTFUtility.GLTFObject gltfObject, System.String filepath, System.Byte[] bytefile, System.Int64 binChunkStart, Siccity.GLTFUtility.ImportSettings importSettings, UnityEngine.AnimationClip[]& animations) [0x000ab] in <a234369d3f4e4b83afe3dc4030317985>:0 
  at Siccity.GLTFUtility.Importer.ImportGLB (System.String filepath, Siccity.GLTFUtility.ImportSettings importSettings, UnityEngine.AnimationClip[]& animations) [0x00012] in <a234369d3f4e4b83afe3dc4030317985>:0 
  at Siccity.GLTFUtility.Importer.LoadFromFile (System.String filepath, Siccity.GLTFUtility.ImportSettings importSettings, UnityEngine.AnimationClip[]& animations, Siccity.GLTFUtility.Format format) [0x00033] in <a234369d3f4e4b83afe3dc4030317985>:0 
  at Siccity.GLTFUtility.Importer.LoadFromFile (System.String filepath, Siccity.GLTFUtility.Format format) [0x00006] in <a234369d3f4e4b83afe3dc4030317985>:0 
  at MultiModelLoader+<DownloadAndSaveFile>d__44.MoveNext () [0x00159] in <d1494a091caf4b75869a10c4f73429a5>:0 
  at UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) [0x00026] in <ed4b14358c3a426aacd38939413c3d3b>:0 
UnityEngine.MonoBehaviour:StartCoroutineManaged2(MonoBehaviour, IEnumerator)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
<LoadFiles>d__42:MoveNext()
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
UnityEngine.MonoBehaviour:StartCoroutineManaged2(MonoBehaviour, IEnumerator)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
MultiModelLoader:PaginateItems(String[])
MultiModelLoader:ReadData()
<Start>d__37:MoveNext()
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

以下是将 3D 模型加载到场景中的 C# 代码的主要部分:

IEnumerator DownloadAndSaveFile(string fileId, Vector3 position)
    {
        string extension = items[fileId].ModelFileExtension;
        string fileName = fileId + "_model." + extension;
        string folderPath = modelPath + category + "/";
        string filePath = folderPath + fileName;

        // Check if the file already exists
        if (File.Exists(filePath))
        {
            CustomDebug("File " + fileName + " already exists in " + folderPath);
        }
        else
        {
            // Download the file from Firebase Storage and save it to local storage
            UnityWebRequest www = UnityWebRequest.Get(storageUrl + "models%2F" + fileName + "?alt=media");
            www.downloadHandler = new DownloadHandlerFile(filePath);
            yield return www.SendWebRequest();

            if (www.result != UnityWebRequest.Result.Success)
            {
                Debug.Log(www.error);
                yield break;
            }

            CustomDebug("File " + fileName + " downloaded and saved to " + folderPath);
        }

        // Load the GLTF file using the GLTFUtility library
        gltfObject = Importer.LoadFromFile(filePath);

        // Set the object's name to the file name (without extension)
        gltfObject.name = Path.GetFileNameWithoutExtension(fileId);

        // Set the parent object
        gltfObject.transform.SetParent(parentObject.transform);

        // Calculate the bounding box of the model before scaling
        Bounds preBounds = gltfObject.GetComponentInChildren<MeshRenderer>().bounds;

        // Calculate the scale factor needed to fit the bounding box within a desired size
        float desiredSize = 2f; // desired size in world units
        float scaleFactor = desiredSize / preBounds.size.magnitude;

        // Apply the scale factor to the model
        gltfObject.transform.localScale *= scaleFactor;

        // Add a BoxCollider to the object
        gltfObject.AddComponent<BoxCollider>();

        // Set the layer of the object to Realtime for realtime lighting to affect it
        int layerIndex = LayerMask.NameToLayer("Realtime");
        // Since some models contain child objects, it's required to set all objects to that layer to receive lighting
        SetLayerRecursively(gltfObject, layerIndex);
        gltfObject.layer = layerIndex;

        // Position the object in the scene as desired
        gltfObject.transform.position = position;

        // Add gravity to the objects and let it place itself on the surface
        gltfObject.AddComponent<Rigidbody>();
        gltfObject.GetComponent<Rigidbody>().isKinematic = false;
        gltfObject.GetComponent<Rigidbody>().useGravity = true;
    }

由于使用 StartCoroutine 函数调用上述函数,我还认为使用多线程方法做同样的事情可能会起作用。但我尝试了一下,即使在编辑器中也失败了。以下是 Siccity 在他的 github 页面中的建议:

// Single thread
using Siccity.GLTFUtility;

void ImportGLTF(string filepath) {
   GameObject result = Importer.LoadFromFile(filepath);
}
// Multithreaded
using Siccity.GLTFUtility;

void ImportGLTFAsync(string filepath) {
   Importer.ImportGLTFAsync(filepath, new ImportSettings(), OnFinishAsync);
}

void OnFinishAsync(GameObject result, AnimationClip[] animations) {
   Debug.Log("Finished importing " + result.name);
}

正如相关 gltf 加载器的 github 页面所述,我将每个单独的着色器添加到 Always Included Shaders 但它仍然不起作用。

除此之外,我还尝试随机启用一些选项,看看其中是否有效。

enter image description here

  • 尝试将实例化变体设置为保留全部
  • 按下 保存到资源... 并将该文件添加到预加载着色器中,如图所示。

enter image description here

  • 尝试将默认的质量级别更改为非常低。

enter image description here

  • 禁用优化网格数据

这是我的第一个 Unity 项目,我正在为期末考试做这个项目。我决定在这里问这个问题,因为我已经没有时间和选择了。任何有关如何解决此问题的帮助/建议将非常感激。

谢谢!

c# unity-game-engine shader gltf
1个回答
0
投票

现在回答你可能有点晚了,但是如果你的项目使用了urp渲染管线,你必须在图形设置中添加GLTFUtility相应的着色器,而不仅仅是内置的!

© www.soinside.com 2019 - 2024. All rights reserved.