Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

[ProTip] Reduce Scene Sizes in Unity 5

Discussion in 'Scripting' started by Sycobob, Mar 12, 2015.

  1. Sycobob

    Sycobob

    Joined:
    Feb 1, 2013
    Posts:
    78
    Hey guys,

    Note: This applies to upgrading projects from previous versions of Unity, not to new projects created in 5.0+.

    If you didn't notice, Unity 5 brought a subtle, but awesome change to scene serialization. Previously, every prefab instance in the scene was serialized as a complete copy of the object. That meant that every time you dragged in prefab, the scene file size increased by roughly the file size of the prefab. This was kind of silly because unless a field was overridden, there was no need to save a copy of it in the scene when it could be read from the prefab. This also meant the scene changed anytime you updated serialized fields on a prefab which was instantiated in the scene.

    Now, scenes only serialize a reference to the prefab and any fields that are overridden. If you're leveraging prefabs to a large degree, this results in quite a lot of data being stripped out of your scene and the file size dropped dramatically. For example, we have a huge scene that was previously 172 MB. It is now 41 MB. I'll take that! Overall, we went from 2.78 GB of scenes to just 0.72 GB.

    The only downside is that this doesn't happen automatically. For some reason, scenes aren't being re-serialized when you upgrade your project to Unity 5. So if you want to take advantage of this, you need to force that re-serialization. The most straightforward way is to open and save the scene. However, if you have a lot of scenes (like us) or are just fundamentally lazy (like me), you can automate this trivially.

    Code (csharp):
    1. using UnityEditor;
    2.  
    3. public static class UpgradeScenes
    4. {
    5.     private const string progressTitle = "Resaving Scenes";
    6.  
    7.     [MenuItem("Pixel Dash/Resave All Scenes")]
    8.     private static void ResaveAllScenes ()
    9.     {
    10.         EditorUtility.DisplayProgressBar(progressTitle, "Finding all scenes", 0);
    11.  
    12.         var scenes = AssetDatabase.FindAssets("t:SceneAsset");
    13.  
    14.         for ( int i = 0; i < scenes.Length; ++i )
    15.         {
    16.             float progress = (float) i / scenes.Length;
    17.             string scenePath = AssetDatabase.GUIDToAssetPath(scenes[i]);
    18.  
    19.             if ( EditorUtility.DisplayCancelableProgressBar(progressTitle, "Opening scene: " + scenePath, progress) ) { break; }
    20.             EditorApplication.OpenScene(scenePath);
    21.  
    22.             if ( EditorUtility.DisplayCancelableProgressBar(progressTitle, "Saving scene: " + scenePath, progress) ) { break; }
    23.             EditorApplication.SaveScene();
    24.         }
    25.  
    26.         EditorUtility.ClearProgressBar();
    27.     }
    28. }
    Reason #2395 why I love being able to script the Editor itself.

    Cheers,
    Adam

    PS You can also force your scenes to re-serialize by changing the serialization setting in Edit > Project Settings > Editor, but I don't recommend this if your project is large. It can take a while. But, if you're not already using it, I highly recommend using Force Text here because assets will be stored more efficiently in version control and it allows limited merging when conflicts occur. Warning: changing it to Force Text has a memory leak and will crash the Editor. Less likely with the 64-bit Editor, but still...
     
    Last edited: Mar 23, 2016
    Kiwasi likes this.
  2. Talsidor

    Talsidor

    Joined:
    Aug 7, 2012
    Posts:
    22
    Hey Sycobob,

    We're trying to do this on Unity 5.3 but it's not making a difference. I believe it may be because 5.3 introduced a change where scenes won't become "dirty" unless you actually change something. I modified your code to call EditorSceneManager.MarkSceneDirty and this did mean that the scenes got resaved (they became changes according to SVN), but they didn't change in size at all. I'm wondering if you (or anyone else) have tried this on Unity 5.3 and have any advice for getting it to work? Thanks!
     
  3. Sycobob

    Sycobob

    Joined:
    Feb 1, 2013
    Posts:
    78
    This was only really relevant during the transition to Unity 5. If you had scenes that were saved in a previous version (and therefore had all the extraneous data in them), saving them in 5 would strip out the excess information. However, once you save the scene with a version >= 5, the deed is done and re-saving isn't going to continually drop the scene size or something magical.

    Assuming you created your current scene with Unity 5 or later, or have ever saved it there's nothing for you to gain here.
     
  4. NgenGames

    NgenGames

    Joined:
    Feb 29, 2016
    Posts:
    4
    Can someone guide us how to reduce the level size in unity3d. In my project the total size of IPA is 725MB in which Levels size is 500MB.. Please help us.
     
  5. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    Do you have a Resources folder? If so, go through that carefully with a fine tooth comb as everything in that folder gets included into the build and it's easy to have unnecessary duplication of stuff.

    If you're using asset bundles, you don't need anything in your resources folder since the asset bundle will automatically link in all dependencies when it's built.
     
  6. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
  7. daxiongmao

    daxiongmao

    Joined:
    Feb 2, 2016
    Posts:
    395
    Does anyone know if this is still the case in 2017?
    Specifically tonight I was expecting to see things be reduced. My actual unity scene file in the project is drastically reduced when I use prefabs in my generated scene. But the actual binary size when doing a build is the same size or even bigger.

    Something I found from 2014 says that prefabs are serialized into the file. I definitely see the the .unity file reduced but not the binary (my case in the iOS build data folder levelxx file)

    Can anyone comment on this?
     
  8. wood333

    wood333

    Joined:
    May 9, 2015
    Posts:
    851
    Feature request. I use ProTip on some moving 3D objects. A fade out delay would help ensure the tip if visible long enough to read. I suppose I could shoot the moving object to slow it down, but that wouldn't be very nice to the moving critter.