Search Unity

(Case 956356) Creating scene outputs different .unity file always

Discussion in '2017.2 Beta' started by Peter77, Oct 4, 2017.

  1. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,033
    (Programmatically) creating a scene with the same content, produces an .unity file with different content always. It seems the GameObject's inside the scene file are stored randomly.

    The provided example creates a new scene and places a few prefabs at hard-coded positions. It's always the same. However, comparing the produced .unity file with a diff tool (such as TortoiseMerge), shows the scene file is different always.

    This causes version control issues. Most likely different asset bundles as well, even though the actual scene is identical.



    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5.  
    6. class CreateSceneTest
    7. {
    8.     [MenuItem("Test/Create Scene A")]
    9.     static void DoMenuItem()
    10.     {
    11.         // create a new scene
    12.         var scene = UnityEditor.SceneManagement.EditorSceneManager.NewScene(UnityEditor.SceneManagement.NewSceneSetup.EmptyScene);
    13.  
    14.         // create a floor place
    15.         var floor = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Art/Floor.prefab"));
    16.         floor.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
    17.         floor.transform.SetAsLastSibling();
    18.  
    19.         // create a few prefabs
    20.         foreach (var pos in new Vector3[] {
    21.             new Vector3(5, 0, 0),
    22.             new Vector3(0, 5, 0),
    23.             new Vector3(0, 0, 5),})
    24.         {
    25.             var cube = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Art/Cube.prefab"));
    26.             cube.transform.SetPositionAndRotation(pos, Quaternion.identity);
    27.             cube.transform.SetAsLastSibling();
    28.         }
    29.  
    30.         // save scene
    31.         UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(scene);
    32.         UnityEditor.SceneManagement.EditorSceneManager.SaveScene(scene, "Assets/Scenes/Scene A.unity");
    33.     }
    34. }
    35.  

    Reproduce
    • Open user attached project
    • Press Mainmenu/Test/Create Scene A
    • Duplicate generated "Scenes/Scene A.unity" and rename it to "Backup"
    • Press Mainmenu/Test/Create Scene A
    • Compare "Scenes/Scene A.unity" and rename it to "Scenes/Backup" with a diff tool
    Observe the file content is different.


    Expected
    The produced file should be the same. If the input is identical, the output should be identical as well.
     
  2. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,033
  3. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    623
    This is not a bug.
    Sorting of objects in the scene file is based on an internal ID given to the objects the first time they are saved.

    Even though you are creating identical objects everytime you run your script you are actually creating new objects which does not have an ID allocated until you save the file. When you save the file all GameObjects and Prefabs are given random IDs, components are given ID based on either the GameObject or the Prefab they belong to. This is to ensure objects are grouped nicely.

    The order of objects in the scene file is not based on the order in the hierarchy but only on the ids, this ensure that changes to order in the hierarchy does not produce massive changes to the scene which can be a problem if the scenes are in version control.
     
  4. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,033
    Which is exactly the problem we have.

    We use an external application (not Unity) to create levels. It's a level editor that is optimized for the kind of content we need to produce. We save the level created by that external editor to the Unity project and have custom code that converts this file to an Unity scene.

    However, every time we convert the same level (input), the Unity scene file (output) is completely different.

    How do I get "deterministic scene files"? If there is a solution to this at all.
     
    Last edited: Oct 5, 2017
  5. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    623
    Only way to get deterministic scenes is to reuse existing objects.

    Load the existing scene, load your generated data, match objects and patch if required, create new objects if required and delete objects that does not have a matching object in your data.
     
    Peter77 likes this.
  6. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,033
    I see, thanks for your help!
     
unityunity