Default material loaded in a prefab instead of the assigned material

Discussion and help for Easy Save 3, The Complete Save Game & Data Serializer System for the Unity Engine
Post Reply
Marou1
Posts: 8
Joined: Fri Apr 15, 2022 11:34 am

Default material loaded in a prefab instead of the assigned material

Post by Marou1 »

Hi,

I have a prefab in the scene with a skinned mesh renderer with a specific material. On runtime, Unity creates an instance of the material as expected and everything is fine. However, if the material instance properties are modified on runtime, and then I save the game. When reloading, the instance of the prefab where previously the material instance properties were modified has actually an instance of the default HD material, not an instance of the material assigned in the inspector.
The other instances of the same prefab in the scene are fine until a I change the properties of the material instance, save and load.

The only reason I am saving the prefab is to have a reference to the object in the scene, not to save its properties, I have separate classes to save what I need, so the modified material properties are saved separately. As a workaround, I could in the code assign the right material on start, it would ensure that it is the right one that is assigned. But I'd like to understand why this is happening to fix properly.

I already added manually the specific material to ES3 references, it did not solve the issue and my understand is since the prefab is already in the scene in the editor, the reference to the material is automatically added to ES3 anyway.

Second question: I have many cases where I save a game object as part of a class only to have the reference for the object in the scene. Does that mean that ES3 will anyway save all the components data anyway? If yes, does it impact the save time? If yes, is it possible to save only the reference, not the game object data?

Third question: What is the meaning of Use Global References in the settings ? (right now it is checked)

Thank you!
User avatar
Joel
Moodkie Staff
Posts: 4986
Joined: Wed Nov 07, 2012 10:32 pm

Re: Default material loaded in a prefab instead of the assigned material

Post by Joel »

Hi there,
The only reason I am saving the prefab is to have a reference to the object in the scene
If you just want to save a reference to the prefab, not the prefab itself, you just saving a class containing a field with that prefab. Fields of prefabs will be saved by reference, but directly saving a prefab will save it by value (unless you've changed the settings for this).
I have many cases where I save a game object as part of a class only to have the reference for the object in the scene.
As above, if you save a class with a field containing a GameObject, that GameObject will be saved by reference. If you save the GameObject itself, it will be saved as described in the Saving and Loading GameObjects documentation (unless you've changed the reference mode settings from default).
Third question: What is the meaning of Use Global References in the settings ? (right now it is checked)
This ensures that reference IDs are the same across scenes. You should only change this if directed to do so in the documentation or by support.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Marou1
Posts: 8
Joined: Fri Apr 15, 2022 11:34 am

Re: Default material loaded in a prefab instead of the assigned material

Post by Marou1 »

So to save a list of references to prefabs in the scene, I cannot save a list of game object, I will have to create a class:
public class MyClass
{
public GameObject prefabInScene;
}

then save a List<MyClass> ?
User avatar
Joel
Moodkie Staff
Posts: 4986
Joined: Wed Nov 07, 2012 10:32 pm

Re: Default material loaded in a prefab instead of the assigned material

Post by Joel »

Marou1 wrote: Mon Sep 09, 2024 7:59 pm So to save a list of references to prefabs in the scene, I cannot save a list of game object, I will have to create a class:
public class MyClass
{
public GameObject prefabInScene;
}

then save a List<MyClass> ?
By default, yes. Or instead of a GameObject field within that class, a List<GameObject> field.

Alternatively you can set the reference mode to ByRef when saving. For example:

Code: Select all

var settings = new ES3Settings();
settings.referenceMode = ES3.ReferenceMode.ByRef;
ES3.Save("references", listOfReferences, settings);
All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Marou1
Posts: 8
Joined: Fri Apr 15, 2022 11:34 am

Re: Default material loaded in a prefab instead of the assigned material

Post by Marou1 »

Alternatively you can set the reference mode to ByRef when saving.
Great! This is straight forward and I won't have to refactor my code!

Thanks!
Marou1
Posts: 8
Joined: Fri Apr 15, 2022 11:34 am

Re: Default material loaded in a prefab instead of the assigned material

Post by Marou1 »

It's not working. Le list is loaded empty. The list is declared as a list of game objects.
There are no errors while saving or loading. If var settings is removed, the list is loaded correctly.

Basically, there are 2 issues:
1- Saving and loading a prefab loads it with a default material instance instead of an instance of the assigned material.
2- To work around this, and since I don't want to save the data of the prefab by default, I am trying to save the reference to the prefab in the scene. But it is not working.

An other workaround would be to use a custom class, but I'd rather not refactor all the code.
User avatar
Joel
Moodkie Staff
Posts: 4986
Joined: Wed Nov 07, 2012 10:32 pm

Re: Default material loaded in a prefab instead of the assigned material

Post by Joel »

Please could you show me the code you're using to save and load.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Marou1
Posts: 8
Joined: Fri Apr 15, 2022 11:34 am

Re: Default material loaded in a prefab instead of the assigned material

Post by Marou1 »

Code: Select all

        var TempSettings = new ES3Settings();
        TempSettings.referenceMode = ES3.ReferenceMode.ByRef;
        AddData("followingRaccoonsList", mainSceneVariablesCP.PlayerArmature.GetComponent<PlayerAnimalInteract>().followingRaccoonsList, TempSettings);

Code: Select all

    private void AddData(string key, object value, ES3Settings settings = null)
    {
        if (value != null)
        {
            Debug.Log($"Key: {key}, Type: {value.GetType()}, Value is null: {value == null}");
            AllDataKeys.Add(key);
            AllDataToSave.Add(new KeyValuePair<object, ES3Settings>(value, settings));  // Store value and settings
        }
        else
        {
            Debug.LogError($"Key: {key}, Type: {value?.GetType().ToString() ?? "null"}, Value is null: true");
        }
    }

Code: Select all

    private void SaveDataToCache(string fileName)
    {
        int objectCount = AllDataKeys.Count;

        if (objectCount == AllDataToSave.Count)
        {
            var cachedDataFile = new ES3Settings(fileName, ES3.Location.Cache);

            // Save to the cache
            for (int i = 0; i < objectCount; i++)
            {
                var dataToSave = (KeyValuePair<object, ES3Settings>)AllDataToSave[i];
                var settings = dataToSave.Value ?? cachedDataFile; // Use specific settings or the default

                ES3.Save(AllDataKeys[i], dataToSave.Key, settings);
            }

            ES3.Save("WasSavingSuccessful", true, cachedDataFile);
        }
        else
        {
            Debug.LogError("The number of keys to save does not match the number of objects to save");
        }
    }
User avatar
Joel
Moodkie Staff
Posts: 4986
Joined: Wed Nov 07, 2012 10:32 pm

Re: Default material loaded in a prefab instead of the assigned material

Post by Joel »

Hi there,

Unfortunately it's not possible for me to replicate it from this as there is a lot of logic which I won't have visibility of. Please could you make a new project with a simple scene with minimal logic (i.e. less than in your example below) which isolates the issue to Easy Save rather than your logic and send it to me using the form at https://moodkie.com/repro.

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