Sprite doesn't load after being saved

Discussion and help for Easy Save 3
Post Reply
cptscrimshaw
Posts: 5
Joined: Wed Mar 31, 2021 11:19 pm

Sprite doesn't load after being saved

Post by cptscrimshaw »

Hi Joel,

I'm having trouble with sprite references saving correctly. I know this was an added feature, so trying to get to the bottom of why this isn't working for me.

Version of ES3: 3.3.2f7

I'm utilizing a Type to save sprites, and I'm guessing the issue I'm having is becuase the sprite is fairly buried. It's saving every other aspect of the Technology, except for the sprite.

Here are the various bits of code:

TechDatabase.cs

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PixelCrushers;

public class TechDatabase : MonoBehaviour
{
    public List<TechCategory> techCategories = new List<TechCategory>();

    void Awake()
    {
        SaveSystem.saveDataApplied += OnSaveDataApplied;
        EventHandler.ScenePortalTriggered += SaveBeforeChangingScenes;
    }

    public void OnSaveDataApplied()
    {
        if (!ManualSave.manuallyLoadingGame)
        {
            if (ES3.KeyExists("techdatabase"))
            {
                techCategories = ES3.Load<List<TechCategory>>("techdatabase");
            }
        }
    }

    void SaveBeforeChangingScenes()
    {
        ES3.Save("techdatabase", techCategories);
    }

    public void OnApplicationQuit()
    {
        ES3.Save("techdatabase", techCategories);
    }

    private void OnDestroy()
    {
        SaveSystem.saveDataApplied -= OnSaveDataApplied;
        EventHandler.ScenePortalTriggered -= SaveBeforeChangingScenes;
    }
}

[System.Serializable]
public class TechGroup : IEnumerable<Technology>
{
    public List<Technology> technologies = new List<Technology>();

