Search Unity

Runtime Scene Serialization package. Status?

Discussion in 'Package Manager' started by mitaywalle, Sep 11, 2021.

  1. mitaywalle

    mitaywalle

    Joined:
    Jul 1, 2013
    Posts:
    251
  2. ReinekeFux

    ReinekeFux

    Joined:
    Apr 7, 2015
    Posts:
    3
    Hi there - I am having the same question and am bumping this thread for that reason :) Did the package get removed from the registry? Best, ReinekeFux.
     
  3. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Hi there!

    Thanks for reaching out about this preview package. It exists to support the MARS Companion workflow, which is still in beta, and indeed under active development! The 0.2 version of this package is based on `com.unity.properties` and `com.unity.serialization` version 1.5.0-preview from the DOTS family of packages, and has become reasonably stable. However, because properties is still in preview, so too is runtime scene serialization. As with any preview packages, we do not provide official support, however I'd be happy to help troubleshoot any issues you are having! Please do heed the warning, though, that you may encounter issues in Unity 2020 and above, and especially if you are using other DOTS packages in your project. The package is still available and can be installed by name or by modifying your project manifest.

    I'm sorry to hear you're having trouble. The same APIs that work in the Editor _should_ work at runtime, as long as the codegen step is done. If you are using the latest version, you must go to `Project Settings > Runtime Scene Serialization` and manually enable codegen for the assemblies/classes you would like to serialize at runtime. Earlier versions (0.2.1-preview and below) generated code for all serialized types across all assemblies by default, but we encountered edge cases which caused build errors for some customers with the MARS Companion packgage in their project. Because of this issue, we updated the package to treat codegen as "opt-in," which has the added benefit of keeping your build size/time down if you aren't using runtime serialization.

    Hope this helps. Good luck!
     
  4. ReinekeFux

    ReinekeFux

    Joined:
    Apr 7, 2015
    Posts:
    3
    Thank you lots for the help & input. I will take a look at the package and see if it is a fit for the project that I am working on. Really curious where this will be taken in the future. :)

    Best,
    ReinekeFux
     
  5. swedishfisk

    swedishfisk

    Joined:
    Oct 14, 2016
    Posts:
    57
    Hey guys, anyone using this now and can share some info on current usability?
     
  6. swedishfisk

    swedishfisk

    Joined:
    Oct 14, 2016
    Posts:
    57
    Hey, testing this out now and seems to work nicely.

    I'm not sure of how much this package is supposed to handle, but when I try to serialize a running scene in editor I get warnings that GUIDs is missing for all materials and meshes in scene - which I half expected.

    But this begs the question how to fix this so I can import the scene and meshes and materials survive.

    I'm currently thinking about adding a layer that serializes the GUIDs on objects so while app is running this information is available and can be used to link up assets. But I almost half expected something like this in the package so just wondering if what I'm doing sounds sensible :)
     
  7. swedishfisk

    swedishfisk

    Joined:
    Oct 14, 2016
    Posts:
    57
    I tried rebuilding project using 2019 LTS and built-in render pipeline but same issue, meshes and materials can't be serialized (any assets references get lost if you serialize scene at runtime).

    I enabled all code-gen settings in project settings to be safe but still same issue.

    Can anyone confirm if you are supposed to be able to save and then import a scene and assets references survive?
     
  8. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Hey there! Thanks for your interest in this package. Sorry for the confusion--we're still working on improving the documentation for this package, which currently doesn't explain how to use an AssetPack to handle guids and asset references.

    Essentially, what you're missing is an `AssetPack` object which you can use to collect asset references. In Edit mode, you will need to serialize your scene using an Asset Pack, which can then be used to map between guid/FileId and object reference. An AssetPack is a ScriptableObject which can be saved as an asset for future use, or you can just instantiate one in memory if you do not need it to persist.

    Take a look at `Editor/MenuItems.cs` for an example of how to use an AssetPack. When you choose the `File > Save JSON Scene...` menu item, this code will create an AssetPack (or re-use an existing one) for the currently active scene and use it during serialization to collect asset references. Then, this AssetPack can be used in Edit Mode or at runtime to look up asset references that were serialized as guid/FileId in the json representation of the scene.

    If you want to serialize at runtime or in Play mode, you will still need an AssetPack pre-populated for any asset references that you might encounter. We can't use guids at runtime, so there is no way to reference a new asset whose guid we did not look up at runtime.

    There is one exception for this, which is the `IPrefabFactory` interface, which allows an external class to provide prefab references based on guid. It still requires that you use an AssetPack when deserializing.
     
    Threeyes and swedishfisk like this.
  9. eckz59

    eckz59

    Joined:
    Apr 21, 2021
    Posts:
    4
    Hello, I am going through some exercises to learn Unity and it looks like this is something that'd enable saving and loading a game without needing to address each GameObject or component individually. Is that an intended use for this package? Checking 'Editor/MenuItems.cs' it seems to rely on some assemblies only available in the editor rather than in a standalone build. Is there an example of loading/saving a scene in a standalone build (e.g. in response to some keypress or UI interaction)? Thank you
     
  10. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Hi there!

    Yep. This package is intended to help you save/load scenes, although it is still experimental and doesn't yet include proper documentation and samples. This is something we plan to improve, but for now this package exists to serve the AR Companion App workflow. We do not officially support using it on its own.

    I wouldn't recommend trying to integrate this package if you are new to Unity. There are some solutions on the Asset Store which serve a similar purpose and provide good documentation. I'm not familiar enough with them to endorse any particular product, but a quick search for serialization or save/load will get you started.

    As for your question about `Editor/MenuItems.cs`, the part that I was calling out in my last message is about how to use an AssetPack. The rest of it is somewhat specific to the Editor context, so you might instead look at the play mode tests for an example of how to serialize a basic scene with GameObjects. The high level is that you want to use `SceneSerialization.SerializeScene` to save and `SceneSerialization.ImportScene` to load. However, pretty much any useful scene is going to have asset references (even the default primitives are asset references) so you'll need to worry about AssetPacks, as described above.
     
  11. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    swedishfisk likes this.
  12. eckz59

    eckz59

    Joined:
    Apr 21, 2021
    Posts:
    4
    Thank you for the documentation! I believe I need to somehow use the Editor itself to "export" my scene and assets it refers to into an AssetBundle containing an AssetPack. If I'm not mistaken, the new documentation says I'm not really going to create such a AssetPack/AssetBundle in code at runtime. Instead, I should look at the Editor UI for such an export once I've added separate package " AR Companion Resource Manager ". Then, with that exported AssetBundle, I would be able to reference some code in that AR package which can load the exported AssetBundle at runtime. Have I understood this well?
     
  13. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Not exactly. I mentioned the AR Companion package as an example of how the package can be used to create AssetBundles, but you can't use it as a general purpose tool. It immediately uploads the asset bundle without saving a local copy, so you won't be able to use the generated AssetBundle in your own projects. However, reading the code in that package may help you write your own scripts. Generally speaking, projects that use AssetBundles use editor scripts to automate the process of building a bunch of AssetBundles at the same time as part of a larger build pipeline. Then, at runtime more code is needed to load up the AssetBundle and extract the asset references. You may want to put multiple `AssetPack` assets into one bundle to support multiple scenes, or build one bundler per-scene, or come up with some other strategy for managing your assets. This package makes no assumptions about how you use AssetBundles, but it sounds like a basic example of building/loading is something we could add as an improvement. In the meantime, I think this should get you started.

    In the editor:
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using System.IO;
    3. using UnityEditor;
    4. using UnityEditor.Build;
    5. using UnityEngine;
    6.  
    7. namespace Unity.RuntimeSceneSerialization
    8. {
    9.     static class BuildAssetBundles
    10.     {
    11.         [MenuItem("Assets/Serialization/Build AssetBundles", false)]
    12.         static void Build()
    13.         {
    14.             var builds = new List<AssetBundleBuild>();
    15.             foreach (var selected in Selection.objects)
    16.             {
    17.                 if (selected is AssetPack assetPack)
    18.                 {
    19.                     var path = AssetDatabase.GetAssetPath(assetPack);
    20.                     if (string.IsNullOrEmpty(path))
    21.                     {
    22.                         Debug.LogError($"Could not get asset path for {assetPack}");
    23.                         continue;
    24.                     }
    25.  
    26.                     var guid = AssetDatabase.AssetPathToGUID(path);
    27.                     if (string.IsNullOrEmpty(guid))
    28.                     {
    29.                         Debug.LogError($"Could not get valid guid for asset at path {path}");
    30.                         continue;
    31.                     }
    32.  
    33.                     // Check existing asset bundle name to avoid overwriting it
    34.                     var assetImporter = AssetImporter.GetAtPath(path);
    35.                     if (!string.IsNullOrEmpty(assetImporter.assetBundleName) && assetImporter.assetBundleName != guid)
    36.                     {
    37.                         Debug.LogError(assetPack.name + " is already part of an AssetBundle, and cannot be built to without overwriting its AssetBundle name. You need to temporarily set its AssetBundle name to None in the inspector in order to build this asset.");
    38.                         continue;
    39.                     }
    40.  
    41.                     builds.Add(new AssetBundleBuild
    42.                     {
    43.                         assetBundleName = path,
    44.                         assetNames = new[] {path}
    45.                     });
    46.                 }
    47.             }
    48.  
    49.             var outputPath = EditorUtility.SaveFolderPanel("Build AssetBundles",  new DirectoryInfo(Application.dataPath).Parent.FullName, "Bundles");
    50.             if (string.IsNullOrEmpty(outputPath))
    51.                 return;
    52.  
    53.             Debug.Log("Building AssetBundles");
    54.             var manifest = BuildPipeline.BuildAssetBundles(outputPath, builds.ToArray(), BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget);
    55.             if (manifest == null)
    56.                 throw new BuildFailedException("Failed to build AssetBundles");
    57.         }
    58.  
    59.         [MenuItem("Assets/Serialization/Build AssetBundles", true)]
    60.         static bool ValidateBuild()
    61.         {
    62.             if (EditorApplication.isPlayingOrWillChangePlaymode)
    63.                 return false;
    64.  
    65.             var isValid = false;
    66.             foreach (var selected in Selection.objects)
    67.             {
    68.                 if (selected is AssetPack)
    69.                 {
    70.                     isValid = true;
    71.                     break;
    72.                 }
    73.             }
    74.  
    75.             return isValid;
    76.         }
    77.     }
    78. }
    79.  
    Note the error about assets already having an AssetBundle name. I added this check to prevent this from interfering with any existing AssetBundle setup you may already have. This code would clear out those names otherwise and potentially break things. This example of a manual context item serves as a fine example to walk you through the process, but your ultimate solution will probably be a little different. Instead of building separate bundles for each asset pack, you may want to combine them or name them slightly differently.

    And in your game/app, something like this:
    Code (CSharp):
    1. using System.IO;
    2. using UnityEngine;
    3.  
    4. namespace Unity.RuntimeSceneSerialization.Test
    5. {
    6.     class LoadSceneWithAssetBundle : MonoBehaviour
    7.     {
    8. #pragma warning disable 649
    9.         [SerializeField]
    10.         string m_ScenePath;
    11.  
    12.         [SerializeField]
    13.         string m_AssetBundlePath;
    14. #pragma warning restore 649
    15.  
    16.         // TODO: Fix initialization bug to allow loading from Awake
    17.         void Start()
    18.         {
    19.             PropertyBagOverrides.InitializeOverrides();
    20.             var sceneJson = File.ReadAllText(m_ScenePath);
    21.             var assetBundle = AssetBundle.LoadFromFile(m_AssetBundlePath);
    22.             var assetPack = (AssetPack) assetBundle.LoadAllAssets()[0];
    23.             SceneSerialization.ImportScene(sceneJson, assetPack);
    24.         }
    25.     }
    26. }
    27.  
    The important things to remember here are to call `PropertyBagOverrides.InitializeOverrides` once before doing any scene imports, and to wait at least until the end of the first frame, otherwise you will hit errors because property bags haven't been initialized yet. Going through this example actually made me realize we can probably fix this, so it was a good exercise! I'll try to get these sample scripts into the package soon so users don't have to come here to find them.
     
    Last edited: Apr 1, 2022
  14. eckz59

    eckz59

    Joined:
    Apr 21, 2021
    Posts:
    4
    This was a very thoughtful reply @mtschoen, thanks for helping especially with the code samples and consideration for those integrating into more mature projects! Agree that example or perhaps a video might help folks. I think I have following questions still, hopefully they're simple to answer

    • I realized menu item "File->Save JSON Scene..." produces a <scenename>.asset file in the root of the project's Asset folder. Apparently this is the asset pack that I just need to have selected in the Project pane before I click the menu item "Assets->Serialization->Build AssetBundles". I don't think there's a need to make a separate asset pack - I can just select that produced one (as least until my scene changes)

    • When I use menu item "Assets->Serialization->Build AssetBundles", I'm creating a "Bundles" folder inside my root Assets folder and just telling the dialog to use that. It produces the following file structure. But when I put breakpoint from code taken from your LoadSceneWithAssetBundle class, it suggests the result of

      m_AssetBundlePath = Application.dataPath + "/Bundles/Bundles";
      var assetBundle = AssetBundle.LoadFromFile(m_AssetBundlePath);
      assetBundle.LoadAllAssets()[0]

      is not of type AssetPack but rather AssetBundleManifest. is it obvious what I've done wrong ?

      Code (csharp):
      1. <path/to/project>/Assets/Bundles
      2. │   assets.meta
      3. │   Bundles
      4. │   Bundles.manifest
      5. │   Bundles.manifest.meta
      6. │   Bundles.meta
      7. └───assets
      8.         scenename.asset
      9.         scenename.asset.manifest
      10.         scenename.asset.manifest.meta
      11.         scenename.asset.meta
     
    Last edited: Apr 2, 2022
  15. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    I think we're almost there!

    Yes, when you do `File > Save JSON Scene...` this process will create an AssetPack and save it to an `.asset` file next to the scene with the same name as the scene. This is an asset representation of the AssetPack ScriptableObject which was used to collect asset references when serializing the scene. If you select this asset, you can use the Inspector to see what asset references were collected when serializing the scene. When you build an AssetBundle, these dependencies get included automatically. You are right that this is what you should have selected when building AssetBundles.

    The directory structure created when building a single AssetBundle can be a little confusing, but the file you want from what you pasted is `Bundles/assets/scenename.asset`. That is the particular bundle that corresponds to the AssetPack you had selected. The path to each AssetBundle within the `Bundles` folder (or whatever you decide to call it) will match its path within the Assets folder. You can ignore the other files that are generated. If you don't put the output folder in the Assets folder, you also won't see the `.meta` files. Note that you can also make multiple selections and build them all at once.

    Unfortunately, the `ScriptableObject` for the asset in the Assets folder and the `AssetBundle` you build have the same extensinon: `.asset`. But they are distinct representations of the AssetPack, and both are needed. There won't be any files called `.assetbundle` or `.assetpack` in the process, just `.asset. The original `scenename.asset` file, which lives in the Assets folder is simply a list of asset references, with their guids and fileIDs stored as strings. If you use text-based asset serialization, you can easily read its contents in a text editor. The AssetBundle representation is a binary file which includes the AssetPack with those strings and asset references, but also the assets themselves transformed into whatever platform-specific representation is needed in order to be loaded in the Player. The same stuff that happens to your models and textures when you click "Build" for your app is happening when you build AssetBundles.

    It is important for the ScriptableObject `.asset` to remain in your project after the scene is saved. First of all, you wouldn't want to build AssetBundles every time you save the JSON scene because, as you have seen, it takes a lot longer to build the AssetBundle than it does to save the scene. Leaving the asset in your project after the scene is saved allows you to save a number of scenes, then select their AssetPack assets and build bundles.

    Furthermore, you need to build a different AssetBundle for each build target and save/load them in separate paths, etc. In other words, if you want to build your app for iOS and Android, you need two AssetBundles for each AssetPack: one built for iOS and one for Android. Leaving the ScriptableObject asset in the projects allows you to switch build targets and do your build as many times as you like without having to open the scenes and serialize them again. This is one of the main reasons why our simplistic example here is only going to get you so far. You would need to use a separate path for the iOS vs. the Android bundle and choose which one to use based in the current platform. And, of course, just working with the filesystem on mobile devices can be tricky--just trying to get the AssetBundles onto the local filesystem where the app can access the can be a challenge.

    You probably don't want to put your AssetBundle output directory in the Assets folder. With the code I shared, it should default to the project folder, not Assets folder. That's what the `new DirectoryInfo(Application.dataPath).Parent.FullName` was for. The Editor doesn't need to "know" about the built AssetBundles; they are only used by the Player. You can avoid getting those extra `.meta` files generated, and Unity will spend some time importing them having them in Assets will bog down your project.

    You are also right to think that you'll need to re-build the AssetBundle every time the scene/AssetPack changes. If a new asset reference is added, you will need to rebuild the AssetBundle (remember, one per-platform) in order to reference the asset. If a reference is removed, you probably want to rebuild to make the bundle a little smaller. This is why, in the case of the Companion App workflow, the Resource Manager helps track what scenes have been updated, and we use a cloud service to transfer files around. Doing it all "by hand" isn't really sustainable, so you will want to take the building blocks you see here and integrate them with some sort of content delivery system. You may also want to consider using Addressable Assets to provide a consistent reference to the AssetPacks in your project. Or you may find that it is more helpful to create custom scripting to combine all the asset references you need into one giant AssetPack. It depends on what you are trying to create.

    At this point it may have become clear why we consider this package experimental. As I explained above, the primary purpose of this package is to support the AR Companion App workflow. This allows us to focus on building out a workflow that serves AR developers while incubating this general-purpose scene serialization functionality. It goes beyond the scope of the AR Companion project to support users with their own serialization workflows, but It's great to hear that some are trying.
     
  16. eckz59

    eckz59

    Joined:
    Apr 21, 2021
    Posts:
    4
    Very generous reply, thanks again @mtschoen ! Think I'm on the final stretch now; I'm seeing many "could not find GUID" and "could not find asset metadata" warnings in the console when I try serializing the scene from play mode. In AssetPack's GetAssetMetadata() method, I'm noticing that
    m_AssetLookupMap.TryGetValue(obj, out assetData)

    returns false seemingly only because the key in m_AssetLookupMap that looks like it should match has a different InstanceID than the obj passed in. I imagine since the dictionary lookup relies on this equality definition between Unity Objects that we expect the InstanceIDs to match. Any idea why in my case they might not? I'll keep debugging but figured worth asking if you'd seen that during your development too.
     
  17. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Do you already have a fully-populated AssetPack for those assets? Even though I think we technically _could_ still look up guids for some types of assets in Play Mode, we don't because Play Mode is intended to be a simulation of how your app will behave in the Player. If we "cheat" in Play Mode, it would hide the fact that the same behavior in the Player will fail. One way or another, any time we need asset metadata, we need to be in edit mode.

    In other words, you shouldn't expect serialization to work in Play Mode unless you already have an AssetPack containing the asset references you need. If you are trying to serialize a _brand new_ scene that was built in Play Mode, you will need to provide an AssetPack that has been created at edit time containing all of the potential assets you made available in your editor. In other words, if a user can place a tree in the scene with a mesh, a material, and a texture, that tree had to come from somewhere, and wherever you set that up, you need to generate an AssetPack with those references. Using Prefabs can be helpful, but you will also need to instantiate those prefabs with a `PrefabMetadata` script attached containing the guid of he original prefab. This is where `IPrefabFactory` can be helpful. We use that in the AR Companion app to provide extra prefabs for users to play with that are bundled up separately from the scene. This prefab list contains its own mapping for prefab-to-guid.

    It depends on what the object is and what you are trying to use it for. For the same reasons I described above, there is no direct equivalence between instances of objects in Play Mode and Edit Mode; Play Mode is a sandbox. I think the issue you're seeing the fact that you have some references to assets in your scripts, which you use to create instances in Play Mode. Then you want to serialize a scene that references these instances. I think that maybe if the AssetPack is _also_ built into your scene this may work, but it doesn't allow you to change the AssetPack after the build, so I wouldn't recommend going this route.

    The most straightforward way to use this package is for your workflow to _start_ in the Editor, so that you can build your scene as normal, pack it up with all its assets, and then let users _modify_ it within a Player build, without introducing new assets after the fact. That way you can either do what I described and just build the AssetPack right into the build, or keep the scene external, and start by deserializing the JSON scene in the player along with its AssetPack (loaded via AssetBundle), and then you can be sure every asset reference came out of the AssetPack, and the instance IDs will all match.

    If you really want your users to start from scratch, you can pack a bunch of prefabs and assets into an AssetPack by either serializing an arbitrary scene containing them all, or writing an Editor script to manually set up an AssetPack. Then you can list out the included prefabs in your UI somewhere and let users pick and choose from them.

    Just remember that, fundamentally, you always need an AssetPack in Play Mode or Player builds that contains references to the assets you need, mapped to their metadata (guid and fileID). This applies to both serialization and deserialization. Both processes need to be able to either convert an object reference into its metadata or metadata into an object reference, and the AssetPack is where they get that mapping.
     
  18. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Hi there!

    I wanted to share a quick update on this package. We just released the `0.3.5-preview` version which contains some bug fixes as well as an AssetBundle Sample which includes the scripts I shared above. We've also improved the documentation to describe how to use the sample and provide more information about how to use AssetPacks with AssetBundles within your project. I hope this helps!
     
    swedishfisk likes this.
  19. swedishfisk

    swedishfisk

    Joined:
    Oct 14, 2016
    Posts:
    57
    Hey awesome progress on the package!

    I've ran into some issues now. It seems UnityEvents with parameters cannot be serialized. Not a big deal for me but maybe good to know (let me know if you want me to open a ticket, not sure how this stuff works with preview packages).

    But another more blocking problem is that I get an error when serializing scene on android builds.

    I get 'Missing property bag error' regarding a type that's a compiled monobehaviour (dll). This reference has been added to the AOT Code Generation Settings. Is this expected to work? It works fine in editor at least, I'm going to try to decompile the class and check again (it's a third party asset).

    I did try to call RegisterPropertyBagRecursively with the type during editor mode but it doesn't respond with anything (no console logs) so not sure if I'm using it correctly.

    Any help much appreciated!
     
  20. swedishfisk

    swedishfisk

    Joined:
    Oct 14, 2016
    Posts:
    57
    Hello again! I can confirm that if you have a compiled dll that contains a serializable class you can't serialize it properly on Android targetting IL2CPP (maybe other targets doesn't work either, but we have to target IL2CPP so I can't verify that).

    After decompiling the dll containing the monobehaviour into a regular source file serialization worked, so it seems compiled dlls are the problem.

    Would be awesome if this could be supported, but I'm not aware of the technicalities of doing this, in the meantime we'll start doing our own custom serializer for the troublesome class.
     
  21. swedishfisk

    swedishfisk

    Joined:
    Oct 14, 2016
    Posts:
    57
    Hey! I'm testing the latest version and noticed that sub-assets are problematic to serialize and sometimes fails. I see these problems when using FBX files with sub-assets like materials and sub-meshes.

    Sometimes they work and sometimes not, typically one or more submeshes or submaterials are serialized correctly, but sometimes they fail and it seems quite random. I end up with pink missing materials on some parts of objects, or missing sub-meshes.

    Sometimes I've had success unpacking a scene FBX and then serializing/deserializing and it works again. So seems the assetPack does pick up the asset but for some reason not all the sub-assets.

    I've also noticed that if I extract materials from the FBX and place them in something like Assets/Materials so they're no sub-assets anymore it will always work.
     
  22. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Hey there! Sorry for the delayed reply--I was on vacation last week :)

    It's great to hear that you're getting so deep in the weeds with runtime scene serialization! I'm sorry to hear you're having trouble, but thanks for reporting these issues. I did a basic test with pre-compiled DLLs early on, but I didn't see the issues you are seeing. Is this DLL marked to be used in the Editor and other player platforms, or is it per-chance only included in Android builds? There is a known issue around types that don't exist at edit time, but are only present in player builds.

    From what I can tell, you're doing the right thing by enabling AOT code generation on the types that need it, and calling RegisterPropertyBagRecursively before doing serialization work. The missing sub-assets are quite a surprise, as AssetPacks are explicitly designed to reference assets by guid and fileID.

    If you are able, please do submit a ticket through the Unity bug reporter (Help > Report a bug) from a project that replicates the issues you are seeing. Generally speaking, we don't support preview packages, but this is still the best way for users to submit projects for reproducing issues. If you have one project that exhibits every issue, that's fine, but it may be easier to isolate each problem in a different bug--do whatever is most convenient for you.
     
    swedishfisk likes this.
  23. swedishfisk

    swedishfisk

    Joined:
    Oct 14, 2016
    Posts:
    57
    Hey again! Now I've been on vacation :) Hope all is well with you, I've asked a colleague to provide a bug report showing the problem of compiled components not being serialized/deserialized correctly: https://unity3d.atlassian.net/servicedesk/customer/portal/2/IN-3845

    We really tried boiling it down to its simplest form, turns out no matter the datastructures inside the class it turns out compiled components makes the runtime scene serialization fail.

    Regarding the other issue on prefab serialization, the assets we use for the project now don't seem to exhibit this issue so I will get back if that problem arises again of sub-assets not working. Awesome that you have thought about it and made such a robust system. Thanks for your time!
     
  24. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Hi there! Sorry for the long delay again, but I finally had a chance to look at your repro cases. For the script-in-a-DLL case, this is indeed a bug, or you could say it is an "undocumented limitation" of the system. :)

    The code generation post processors seem to be missing that DLL which means no property bag is generated for the contained types and thus I would expect to see the errors you are seeing. There is a step for including precompiled DLLs (including UnityEngine.dll, etc.) but it's not picking up on it. Vexingly, it does find the TestEmptyClass script in one part of the pipeline but not the more important part that generates the property bags. :(

    This must have regressed at some point and unfortunately wasn't covered by automated testing. I'll work on a fix but I can't promise anything soon. Hopefully you can work around this issue in the meantime by making sure that you define any MonoBehaviour components in assemblies that are compiled by Unity. Note that you should be able to reference pre-compiled DLLs in these MonoBehaviours, but I think you should be fine as long as the "root" type being serialized is in one of these Unity assemblies.

    As for the prefab GUID issues, this is expected behavior, for better or worse. The problem is that, when you're in play mode, we don't know that the thing you're trying to serialize is a prefab. When you save an AssetPack for the scene in edit mode, it is a prefab, so you save a reference to the prefab asset, not the individual assets that make up the prefab. This is fine if you start with a version of the scene which is deserialized from JSON, because prefabs are deserialized with an extra script that contains the guid and prefab overrides. I understand why this is unexpected behavior, but it is still "correct" given the fact that prefabs are unpacked when you enter Play mode.

    There are two ways to resolve this:
    - Unpack the prefabs in scenes that you want to serialize before generating their asset packs
    - Always work with the JSON-deserialized version of a scene in play mode and player builds

    I would recommend the latter approach, because it allows you to use prefabs instead of always breaking scenes down into their individual asset references. Furthermore, it means that you won't be able to accidentally add asset references to the Unity scene which isn't represented in the AssetPack. Whenever you save the JSON scene, you will also update its AssetPack.

    This is also where the `IPrefabFactory` interface comes in handy. You can add extra content to the scene at runtime via prefabs that may not have been in the original scene by implementing this and hooking it up to the AssetPack you use to serialize/deserialize the scene. This can be backed by more AssetPacks, or your own data structure for generating AssetBundles containing those Prefabs, indexed by their guid. That way you can still have prefabs be part of your workflow, and avoid having to build a lot of assets into each scene's AssetPack.

    To be clear, though, as long as you deserialize the scene from JSON, you will be able to re-serialize a scene with prefabs properly, without seeing these warnings. In that situation, the serializer will not look up references for each asset within the prefab hierarchy, but instead will just write out its guid and any overrides applied to it. Note that if you want to modify the prefab (including its Transform), you will have to explicitly set overrides for the properties you are modifying in order to save those changes.

    Let me know if you have any further questions. I'll update this thread when I've been able to release a fix for the DLL issue. Cheers, and good luck!
     
    swedishfisk likes this.
  25. Xriuk

    Xriuk

    Joined:
    Aug 10, 2018
    Posts:
    21
    Hi, I tried using this package in our project but I can't get it to serialize a scene it always goes in StackOverflow, because of prefabs, here's a log.
    Unity 2020.2.0:
    Code (CSharp):
    1. StackOverflowException: The requested operation caused a stack overflow.
    2. Unity.RuntimeSceneSerialization.Internal.Prefabs.RuntimePrefabPropertyOverride.Create[TContainer] (UnityEditor.SerializedProperty property, System.String propertyPath, System.String transformPath, System.Int32 componentIndex, System.Boolean& hasNext, System.Boolean& shouldIterate, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Prefabs/RuntimePrefabPropertyOverride.cs:136)
    3. Unity.RuntimeSceneSerialization.Internal.Prefabs.RuntimePrefabPropertyOverride.CreateMultiple[TContainer] (UnityEditor.SerializedProperty property, System.String rootPropertyPath, System.String transformPath, System.Int32 componentIndex, System.Boolean& hasNext, System.Boolean& shouldIterate, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Prefabs/RuntimePrefabPropertyOverride.cs:90)
    4. Unity.RuntimeSceneSerialization.Internal.Prefabs.RuntimePrefabPropertyOverride.Create[TContainer] (UnityEditor.SerializedProperty property, System.String propertyPath, System.String transformPath, System.Int32 componentIndex, System.Boolean& hasNext, System.Boolean& shouldIterate, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Prefabs/RuntimePrefabPropertyOverride.cs:124)
    5. Unity.RuntimeSceneSerialization.Internal.Prefabs.RuntimePrefabPropertyOverride.GetOverrides[TContainer] (TContainer instanceObject, System.Collections.Generic.List`1[T] overrides, System.String transformPath, System.Int32 componentIndex, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Prefabs/RuntimePrefabPropertyOverride.cs:197)
    6. System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <9577ac7a62ef43179789031239ba8798>:0)
    7. System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <9577ac7a62ef43179789031239ba8798>:0)
    8. Unity.RuntimeSceneSerialization.Internal.Prefabs.RuntimePrefabPropertyOverride.GetOverrides (UnityEngine.Object instanceObject, System.Collections.Generic.List`1[T] overrides, System.String transformPath, System.Int32 componentIndex, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Prefabs/RuntimePrefabPropertyOverride.cs:181)
    9. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:80)
    10. Unity.RuntimeSceneSerialization.Internal.GameObjectContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/GameObjectContainer.cs:126)
    11. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer.GetMetadataRecursively (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata, System.String parentTransformPath, System.String transformPath) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:119)
    12. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:111)
    13. Unity.RuntimeSceneSerialization.Internal.GameObjectContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/GameObjectContainer.cs:126)
    14. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer.GetMetadataRecursively (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata, System.String parentTransformPath, System.String transformPath) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:119)
    15. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:111)
    16. Unity.RuntimeSceneSerialization.Internal.GameObjectContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/GameObjectContainer.cs:126)
    17. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer.GetMetadataRecursively (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata, System.String parentTransformPath, System.String transformPath) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:119)
    18. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:111)
    19. Unity.RuntimeSceneSerialization.Internal.GameObjectContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/GameObjectContainer.cs:126)
    20. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer.GetMetadataRecursively (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata, System.String parentTransformPath, System.String transformPath) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:119)
    21. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:111)
    22. Unity.RuntimeSceneSerialization.Internal.GameObjectContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/GameObjectContainer.cs:126)
    23. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer.GetMetadataRecursively (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata, System.String parentTransformPath, System.String transformPath) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:119)
    24. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:111)
    25. Unity.RuntimeSceneSerialization.Internal.GameObjectContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/GameObjectContainer.cs:126)
    26. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer.GetMetadataRecursively (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata, System.String parentTransformPath, System.String transformPath) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:119)
    27. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:111)
    28. Unity.RuntimeSceneSerialization.Internal.GameObjectContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/GameObjectContainer.cs:126)
    29. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer.GetMetadataRecursively (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata, System.String parentTransformPath, System.String transformPath) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:119)
    30. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:111)
    31. Unity.RuntimeSceneSerialization.Internal.GameObjectContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/GameObjectContainer.cs:126)
    32. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer.GetMetadataRecursively (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata, System.String parentTransformPath, System.String transformPath) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:119)
    33. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:111)
    34. Unity.RuntimeSceneSerialization.Internal.GameObjectContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/GameObjectContainer.cs:126)
    35. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer.GetMetadataRecursively (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata, System.String parentTransformPath, System.String transformPath) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:119)
    36. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:111)
    37. Unity.RuntimeSceneSerialization.Internal.GameObjectContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/GameObjectContainer.cs:126)
    38. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer.GetMetadataRecursively (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata, System.String parentTransformPath, System.String transformPath) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:119)
    39. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:111)
    40. Unity.RuntimeSceneSerialization.Internal.GameObjectContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/GameObjectContainer.cs:126)
    41. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer.GetMetadataRecursively (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerialization.SerializationMetadata metadata, System.String parentTransformPath, System.String transformPath) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.3.5-preview/Runtime/Internal/Containers/PrefabMetadataContainer.cs:119)
    42. Unity.RuntimeSceneSerialization.Internal.PrefabMetadataContainer..ctor (UnityEngine.GameObject gameObject, Unity.RuntimeSceneSerializ
     
    Last edited: Jul 16, 2022
  26. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Whoops! That's not great =\

    I am able to get a stack overflow to happen if I create a prefab and then add an instance of itself as an added GameObject. This is honestly just a scenario we never though of when testing, so it slipped through the cracks. However, I get a slightly different stack trace in this case. Can you submit a bug report via the normal bug reporter (Help > Report a Bug...) so I can take a look at your scene? If you aren't comfortable sharing your whole project, can you come up with an isolated reproduction case?

    I'll get working on a fix for this soon. Sorry for the inconvenience, and thanks for reporting!
     
  27. Xriuk

    Xriuk

    Joined:
    Aug 10, 2018
    Posts:
    21
    Hi I sent the report, fortunately I was able to replicate our setup in a new project: https://unity3d.atlassian.net/servicedesk/customer/portal/2/IN-11111

    I think the problem is in how you are saving prefabs (and overrides?) now, with recursion.
    I don't know if our setup is considered "orthodox" or not, but basically in each scene we have a SceneRoot prefab (which handles the custom serialization of all objects in the scene, this was prior to discovering this package, cause we implemented our own save system).
    But even if we remove the root we still have a prefab for each room in the scene, that is because the prefab has predefined "folders"/gameobjects like Lights, Entities, Triggers, ... so we can organize our scenes better.
    We make "heavy" use of nested prefabs, so I don't know if it would be a big deal to rework your save system to accomodate for that, maybe recursion would be good only for simpler scenes, in fact the package works fine with a simpler development scene with fewer prefabs.
    I don't think this is about the quantity of prefabs as it is about nesting them mainly.
     
  28. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Thanks for the bug report! I'll get this fixed as soon as I can.
     
    Xriuk likes this.
  29. Guillaume_Gleechi

    Guillaume_Gleechi

    Joined:
    Jan 19, 2022
    Posts:
    2
    Hello and thanks a lot for your previous answers !
    I am having an issue while creating the Asset Pack with fbx meshes that are sub-assets both in 2020.3.33 and 2021.3.6. As you can see in the screenshot there, some of the sub-assets get assigned a negative fileID and everything looks fine in the inspector and there seems to be a proper connection between the asset pack and my assets

    AssetPack.png

    However it seems like negative fileIDs are rejected and log warnings such as :
    Code (CSharp):
    1. Could not find sub-asset for Pipe.001 (UnityEngine.Mesh) at fileId -1289390338209425561
    2. UnityEngine.Debug:LogWarningFormat (string,object[])
    3. Unity.RuntimeSceneSerialization.Internal.UnityObjectReference:GetReferenceForObject (UnityEngine.Object,Unity.RuntimeSceneSerialization.SerializationMetadata) (at Library/PackageCache/com.unity.runtime-scene-serialization@0.6.0-preview/Runtime/Internal/UnityObjectReferenceProperty.cs:92)
    EDIT: I noticed that the fileIDs don't match in the screenshot and in the log but it is because I had rebuilt the asset pack in-between. I just tried again and the log shows the same fileID as the asset pack

    I have looked into it a bit as some of my other assets are not causing this issue, and from what I understand the fileIDs are sometimes built based on the property internalIDToNameTable of the .meta file of the FBX as shown in this screenshot (not all IDs match but there is definitely a connection) : upload_2022-9-20_14-52-19.png

    For the problematic asset, the field
    internalIDToNameTable
    is empty and I have failed at understanding and finding documentation on how to generate it.
    So it seems like in the first case, some random fileIDs are generated and turn out to be negative, and then rejected even though they look valid in the inspector.

    Thanks in advance for helping, let me know if I should create a bug report or if I am just doing something wrong. Cheers !
     
  30. Guillaume_Gleechi

    Guillaume_Gleechi

    Joined:
    Jan 19, 2022
    Posts:
    2
    So a little update from yesterday, I managed to make it work by manually modifying the .meta file in this way : upload_2022-9-21_9-23-47.png

    I am not so sure why it works though and what is the reason why it didn't work in the first place !
     
  31. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Hi there! Thanks for sharing this question, and the workaround! I actually came across this issue recently, myself. I was (incorrectly) treating negative file ID's as invalid. I'll make sure to get this fixed in the next release. It should be a pretty minor change, so in the meantime you can embed the package and fix it on your end. I'll reply back later today with details on how to fix the issue locally.
     
  32. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Hey there! I'm pleased to inform you that the latest two bugs being discussed in this thread (recursive prefabs and negative fileIDs) have been fixed in the latest version(s) of `com.unity.runtime-scene-serialization`!

    You can pull version `0.3.7-preview` or `0.6.2-preview` (depending on your target Unity version) into your project to take advantage of the fixes.

    @Guillaume_Gleechi, @Xriuk, please let me know if you have any further issues.

    Cheers!
     
  33. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,164
    This package seem not to work in unity 2022.2.1

    There are many error related to interface implementation or protection level of class member access. And so highly suspect it didn't work in any later version

    upload_2022-12-25_16-7-31.png

    Update serialization and properties package causing even more error

    upload_2022-12-25_16-11-14.png
     
    Last edited: Dec 25, 2022
  34. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    That is correct. We have a new version that is currently going through approvals which should resolve this issue. I'll update this thread when it is ready.
     
    Thaina likes this.
  35. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Alright! Docs aren't up yet but `com.unity.runtime-scene-serialization@1.0.0-exp.3` is live! Please give that version a try and let us know if you run into any issues in 2022.2+
     
    mitaywalle and Thaina like this.
  36. thomas3dat

    thomas3dat

    Joined:
    Feb 24, 2021
    Posts:
    2
    Hey @mtschoen,

    I was playing around with this package, just to see what it can do, but I am correct to assume that the serialization system used here does not support the SerializeReference attribute?
    The data serialized using this attribute doesn't get saved to the json.

    Our team is actually very interested in a solution like this for multiple reasons, but we also already use the SerializeReference attribute in a couple of our systems and it would be hard to refactor that at this stage (because that would mean losing serialized data)

    So we were wondering if we were doing something wrong or if it is just not supported,
    in case of the latter is this something that might be added in the future?

    Btw, cool package! ;)

    Thanks in advance!
    Thomas
     
  37. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Hi there!

    Indeed, `SerializeReference` is not supported. I don't suppose there is a fundamental reason for why this is the case, but it wasn't in scope for our original requirements. Unfortunately, it would be a pretty major refactor (and likely breaking change) to support serialized references properly. Furthermore, we haven't encountered a need for `SerializedReference` for the AR Companion workflow (for which this package was created) and thus we aren't likely to add support any time soon.

    I will update this thread if that situation changes. In the meantime, it might be worth it to try customizing the package on your end to add `SerializedReference` support. While we have to worry about backwards compatibility and support/maintenance, you may be able to hack in the features you need specific to your situation. If you hit a snag, I can probably help you troubleshoot, but I can't make any promises.

    Good luck!
     
    thomas3dat, mitaywalle and Thaina like this.
  38. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    613
    Hi there @mtschoen , I have recently discovered this package and I love it!

    I saw 2 things that could be improved very easily and I wanted to share them with the creators (already being a douche about it I know I’m sorry)

    1. Polymorphism not supported.
    SceneSerialization doesn’t support polymorphism but I was able to bypass it doing this:
    SceneSerialization.ToJson((dynamic)myObject));

    So if that works, it might as well be added to the package I thought.

    2: SafeDestroy performance.
    I noticed you had a private method SafeDestroy (or similar). I don’t know how often it gets called but this has better performance in builds and is really elegant:
    Code (csharp):
    1. #if UNITY_EDITOR
    2. if (!Application.isPlaying)
    3. {
    4.     DestroyImmediate(obj);
    5. }
    6. else
    7. #endif
    8. {
    9.     Destroy(obj);
    10. }
     
    Last edited: May 6, 2023
    mitaywalle and Thaina like this.
  39. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    613
    I also wanted to share something I'm using this to hopefully inspire someone. I've created this menu:

    Code (CSharp):
    1. [MenuItem("CONTEXT/Object/Serialize", priority = 200)]
    2. private static void Serialize(MenuCommand command)
    3. {
    4.     var content = (string)SceneSerialization.ToJson((dynamic)command.context); // We need to cast to dynamic since SceneSerialization doesn't support polymorphism.
    5.     ProjectWindowUtil.CreateAssetWithContent($"New{command.context.GetType().Name}State.json", content);
    6. }
    Which allows me to easily create a json file out of any object that I then save in my Unity project. I then have this script:
    Code (CSharp):
    1. public class Test : MonoBehaviour
    2. {
    3.     public TextAsset defaultState;
    4.     public TextAsset crouchState;
    5.  
    6.     [ContextMenu("Default")]
    7.     public void Default()
    8.     {
    9.         var capsuleCollider = GetComponent<CapsuleCollider>();
    10.         SceneSerialization.FromJsonOverwrite(defaultState.text, ref capsuleCollider);
    11.     }
    12.  
    13.     [ContextMenu("Crouch")]
    14.     public void Crouch()
    15.     {
    16.         var capsuleCollider = GetComponent<CapsuleCollider>();
    17.         SceneSerialization.FromJsonOverwrite(crouchState.text, ref capsuleCollider);
    18.     }
    19. }
    With this simple setup I have an easy json file I can use to save state and manipulate objects at will.
    Default.png

    Crouch.png

    The implications are massive here! Character Controllers with a lot of complexity (crouching, swimming, climbing, flying, skydiving <- think Tears of the Kingdom) will need to change the state of a TON of objects, all the time. Unless you want to create massive unreusable inspectors where you show all the different settings in a big confusing cluster, then this simple state saver is the way to go!

    Also massively useful for item manipulation, e.g. changing a rigidbody when you pick it up.

    It is something I've always wanted in Unity and with this system it's literally 2 lines of code and stores the data in cheap json files for you to reuse and design around. Amazing asset!
     
    swedishfisk, mitaywalle and Thaina like this.
  40. Threeyes

    Threeyes

    Joined:
    Jun 19, 2014
    Posts:
    80
    Hi, I am using Unity 2022.3.4f1 LTS, and some wierd error happens:

    1.when I try to serialize Components with [RequireComponent] attribute.
    For example, in this gameobject, the Image Component relies on CanvasRenderer Component, if you put the order of Image lower than CanvasRenderer, then every works fine.
    微信截图_20230716221213.png
    But if the order of Image is higher than CanvasRenderer, I will get the following error when I try to load the scene:
    微信截图_20230716220759.png

    And if the scene contains gameobject with HingeJoint Component, it will show the following error on save no matter what order the components are:
    微信截图_20230716221625.png

    2.All gameobject become active after loaded (Instance or prefab).

    Thanks for your time! It's a perfect solution to save game state!
     
    Last edited: Jul 18, 2023
  41. unityl2ga

    unityl2ga

    Joined:
    Feb 3, 2022
    Posts:
    10
    Hello there. I am not able to import this package.
    I have added "com.unity.runtime-scene-serialization": "1.0.0" in my packages manifest.json file and I am using Unity 2021.3.21f1 LTS version

    Am I missing something?
     
  42. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,164
    Because it is currently still being "1.0.0-exp.3" maybe?
     
  43. unityl2ga

    unityl2ga

    Joined:
    Feb 3, 2022
    Posts:
    10
    Yes . Changing to it worked !
    Thanks a lot :)
     
  44. TMC_YusukeKobayashi

    TMC_YusukeKobayashi

    Joined:
    Jan 13, 2022
    Posts:
    1
    Hello
    In Version 0.6.2, the Active state of GameObject could be loaded, but it seems that this is no longer possible in Version 1.0.0.
    (Whether in the File “JASON Scene” menu or at runtime)
    Is there a setting somewhere?