Search Unity

Best way to save a scene in a save file... Asset Reference?

Discussion in 'Addressables' started by Fakkau, Oct 9, 2019.

  1. Fakkau

    Fakkau

    Joined:
    Mar 11, 2013
    Posts:
    22
    So I'm currently setting up a save/load game system and want to save the current, active scene. (I'm using the Binary format: https://unity3d.com/es/learn/tutorials/topics/scripting/introduction-saving-and-loading)

    The easy way to save the active scene is something like "string lastScene = SceneManager.GetActiveScene().name", but that means saving it as a string. This would not allow renaming of scene files.

    I was therefor wondering if it would be possible to save an AssetReference in a save file. This would allow renaming and repositioning of scene files.

    The main problems I'm facing are:
    - How would I get the active scene as an AssetReference type?
    - If I can get the AssetReference, can I save it as that type, or do I save it's RuntimeKey as an int? (Not sure if this int will always have the same value)

    If anyone has an answer (or tips for better methods), I would appreciate it!
     
  2. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    429
    You can create list of asset references there you could assign all your addressable scenes and load your scenes like this AssetReferencedScenes.ElementAt(scene index).LoadSceneAsync() (it does not have to be a list but it just for purpose of example). Then you create variable of assetReference called CurrentScene. Then you load your scenes you need to also set this variable as assetReference from that you have loaded the scene, do it everytime you load a scene. Then you just serialize your CurrentScene variable (it is serialized by persistent guid). Then on load you deserialize CurrentScene variable then you load your load this variable CurrentScene.LoadSceneAsync(). And then you will be inside your last scene.

    But that means all your scenes need to be addressable. And every time you load scene from another assetReference variable you need to set CurrentScene assetReference variable.
     
  3. Fakkau

    Fakkau

    Joined:
    Mar 11, 2013
    Posts:
    22
    Hmmm ok, so whenever I change scenes using an AssetReference, I can indeed simply manually store that AssetReference as a 'currentScene' variable. Easy, thanks!

    But I'm not too sure exactly how to serialize it though, you mention a persistent guid? Does simply serializing a variable of type AssetReference mean it will automatically save it using that persistent guid? Changes to asset bundles (or the names of files) wouldn't affect that guid as long as the linked scene is still addressable?
     
  4. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    429
    Calling JsonUtility.ToJson(CurrentScene) will save asset reference to JSON by guid.
    Or you just can serialize,
    with whatever serializer you want,
    CurrentScene.RuntimeKey.ToString() - this is guid based key of scene asset this thing never changes on one computer.
    You can then create new asset reference and pass there guide then load it. Or call Adressables.LoadSceneAsync( yourSavedSceneKey).
     
  5. Fakkau

    Fakkau

    Joined:
    Mar 11, 2013
    Posts:
    22
    Alright, so storing the unique runtime key as a string should work. But is there a way to take that saved runtime key (string) and get the corresponding AssetReference? I can load a scene using that string, but I need to find its AssetReference so I can keep track of which scene (AssetReference) has been loaded last.

    I could make a list of all the scene AssetReferences like you said, and then loop through them and check which runtimekey matches, but that feels... as though there should be a cleaner method.

    In any case, I'll try out this method for now. Thanks for the help!
     
  6. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    429
    There is no cleaner way. So matching is the only one. Good luck.
     
  7. Fakkau

    Fakkau

    Joined:
    Mar 11, 2013
    Posts:
    22
    Thanks, I just tested it and it all seems to work perfectly. I ended up simply keeping track of the active scene using the Asset Reference's runtime key (as a string) instead of storing the Asset Reference itself. That way, I don't need to convert the saved runtime key back to an Asset Reference.

    Yay! :)
     
    TextusGames likes this.
  8. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    429
    I am glad I helped you.;)
     
    unity_bill and Fakkau like this.