    public IEnumerator<Technology> GetEnumerator()
    {
        return technologies.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
Within each TechCategory is a list of TechGroups and within that are a list of Technologies. Each of these are custom classes. Then within technology, the sprite is listed:

TechCategory.cs

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class TechCategory : IEnumerable<TechGroup>
{
    public string categoryName;
    public List<TechGroup> techGroups = new List<TechGroup>();

    public IEnumerator<TechGroup> GetEnumerator()
    {
        return techGroups.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
Technology.cs

Code: Select all

using System.Collections.Generic;
using UnityEngine;
using System.Linq;

[System.Serializable]
public class Technology
{
    public enum AvailabilityState
    {
        Locked,
        Unlocked,
        Researching,
        Learned
    }

    public AvailabilityState availabilityState;
    public string techName;
    public string techDescription;
    public Sprite techImage;
    public List<ResourceAmount> resourceCosts;
    public List<RequiredTech> techRequirements;
    public List<TechModifiers> techModifiers;
    [SerializeField]
    private int researchedTurns;
    public int requiredResearchTurns;
    public Color techUIColor;

    public Technology()
    {
        if(availabilityState == AvailabilityState.Locked)
        {
            TechEvents.OnTechResearchCompleted += CheckRequirements;
        }
    }

    public void Unlock()
    {
        availabilityState = AvailabilityState.Unlocked;
        TechEvents.TechUnlocked(this);
        TechEvents.OnTechResearchCompleted -= CheckRequirements;
        Debug.Log("Tech was unlocked: " + this.techName);
    }

    public void Learn()
    {
        TechEvents.TechResearchCompleted(this);
        TechEvents.OnTurnPassed -= NewTurn;
        availabilityState = AvailabilityState.Learned;
        Debug.Log("Tech was learned: " + this.techName);
        EventHandler.CallLearnedTech(this.techName);
    }

    public void NewTurn()
    {
        if(availabilityState == AvailabilityState.Researching)
        {
            researchedTurns++;
            if(researchedTurns >= requiredResearchTurns)
            {
                Learn();
            }
        }
    }

    private void CheckRequirements(Technology tech)
    {
        if(availabilityState == AvailabilityState.Locked)
        {
            RequiredTech requireTech = techRequirements.FirstOrDefault(rt => rt.techName == tech.techName);
            if(requireTech != null && !requireTech.completed)
            {
                requireTech.completed = true;
                if(!techRequirements.Any(t => t.completed == false))
                {
                    Unlock();
                }
            }
        }
    }

    public bool StartResearching()
    {
        bool hasEnoughResources = false;
        List<ResourceAmount> resourceAmounts = new List<ResourceAmount>();

        for(int i = 0; i < resourceCosts.Count; i++)
        {
            ResourceAmount currentAmount = TechResources.Instance.GetResourceAmount(resourceCosts[i].resourceType);
            ResourceAmount cost = resourceCosts[i];
            //TODO add in quest item check
            if(resourceCosts[i].resourceType == ResourceTypes.QuestItem)
            {

            }

            if(currentAmount.resourceAmount >= cost.resourceAmount)
            {
                resourceAmounts.Add(currentAmount);
            }
        }

        if(resourceAmounts.Count >= resourceCosts.Count)
        {
            hasEnoughResources = true;
            for (int i = 0; i < resourceCosts.Count; i++)
            {
                resourceAmounts[i].resourceAmount -= resourceCosts[i].resourceAmount;
            }
            availabilityState = AvailabilityState.Researching;
            TechEvents.TechResearchStarted(this);
            TechEvents.OnTurnPassed += NewTurn;

            GameObject.FindObjectOfType<TechTreeUI>().UpdateAvailableXP();
            GameObject.FindObjectOfType<TechTreeUI>().RemoveResourceCost(techName);
        }

        return hasEnoughResources;
    }
}

[System.Serializable]
public class RequiredTech
{
    public string techName;
    public bool completed;
}

[System.Serializable]
public class TechModifiers
{
    public enum ModifierType { Recipe, Tool, Gameplay }
    public ModifierType modifier;
    public string item;
}
I could perhaps save every technology, but I'd prefer not to do that if I don't have to.

Hopefully this is enough information, but if not, let me know what else I can provide.

Thanks!
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Sprite doesn't load after being saved

Post by Joel »

Hi there,

Are you getting any warnings to console when you load?

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
cptscrimshaw
Posts: 5
Joined: Wed Mar 31, 2021 11:19 pm

Re: Sprite doesn't load after being saved

Post by cptscrimshaw »

Yes! And I tried refreshing the references and still got this warning:

Reference for UnityEngine.Sprite with ID 5926514645306553402 could not be found in Easy Save's reference manager. Try pressing the Refresh References button on the ES3ReferenceMgr Component of the Easy Save 3 Manager in your scene. If you are loading objects dynamically, this warning is expected and can be ignored.
To disable warnings from Easy Save, go to Window > Easy Save 3 > Settings, and uncheck 'Log Warnings'
UnityEngine.Debug:LogWarningFormat (UnityEngine.Object,string,object[])
ES3Internal.ES3Debug:LogWarning (string,UnityEngine.Object,int) (at Assets/Plugins/Easy Save 3/Scripts/Debugging/ES3Debug.cs:30)
ES3Internal.ES3ReferenceMgrBase:Get (long,System.Type) (at Assets/Plugins/Easy Save 3/Scripts/ES3ReferenceMgrBase.cs:143)
ES3Types.ES3UnityObjectType:ReadObject<UnityEngine.Sprite> (ES3Reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3UnityObjectType.cs:69)
ES3Types.ES3ObjectType:Read<UnityEngine.Sprite> (ES3Reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:54)
ES3Reader:ReadObject<UnityEngine.Sprite> (ES3Types.ES3Type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:249)
ES3Reader:Read<UnityEngine.Sprite> (ES3Types.ES3Type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:278)
ES3Types.ES3UserType_Technology:ReadObject<object> (ES3Reader,object) (at Assets/Easy Save 3/Types/ES3UserType_Technology.cs:49)
ES3Types.ES3UserType_Technology:ReadObject<object> (ES3Reader) (at Assets/Easy Save 3/Types/ES3UserType_Technology.cs:79)
ES3Types.ES3ObjectType:Read<object> (ES3Reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:54)
ES3Reader:ReadObject<object> (ES3Types.ES3Type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:249)
ES3Reader:Read<object> (ES3Types.ES3Type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:278)
ES3Types.ES3ListType:Read (ES3Reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Collection Types/ES3ListType.cs:64)
ES3Reader:Read<System.Collections.Generic.List`1<Technology>> (ES3Types.ES3Type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:274)
ES3Reader:Read<System.Collections.Generic.List`1<Technology>> () (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:126)
ES3Types.ES3UserType_TechGroup:ReadObject<object> (ES3Reader,object) (at Assets/Easy Save 3/Types/ES3UserType_TechGroup.cs:31)
ES3Types.ES3UserType_TechGroup:ReadObject<object> (ES3Reader) (at Assets/Easy Save 3/Types/ES3UserType_TechGroup.cs:43)
ES3Types.ES3ObjectType:Read<object> (ES3Reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:54)
ES3Reader:ReadObject<object> (ES3Types.ES3Type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:249)
ES3Reader:Read<object> (ES3Types.ES3Type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:278)
ES3Types.ES3ListType:Read (ES3Reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Collection Types/ES3ListType.cs:64)
ES3Reader:Read<System.Collections.Generic.List`1<TechGroup>> (ES3Types.ES3Type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:274)
ES3Reader:Read<System.Collections.Generic.List`1<TechGroup>> () (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:126)
ES3Types.ES3UserType_TechCategory:ReadObject<object> (ES3Reader,object) (at Assets/Easy Save 3/Types/ES3UserType_TechCategory.cs:35)
ES3Types.ES3UserType_TechCategory:ReadObject<object> (ES3Reader) (at Assets/Easy Save 3/Types/ES3UserType_TechCategory.cs:47)
ES3Types.ES3ObjectType:Read<object> (ES3Reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:54)
ES3Reader:ReadObject<object> (ES3Types.ES3Type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:249)
ES3Reader:Read<object> (ES3Types.ES3Type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:278)
ES3Types.ES3ListType:Read (ES3Reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Collection Types/ES3ListType.cs:64)
ES3Reader:Read<System.Collections.Generic.List`1<TechCategory>> (ES3Types.ES3Type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:274)
ES3Reader:Read<System.Collections.Generic.List`1<TechCategory>> (string) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:197)
ES3:Load<System.Collections.Generic.List`1<TechCategory>> (string,ES3Settings) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:371)
ES3:Load<System.Collections.Generic.List`1<TechCategory>> (string) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:336)
TechDatabase:OnSaveDataApplied () (at Assets/Scripts/Tech Tree/TechDatabase.cs:22)
PixelCrushers.SaveSystem:ApplySavedGameData (PixelCrushers.SavedGameData) (at Assets/Plugins/Pixel Crushers/Common/Scripts/Save System/SaveSystem.cs:662)
PixelCrushers.SaveSystem/<LoadSceneCoroutine>d__107:MoveNext () (at Assets/Plugins/Pixel Crushers/Common/Scripts/Save System/SaveSystem.cs:765)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&) (at /Users/bokken/buildslave/unity/build/Modules/IMGUI/GUIUtility.cs:189)
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Sprite doesn't load after being saved

Post by Joel »

Hi there,

Just to check, is there an instance of the Sprite in your scene prior to runtime? Or is it being loaded dynamically?

Also do you modify your Sprite anywhere?

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
cptscrimshaw
Posts: 5
Joined: Wed Mar 31, 2021 11:19 pm

Re: Sprite doesn't load after being saved

Post by cptscrimshaw »

Yeah, I have a TechDatabase prefab GameObject that's in the scene hierarchy of every scene that has the sprites in the techImage field for each technology. And no, the sprite isn't modified at all.

Thanks for you help in figuring this out!
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Sprite doesn't load after being saved

Post by Joel »

Thanks for the info.

As I've not been able to replicate this at my end, please could you put together a new project with a simple scene which replicates the issue and private message it to me with instructions so I can see what is happening?

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Post Reply