简体   繁体   中英

loading a serialized sprite icon in Unity

So I created a JSON script to serialize and save the inventory of a game in Unity, the saving of the inventory items names, stats etc works fine but the icon of the item does load properly, I get a placeholder icon with "?" instead.

I have been following: Is it possible to serialize sprites in unity?

but this led to the error mentioned above.

saving and loading is done with the following:

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;
}
}

converting the item to a serializable is done with:

 [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;
}

Finally Loading the item back is done with the following:

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);
    }
}

In the above including the GetComponent gives me an ArgumentException as the "Equipment" is a scriptable object and does not derive from MonoBehaviour.

Thank you in advance for any help resolving this

You would be better off using an ID for the item icon and you could have a dictionary to store icons and their respective IDs. Serializing and storing copies of the item icons is just unnecessary. Try something like this:

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);
    }
}

If it's easier for you, you could also store the items in an array like this:

[SerializeField]
Texture[] itemIcons;

So that you could assign the icons in the inspector.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM