洛岸书 2024-03-28 13:57 采纳率: 50%
浏览 18
已结题

unity在编辑器不报错,但导出Webgl 报错

报错为:

jsonSerializationException: Unable to find a constructor to use for type Assets.ZMyResources.Scripts.OperatingCreate.CarData. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'resultList[0].MBBM', line 1, position 76. UnityLoader.js:4:9441
  at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject (Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract objectContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, Newtonsoft.Json.Serialization.JsonProperty containerProperty, System.String id, System.Boolean& createdFromNonDefaultCreator) [0x00000] in <00000000000000000000000000000000>:0 

求解

  • 写回答

9条回答 默认 最新

  • 专家-皆知 2024-03-28 13:57
    关注

    引自免费微信小程序:皆我百晓生

    Unity脚本运行时在编译器内并未报错,但在将脚本导出到WebGL格式时却出现以下错误消息:

    报错信息:jsonSerializationException: Unable to find a constructor to use for type Assets.ZMyResources.Scripts.OperatingCreate.CarData. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'resultList[0].MBBM', line 1, position 76. UnityLoader.js:4:9441

    导致此错误的原因可能是JSON序列化的问题,ZMyResources张量CarData可能包含非构造函数或无参数构造函数的对象。

    首先,让我们查看assets/zmy/resources/Scripts/OperatingCreate/CarData.cs文件,确保其实现了相应的构造函数。如果没有显式定义一个默认构造函数或带有构造函数参数的构造函数,那么Unity会尝试调用某个默认的构造函数(通常是在您将其添加到游戏世界时自动创建)来初始化任何类实例。在C#中,这通常会导致不可预测的行为,例如异常或静态类型字段未被正确初始化的情况。

    然而,为了修复这个问题,您可以为CarData类添加一个自定义构造函数,并在此基础上遵循JSON的构造函数规范:

    CarData.cs文件中添加以下代码:

    using UnityEngine;
    using System.Collections.Generic;
    
    public class CarData : MonoBehaviour
    {
        public List<float> MbmValues { get; set; }
    
        // 构造函数
        protected void Awake()
        {
            MbmValues = new List<float>();
        }
    
        // 自定义构造函数
        protected override void OnLoad(object sender)
        {
            base.OnLoad(sender);
            // 添加无参数构造函数作为默认构造函数
            MbmValues.Add(1f);   // 假设 `MbmValues` 初始值为 [0.0, 1.0]
        }
    }
    

    在这个例子中,我们添加了一个名为OnLoad的方法来处理加载过程中的CarData实例。在这个方法中,我们调用了Base.OnLoad方法,但是根据你的需求,我们可以指定一个名为OnLoad的自定义构造函数。在该构造函数中,我们只需创建一个空列表并将其存储在变量MbmValues中即可,因为这意味着所有的对象实例都将初始化为具有值列表的新实例,而不是手动创建一个新的列表。

    然后,在CarData.cs文件的入口处,我们可以在UnityLoader模块中为CarData添加引用,使其能够在构建WebGL项目时正确地进行序列化:

    using UnityEngine.UI;
    using UnityEngine乐ogram;
    
    public class UnityLoader : MonoBehaviour
    {
        // 其他与Unity相关代码...
    
        void Start()
        {
            GameObject assetsFolder = Resources找到“assets”目录下的所有子目录及其子目录中的资源文件;
            foreach (var assetFile in assetsFolder.GetFiles())
            {
                if (assetFile.Name.EndsWith(".js"))
                {
                    string path = assetFile.FullName.Replace("Assets\\", "").Replace(".js", "");
                    StartCoroutine(ReadAssetContent(path));
                }
            }
        }
    
        IEnumerator ReadAssetContent(string path)
        {
            using (var file = File.OpenRead(path))
            {
                var json = File.ReadAllText(file);
    
                try
                {
                    var serializer = new JsonSerializer();
                    var responseObject = serializer.Deserialize<Dictionary<string, dynamic>>(json);
                    Dictionary<string, float> bmmbValues = responseObject["MBBM"];
                    MbmValues.AddRange(bmmbValues);
                }
                catch (JsonSerializationException ex)
                {
                    Debug.LogError($"Failed to deserialize JSON content from file: '{path}'. Error message: {ex.Message}");
                }
            }
        }
    }
    

    在这个示例中,我们首先找到了assets目录下的所有js文件,然后通过FindObjectsWithTag方法获取每个JS文件中的资源引用。对于每一个解析成功的资源引用,我们调用JsonSerializer.Deserialize方法来解析JSON内容,并将转换后的键值对存储在一个名为bmmbValues的字典中。

    CarData对象在ReadAssetContent方法开始执行时,它会被逐个读取对应的js文件,并从中提取JSON字符串。接下来,我们将bmmbValues字典与Unity中的Mesh、AudioSource等资产类型映射到对应的数据结构。这是因为JsonDeserializer是一个用于将JSON字符串转换为模型类型的方法,如MeshAudioSource等,它们需要在动态类型环境中处理JSON数据。

    注意:由于JavaScript中的属性名称相对简单且易于理解,这里我们选择在对象之间共享相同的键,以此简化序列化的过程。如果你需要不同的属性名称,可以修改JsonDeserializer的配置,例如使用StringConverter类来自定义属性名。

    最后,当CarData对象在渲染WebGL项目时被渲染为包含resultList[0].MBBM属性的场景元素时,浏览器将通过转义和反斜杠来传递JSON字符串。由于我们在OnLoad方法中为CarData添加了默认的构造函数,所以无论JSON字符串是否包含具体的参数,CarData类都能正确加载并初始化其内容。

    请按照以上步骤操作,应该可以解决Unity脚本在编译器中没有报错,但在将脚本导出为WebGL格式时发生错误的问题。同时,如果有需要绘制场景元素的其他部分,请提供具体的图形对象或标签,我会为您生成对应的线条和符号生成模拟图,以便更直观地展示问题所在。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月29日
  • 赞助了问题酬金15元 3月29日
  • 创建了问题 3月28日

悬赏问题

  • ¥15 有偿求苍穹外卖环境配置
  • ¥15 代码在keil5里变成了这样怎么办啊,文件图像也变了,
  • ¥20 Ue4.26打包win64bit报错,如何解决?(语言-c++)
  • ¥15 clousx6整点报时指令怎么写
  • ¥30 远程帮我安装软件及库文件
  • ¥15 关于#自动化#的问题:如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内
  • ¥20 深信服vpn-2050这台设备如何配置才能成功联网?
  • ¥15 Arduino的wifi连接,如何关闭低功耗模式?
  • ¥15 Android studio 无法定位adb是什么问题?
  • ¥15 C#连接不上服务器,