Search Unity

Question C#: Difference between ForceReserializeAssets and Reimport?

Discussion in 'Asset Database' started by alexanderaowen, Jul 12, 2022.

  1. alexanderaowen

    alexanderaowen

    Joined:
    Oct 25, 2020
    Posts:
    2
    Hi all,

    I'm using Unity 2020.3.30, so Asset Database V2.

    We had some strange bug where the Library artifacts were sometimes missing references to other objects, and clicking "Reimport" on the asset from the Project view would resolve the issue.

    I'm looking to do this programmatically from code. Does anyone know the difference between AssetDatabase.ForceReserializeAssets and the Reimport menu option? I suspect that ForceReserializeAssets does _more_ than reimport, but also does a reimport. For my purposes, that would be sufficient, but I'm looking for more clarity on these two actions.
     
  2. doday

    doday

    Joined:
    May 12, 2015
    Posts:
    41
    I am on the same project as alex, and to add to this for future google explorers, we saw this manifest in two ways. Both are creeping issues. They do not occur when the object is first authored, or even when it is touched. Random assets just seem to get in a bad state.

    The first manifestation was intermittent dereferenced VFX. This was wildly inconsistent: sometimes the dereference would be local only, sometimes it would affect everyone on the project, which means it somehow got transmitted through perforce. However, someone fixing themselves locally would not generate any submittable changes, so we could not just fix it once and have people sync.

    The fix was to reimport and reserialize all prefabs under a selection of folders. This would make everything work correctly. Notably, if we then deleted the Library folder and regenerated it, the issues would come back, for all the same assets that were broken before. We iterated on this solution, and found a way to detect specifically which assets were broken, so we could only reimport / reserialize those. We have this as part of a build step, now. We never fixed the underlying issue.

    The second we are wrangling right now. So far, it seems to only happen to FBXs in a prefab that is instantiated at runtime. The most frustrating thing for us it is only happened on one machine: Our build machine. We could never repro locally, in editor or builds, so we had to submit changes and run a build to iterate on the issue.

    The obvious symptom is that the object and any children do not show up. After more logging, we discovered the names of these objects were wrong. All the names were
    "Placeholder for referenced GameObject in Prefab instance"
    for every broken Game Object, and all their children. In addition, they were active, whether we had saved them active in the prefab or not, and they were at (0,0,0). So default data.

    I googled that string, and searched these forums, and could not find anything. It seems like a string Unity is creating, but I don't know when or why. Perhaps Unity names every object that before some sort of initialization happens when it loads a prefab, and that process went awry.

    We tried just reimporting the broken assets, but it worked on one and not the other. We are now trying Reimporting and Force Reserializing, but the results will take time. The question of what the difference would be prompted this thread.
     
    Last edited: Jul 12, 2022
  3. unity_chris

    unity_chris

    Unity Technologies

    Joined:
    Dec 23, 2015
    Posts:
    18
    Reimport is basically equivalent to
    Code (CSharp):
    1. AssetDatabase.ImportAsset()
    , and will attempt to reimport the asset from disk into the database - i.e. re-running its associated importer.

    Code (CSharp):
    1. AssetDatabase.ForceReserializeAssets()
    is more about re-serialisation of in-memory changes to disk, and the intention behind making this available is that when you get a new version of Unity, there are often subtle (and not-so-subtle) changes to the way assets are serialised. If we've done this correctly, it's deterministic, so in many cases, we don't bother to update the assets on disk to avoid churn in source control when switching versions (as outlined in the manual page: https://docs.unity3d.com/ScriptReference/AssetDatabase.ForceReserializeAssets.html). So the idea was to give users full control and granularity over 'updating' these assets and saving them back to disk.

    As for the issue you're facing, "Placeholder for referenced GameObject in Prefab instance" is indeed created within Unity in the event of a prefab instance having a missing/broken connection to its source prefab. A placeholder is created in the hope that the connection can be fixed later during the load, and to make sure any references to components stay valid, but it seems in this case Unity is unable to reconcile them.

    Prefabs folks might be able to advise further on the specifics of what might be happening here.
     
    alexanderaowen likes this.
  4. bastien_humeau

    bastien_humeau

    Unity Technologies

    Joined:
    Jun 14, 2017
    Posts:
    191
    Are you using Accelerator on the machine where the assets seem to be broken? Or maybe there is a Library folder that would contain a broken version of the FBX or Prefab files. That's the main thing that comes to mind for me when I read your message.
    ForceReserialize and/or ImportAsset forces Unity to process the import locally and update the Library even if the result was already there, which would explain why the references would go from broken to fixed and that there is nothing to commit from the project itself.
    I can't say for sure without proper debugging, but it looks like a missing dependency somewhere between the fbx file and/or the Prefab that would make sure everything gets updated properly and stays up to date...
     
  5. doday

    doday

    Joined:
    May 12, 2015
    Posts:
    41
    Thanks for the response. We have gone through quite a few Unity versions on this project over the years. I don't even know what the original version was. I know it was 2017.x at one point, then 2018.x, and now is 2020.x. So serialization changes across Unity versions, complicated by various third party packages perhaps, could be the culprit.
     
  6. doday

    doday

    Joined:
    May 12, 2015
    Posts:
    41
    I had to look up what Accelerator was. We had a shared library cache thing before, but the Pandemic / WFH made it less useful, so we turned it off. We do not use Accelerator.

    As for the broken library thing, that does seem likely, but the real confusing part is why the first manifestation of this comes back when you delete your Library and regen. Force Reimport / Reserialize does some work to fix it that clearing your Library reverts. Bizarre. But we have an automatic fix now, so this is not a critical bug, just a curiousity.

    The second manifestation is a current bug and our reimport / reserialize fixed one for PC and iOS, but not Android. It fixed another on Android (at least, others untested) for one day then broke again the next build. So, very inconsistent.
     
    Last edited: Jul 14, 2022
  7. alexanderaowen

    alexanderaowen

    Joined:
    Oct 25, 2020
    Posts:
    2
    Hi Bastien, thanks for responding!

    I confirmed we're not using Accelerator on the affected machine. None of our machines (local or build) are currently using Accelerator.

    I was thinking an out of date Library was the like the most likely candidate, but investigations on that path haven't lead to any conclusions. I have inspected the Library files using the binary2text tool a few times (the one shipped with Unity), they've been fruitless results so far.

    Another observation about our situation is that the FBX is only missing on our mobile builds (Android and iOS), but the game object appears correctly on PC (Windows) builds.

    I'll describe the problem in more detail, just in case it rings any bells:
    We have a prefab for one of our characters. In the prefab, there are a few Timeline instances (Playable Director component). On one of these timelines, the character makes an object appear and then disappear, and the bug is that the object never appears. The game object that should appear is an imported FBX object, and it is instantiated in the prefab, under a "Props" parent game object. We added a logger to monitor the missing object at runtime on the build (because the issue does not reproduce in Unity Editor), and it's name is
    "Placeholder for referenced GameObject in Prefab instance" at runtime.

    I appreciate your time, let me know if you have any ideas we can try.
     
  8. doday

    doday

    Joined:
    May 12, 2015
    Posts:
    41
    To add to Alex's description, we previously had issues where the Activation tracks for some objects were not turning inactive objects active correctly. The fix was to make objects invisible in other ways: scaling down to 0, turning off their mesh renderer, changing some material properties, etc. This worked before, so I think it was a different issue than the one we are discussing now.

    For the current issues, though, the timeline turns the object visible by turning on the Mesh Renderer, not an Activation track, and it still does not show up. Instead, it is the Placeholder object.