【问题标题】:loading a serialized sprite icon in Unity在 Unity 中加载序列化的精灵图标
【发布时间】:2020-01-16 07:32:18
【问题描述】:

所以我创建了一个 JSON 脚本来序列化和保存 Unity 中的游戏库存,库存项目名称、统计数据等的保存工作正常,但项目的图标加载正确,我得到一个占位符图标“ ?”而是。

我一直在关注:Is it possible to serialize sprites in unity?

但这导致了上面提到的错误。

保存和加载通过以下方式完成:

public class JSONsave 
{

[SerializeField]
Sprite m_InSprite;

SerializeTexture exportObj = new SerializeTexture();
SerializeTexture importObj = new SerializeTexture();

[ContextMenu("serialize")]
public void SerializeTest(CharacterStats PlayerStats)
{
    PlayerSaveData data = new PlayerSaveData(PlayerStats);
    string text = JsonUtility.ToJson(data);
    File.WriteAllText(Application.persistentDataPath + "/playerInfo.dat", text);
}

[ContextMenu("deserialize")]
public PlayerSaveData DeSerializeTest()
{
    string text = File.ReadAllText(Application.persistentDataPath + "/playerInfo.dat");
    //importObj = JsonUtility.FromJson<SerializeTexture>(text);
    PlayerSaveData data = JsonUtility.FromJson<PlayerSaveData>(text);
    return data;
}

[Serializable]
public class SerializeTexture
{
    [SerializeField]
    public int x;
    [SerializeField]
    public int y;
    [SerializeField]
    public byte[] bytes;
}
}

将项目转换为可序列化通过以下方式完成:

 [Serializable]
public class SaveGameEquipment
{
public string name;

[SerializeField]
Sprite m_InSprite;

public bool isDefaultItem;

public EquipmentSlot equipSlot;
public SkinnedMeshRenderer mesh;
public int armorModifier;
public int damage;
public int energy;

SerializeTexture exportObj = new SerializeTexture();


public SaveGameEquipment(Equipment a_item)
{
    //get items sprite
    m_InSprite = a_item.icon;
    //converting sprite to json readable format - 
    Texture2D tex = m_InSprite.texture;
    exportObj.x = tex.width;
    exportObj.y = tex.height;
    exportObj.bytes = ImageConversion.EncodeToPNG(tex);

    name = a_item.name;
    equipSlot = a_item.equipSlot;
    mesh = a_item.mesh;
    armorModifier = a_item.armorModifier;
    damage = a_item.damage;
    energy = a_item.energy;
    isDefaultItem = a_item.isDefaultItem;



}

public class SerializeTexture
{
    [SerializeField]
    public int x;
    [SerializeField]
    public int y;
    [SerializeField]
    public byte[] bytes;
}

最后通过以下方式加载项目:

public void loadItems(PlayerSaveData data)
{

    SaveGameItem.SerializeTexture importObj = new SaveGameItem.SerializeTexture();

    foreach (SaveGameEquipment item in data.wrappedList)
    {
        Equipment n_Item = ScriptableObject.CreateInstance<Equipment>();
        n_Item.name = item.name;

        //sort out the icon
        Texture2D tex = new Texture2D(importObj.x, importObj.y);
        ImageConversion.LoadImage(tex, importObj.bytes);
        Sprite mySprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), Vector2.one);
        //GetComponent<Equipment>().sprite = mySprite;

        n_Item.icon = mySprite;


        n_Item.equipSlot = item.equipSlot;
        n_Item.mesh = item.mesh;
        n_Item.armorModifier = item.armorModifier;
        n_Item.damage = item.damage;
        n_Item.energy = item.energy;

        n_Item.isDefaultItem = item.isDefaultItem;

        Add(n_Item);
    }
}

在上面,包括 GetComponent 给了我一个 ArgumentException,因为“设备”是一个可编写脚本的对象,不是从 MonoBehaviour 派生的。

提前感谢您提供解决此问题的任何帮助

【问题讨论】:

标签: c# unity3d serialization save deserialization


【解决方案1】:

最好为项目图标使用 ID,并且可以使用字典来存储图标及其各自的 ID。不需要序列化和存储项目图标的副本。试试这样的:

public static Dictionary<int,Texture> itemIcons = new Dictionary<uint, itemIcons>();

public void loadIcons(){
    // Initialize your dictionary with your icons
    itemIcons.Add(id,texture);
    ...
}

public void loadItems(PlayerSaveData data)
{

    SaveGameItem.SerializeTexture importObj = new SaveGameItem.SerializeTexture();

    foreach (SaveGameEquipment item in data.wrappedList)
    {
        Equipment n_Item = ScriptableObject.CreateInstance<Equipment>();
        n_Item.name = item.name;

        //sort out the icon
        Texture2D tex = itemIcons[item.iconID];
        Sprite mySprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), Vector2.one);
        //GetComponent<Equipment>().sprite = mySprite;

        n_Item.icon = mySprite;


        n_Item.equipSlot = item.equipSlot;
        n_Item.mesh = item.mesh;
        n_Item.armorModifier = item.armorModifier;
        n_Item.damage = item.damage;
        n_Item.energy = item.energy;

        n_Item.isDefaultItem = item.isDefaultItem;

        Add(n_Item);
    }
}

如果对您来说更容易,您还可以将项目存储在这样的数组中:

[SerializeField]
Texture[] itemIcons;

这样您就可以在检查器中分配图标。

【讨论】:

  • 您好,谢谢您的回复。但是,在实施所有这些之后,库存中的图标仍然是一个问号。所以我列出了项目而不是图标,保存了项目编号,然后在加载游戏时加载了相应的项目。 (由于某种原因,资产 png 在此过程中被删除,但重新加载后效果很好。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-07
  • 2017-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多