c# - 统一: Saving/Loading Sprites as Json

标签 c# json unity3d

我正在学习一个教程,其中我需要保存属于某个对象的 Sprite 。 我正在创建一个项目数据库,当然希望项目附带正确的图像。这就是我构建项目数据库的方式:

项目对象

[System.Serializable]
public class ItemObject{

    public int id;
    public string title;
    public int value;
    public string toolTip;
    public bool stackable;
    public string category;
    public string slug;
    public Sprite sprite;


    public ItemObject(int id, string title, int value, string toolTip, bool stackable, string category, string slug)
    {
        this.id = id;
        this.title = title;
        this.value = value;
        this.toolTip = toolTip;
        this.stackable = stackable;
        this.category = category;
        this.slug = slug;
        sprite = Resources.Load<Sprite>("items/" + slug);
    }

元素数据

[System.Serializable]
public class ItemData {

    public List<ItemObject> itemList;

}

然后我保存/加载 ItemData.itemList。效果很好。如您所见,我使用“slug”来加载我的 Item 的 sprite,slug 基本上是一个代码友好的名称(例如:golden_hat),然后我为我的 Sprite 使用了相同的名称。

这也很好用,但是 Unity 保存了 Sprite InstanceID,它总是在启动时改变,所以如果我退出 Unity 并加载我的数据,它会得到错误的图像。

我的 Json:

{
    "itemList": [
        {
            "id": 0,
            "title": "Golden Sword",
            "value": 111,
            "toolTip": "This is a golden sword",
            "stackable": false,
            "category": "weapon",
            "slug": "golden_sword",
            "sprite": {
                "instanceID": 13238
            }
        },
        {
            "id": 1,
            "title": "Steel Gloves",
            "value": 222,
            "toolTip": "This is steel gloves",
            "stackable": true,
            "category": "weapon",
            "slug": "steel_gloves",
            "sprite": {
                "instanceID": 13342
            }
        }
    ]
}

所以我猜这样做是行不通的,还有其他方法可以在 Json 中保存 Sprite 吗?还是我每次都必须使用我的“slug”在运行时加载正确的 Sprite?

最佳答案

如果您使用 JsonUtility 进行序列化,您可以实现 ISerializationCallbackReceiver 以接收序列化回调。这样你就可以在对象被反序列化后根据存储的路径加载正确的 Sprite 。您还将避免资源重复。

[Serializable]
public class ItemObject : ISerializationCallbackReceiver
{
    public void OnAfterDeserialize()
    {
        sprite = Resources.Load<Sprite>("items/" + slug);
        Debug.Log(String.Format("Loaded {0} from {1}", sprite, slug));
    }

    public void OnBeforeSerialize() { }

    (...)
}

如果您真的想将 Sprite 直接存储在 JSON 中,请考虑序列化从 Sprite.texture.GetRawTextureData() 中获取的原始纹理数据(可能存储二进制base64 string 中的数据)并在运行时使用 Sprite.Create() 重新创建它。 ISerializationCallbackReceiver 技巧也适用于此。

作为附加说明,如果符合您的要求,请务必考虑放弃基于 JSON 的对象数据库,转而使用 Scriptable Objects .通过这种方式,您可以轻松引用 U​​nityEngine 对象,而不必诉诸于使用 Resources 文件夹(除非必要,否则不推荐这样做)。

关于c# - 统一: Saving/Loading Sprites as Json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44323901/

相关文章:

c# - 将图像存储到 Windows Phone 7 中的隔离存储中

C#区间树类

javascript - 为什么我无法使用 jQuery.parseJSON(json) 解析 json 字符串?

javascript - 浏览器无法处理大 JSON

c# - Unity 4.3 - 2D,如何以编程方式将 Sprite 分配给对象

android - Unity3d 与 android 集成

c# - 依赖注入(inject)不只是将问题转移到别处吗?

c# - 在 C# 中下载整个网站

java - 如何同时加载JSP页面并在json文件上写入数据?

从 Unity3D 构建的 Android .apk 在设备上出现 'App not installed' 错误