Forum rules - please read before posting.

Bug (?) with Save Game (on separate thread only) when syncing a GameObject GVar

edited August 2 in Technical Q&A

Hi

I believe this is a bug. I haven't attempted to reproduce outside my project.

  1. Ensure AC Game Editor -> Settings -> Saving -> "Save using separate thread?" is checked (enabled)
  2. Have a variable linking script that syncs a GameObject to a global variable (who's type is Game Object as well). (This script is on the player prefab. I dont think this is being a prefab is relevant)
  3. OnDownload should sync the GameObject variable.

Given the above, when you save Unity with throw a "UnityException: GetName can only be called from the main thread."

It looks like the GVar GameObjectValue set property access the .name member, which in turn calls Unity.GetName - which isnt thread safe. Maybe you need to cache the name, IDK.

Disabling saving on a separate thread prevents this bug from occurring. This is fine for me.

Call stack

OnDownload() is simple. Both parameters have the expected values.

private void OnDownload(GVar variable, Variables variables)
{
    if (variable.id == variableIDToSyncWith)
    {               
        variable.GameObjectValue = characterGameObject;
    }
}

Note: I also dont even need to serialize/ save this game object global variable, since its just a way for action lists to have access to a game object that code controls. If I missed documentation stating you need to explicitly avoid syncing a game object variable during save, then sorry :)

Comments

  • Thanks for the report. Yes, it's an issue with GameObjectValue being set - Unity doesn't allow access on a separate thread.

    If the Variable doesn't need saving, you can hook into the OnBeforeSaving event to inform your script to avoid the call within OnDownload while saving, i.e.:

    bool isSaving;
    
    void OnEnable()
    {
        EventManager.OnBeforeSaving += OnBeforeSaving;
        EventManager.OnFinishSaving += OnFinishSaving;
        EventManager.OnFailSaving += OnFailSaving;
    }
    
    void OnDisable()
    {
        EventManager.OnBeforeSaving -= OnBeforeSaving;
        EventManager.OnFinishSaving -= OnFinishSaving;
        EventManager.OnFailSaving -= OnFailSaving;
    }
    
    void OnBeforeSaving (int saveID) => isSaving = true;
    void OnFinishSaving (SaveFile saveFile) => isSaving = false;
    void OnFailSaving (int saveID) => isSaving = false;
    
    private void OnDownload(GVar variable, Variables variables)
    {
        if (isSaving) return;
        //
    }
    
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.