引自免费微信小程序:皆我百晓生
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字符串转换为模型类型的方法,如Mesh
、AudioSource
等,它们需要在动态类型环境中处理JSON数据。
注意:由于JavaScript中的属性名称相对简单且易于理解,这里我们选择在对象之间共享相同的键,以此简化序列化的过程。如果你需要不同的属性名称,可以修改JsonDeserializer
的配置,例如使用StringConverter
类来自定义属性名。
最后,当CarData
对象在渲染WebGL项目时被渲染为包含resultList[0].MBBM
属性的场景元素时,浏览器将通过转义和反斜杠来传递JSON字符串。由于我们在OnLoad
方法中为CarData
添加了默认的构造函数,所以无论JSON字符串是否包含具体的参数,CarData
类都能正确加载并初始化其内容。
请按照以上步骤操作,应该可以解决Unity脚本在编译器中没有报错,但在将脚本导出为WebGL格式时发生错误的问题。同时,如果有需要绘制场景元素的其他部分,请提供具体的图形对象或标签,我会为您生成对应的线条和符号生成模拟图,以便更直观地展示问题所在。