public override void OnImportAsset(AssetImportContext ctx)
        {
            try
            {
                ctx.DependsOnCustomDependency("EntityBinaryFileFormatVersion");

                var sceneWithBuildConfiguration = SceneWithBuildConfigurationGUIDs.ReadFromFile(ctx.assetPath);

                // Ensure we have as many dependencies as possible registered early in case an exception is thrown
                var scenePath = AssetDatabase.GUIDToAssetPath(sceneWithBuildConfiguration.SceneGUID.ToString());
                ctx.DependsOnSourceAsset(scenePath);

                if (sceneWithBuildConfiguration.BuildConfiguration.IsValid)
                {
                    var buildConfigurationPath = AssetDatabase.GUIDToAssetPath(sceneWithBuildConfiguration.BuildConfiguration.ToString());
                    ctx.DependsOnSourceAsset(buildConfigurationPath);
                    var buildConfigurationDependencies = AssetDatabase.GetDependencies(buildConfigurationPath);
                    foreach (var dependency in buildConfigurationDependencies)
                    {
                        ctx.DependsOnSourceAsset(dependency);
                    }
                }

                var dependencies = AssetDatabase.GetDependencies(scenePath);
                foreach (var dependency in dependencies)
                {
                    if (dependency.ToLower().EndsWith(".prefab"))
                    {
                        ctx.DependsOnSourceAsset(dependency);
                    }
                }

                var config = BuildConfiguration.LoadAsset(sceneWithBuildConfiguration.BuildConfiguration);

                var scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive);

                try
                {
                    var settings = new GameObjectConversionSettings();

                    settings.SceneGUID          = sceneWithBuildConfiguration.SceneGUID;
                    settings.BuildConfiguration = config;
                    settings.AssetImportContext = ctx;

                    var sectionRefObjs = new List <ReferencedUnityObjects>();
                    var sectionData    = EditorEntityScenes.ConvertAndWriteEntityScene(scene, settings, sectionRefObjs);
                    WriteRefGuids(sectionRefObjs, sectionData, ctx);
                }
                finally
                {
                    EditorSceneManager.CloseScene(scene, true);
                }
            }
            // Currently it's not acceptable to let the asset database catch the exception since it will create a default asset without any dependencies
            // This means a reimport will not be triggered if the scene is subsequently modified
            catch (Exception e)
            {
                Debug.Log($"Exception thrown during SubScene import: {e}");
            }
        }
        public override void OnImportAsset(AssetImportContext ctx)
        {
            try
            {
                var sceneWithBuildSettings = ReadSceneWithBuildSettings(ctx.assetPath);

                // Ensure we have as many dependencies as possible registered early in case an exception is thrown
                var scenePath = AssetDatabase.GUIDToAssetPath(sceneWithBuildSettings.SceneGUID.ToString());
                ctx.DependsOnSourceAsset(scenePath);

                if (sceneWithBuildSettings.BuildSettings.IsValid)
                {
                    var buildSettingPath = AssetDatabase.GUIDToAssetPath(sceneWithBuildSettings.BuildSettings.ToString());
                    ctx.DependsOnSourceAsset(buildSettingPath);
                    var buildSettingDependencies = AssetDatabase.GetDependencies(buildSettingPath);
                    foreach (var dependency in buildSettingDependencies)
                    {
                        ctx.DependsOnSourceAsset(dependency);
                    }
                }

                var dependencies = AssetDatabase.GetDependencies(scenePath);
                foreach (var dependency in dependencies)
                {
                    if (dependency.ToLower().EndsWith(".prefab"))
                    {
                        ctx.DependsOnSourceAsset(dependency);
                    }
                }

                var buildSettings = BuildSettings.LoadBuildSettings(sceneWithBuildSettings.BuildSettings);

                var scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive);

                try
                {
                    var settings = new GameObjectConversionSettings();

                    settings.SceneGUID          = sceneWithBuildSettings.SceneGUID;
                    settings.BuildSettings      = buildSettings;
                    settings.AssetImportContext = ctx;

                    EditorEntityScenes.WriteEntityScene(scene, settings);
                }
                finally
                {
                    EditorSceneManager.CloseScene(scene, true);
                }
            }
            // Currently it's not acceptable to let the asset database catch the exception since it will create a default asset without any dependencies
            // This means a reimport will not be triggered if the scene is subsequently modified
            catch (Exception e)
            {
                Debug.Log($"Exception thrown during SubScene import: {e.Message}");
            }
        }
Beispiel #3
0
 static void RegisterDependencies(AssetImportContext importContext, ConversionDependencies dependencies)
 {
     using (var assets = dependencies.AssetDependentsByInstanceId.GetKeyArray(Allocator.Temp))
     {
         for (int i = 0; i < assets.Length; i++)
         {
             var asset = EditorUtility.InstanceIDToObject(assets[i]);
             importContext.DependsOnSourceAsset(AssetDatabase.GetAssetPath(asset));
         }
     }
 }
        static void EnsureFileIsWritableOrThrow(string path, AssetImportContext ctx)
        {
            if (ctx != null)
            {
                return;
            }

            // We're going to do file writing manually, so make sure to do version control dance if needed
            if (Provider.isActive && File.Exists(path) && !AssetDatabase.IsOpenForEdit(path, StatusQueryOptions.UseCachedIfPossible))
            {
                var task = Provider.Checkout(path, CheckoutMode.Asset);
                task.Wait();
                if (!task.success)
                {
                    throw new System.Exception($"Failed to checkout entity cache file {path}");
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Describe how to create an Prefab for the current SRP, have to be reimplemented for each SRP.
        /// </summary>
        /// <param name="ctx">Context used from the asset importer</param>
        /// <param name="iesFileName">Filename of the current IES file</param>
        /// <param name="useIESMaximumIntensity">True if uses the internal Intensity from the file</param>
        /// <param name="iesMaximumIntensityUnit">The string of the units described by the intensity</param>
        /// <param name="iesMaximumIntensity">Intensity</param>
        /// <param name="light">Light used for the prefab</param>
        /// <param name="ies">Texture used for the prefab</param>
        /// <returns></returns>
        static public void CreateRenderPipelinePrefabLight(UnityEditor.Experimental.AssetImporters.AssetImportContext ctx, string iesFileName, bool useIESMaximumIntensity, string iesMaximumIntensityUnit, float iesMaximumIntensity, Light light, Texture ies)
        {
            HDLightTypeAndShape hdLightTypeAndShape = (light.type == LightType.Point) ? HDLightTypeAndShape.Point : HDLightTypeAndShape.ConeSpot;

            HDAdditionalLightData hdLight = GameObjectExtension.AddHDLight(light.gameObject, hdLightTypeAndShape);

            if (useIESMaximumIntensity)
            {
                LightUnit lightUnit = (iesMaximumIntensityUnit == "Lumens") ? LightUnit.Lumen : LightUnit.Candela;
                hdLight.SetIntensity(iesMaximumIntensity, lightUnit);
                if (light.type == LightType.Point)
                {
                    hdLight.IESPoint = ies;
                }
                else
                {
                    hdLight.IESSpot = ies;
                }
            }

            // The light object will be automatically converted into a prefab.
            ctx.AddObjectToAsset(iesFileName + "-HDRP", light.gameObject);
        }
Beispiel #6
0
        static void RegisterDependencies(AssetImportContext importContext, ConversionDependencies dependencies)
        {
            using (var assets = dependencies.AssetDependentsByInstanceId.GetKeyArray(Allocator.Temp))
            {
                for (int i = 0; i < assets.Length; i++)
                {
                    var asset = EditorUtility.InstanceIDToObject(assets[i]);
                    if (asset == null)
                    {
                        var    dependents = FormatDependents(assets[i]);
                        string errorMsg   =
                            $"Invalid asset dependency on instance ID {assets[i]} - this instance ID does not correspond to an object.\n" +
                            "This dependency was registered by: " + dependents;
                        Debug.LogWarning(errorMsg);
                        continue;
                    }

                    var path = AssetDatabase.GetAssetPath(asset);
                    if (string.IsNullOrEmpty(path))
                    {
                        var    dependents = FormatDependents(assets[i]);
                        string errorMsg   =
                            $"Invalid asset dependency on object {asset.name}. This object does not have a valid asset path.\n" +
                            "This dependency was registered by: " + dependents;
                        Debug.LogWarning(errorMsg, asset);
                        continue;
                    }

                    var guid = new GUID(AssetDatabase.AssetPathToGUID(path));
                    if (GUIDHelper.IsBuiltinAsset(in guid))
                    {
                        // AssetImportContext does not support dependencies on inbuilt assets
                        continue;
                    }

                    if (guid.Empty())
                    {
                        // This should never happen
                        var    dependents = FormatDependents(assets[i]);
                        string errorMsg   =
                            $"Invalid asset dependency on object {asset.name} at path {path}. It doesn't have a valid GUID.\n" +
                            "This dependency was registered by: " + dependents;
                        Debug.LogWarning(errorMsg, asset);
                        continue;
                    }

                    importContext.DependsOnSourceAsset(path);
                }
            }

            string FormatDependents(int assetInstance)
            {
                var    iter = dependencies.AssetDependentsByInstanceId.GetValuesForKey(assetInstance);
                string deps = "";

                while (iter.MoveNext())
                {
                    if (deps.Length > 0)
                    {
                        deps += ", ";
                    }
                    var obj = EditorUtility.InstanceIDToObject(iter.Current);
                    deps += $"{(obj == null ? "NULL" : obj.name)}";
                }

                return(deps);
            }
        }
Beispiel #7
0
        internal static string GetSceneWritePath(EntityScenesPaths.PathType type, string subsectionName, AssetImportContext ctx)
        {
            var prefix = string.IsNullOrEmpty(subsectionName) ? "" : subsectionName + ".";
            var path   = ctx.GetResultPath(prefix + EntityScenesPaths.GetExtension(type));

            return(path);
        }
Beispiel #8
0
        public static SceneSectionData[] WriteEntityScene(EntityManager entityManager, Hash128 sceneGUID, string sceneName, AssetImportContext importContext, int framesToRetainBlobAssets = 0, List <ReferencedUnityObjects> sectionRefObjs = null)
        {
            if (importContext != null)
            {
                using (var allTypes = new NativeHashMap <ComponentType, int>(100, Allocator.Temp))
                    using (var archetypes = new NativeList <EntityArchetype>(Allocator.Temp))
                    {
                        entityManager.GetAllArchetypes(archetypes);
                        foreach (var archetype in archetypes)
                        {
                            using (var componentTypes = archetype.GetComponentTypes())
                                foreach (var componentType in componentTypes)
                                {
                                    if (allTypes.TryAdd(componentType, 0))
                                    {
                                        TypeDependencyCache.AddDependency(importContext, componentType);
                                    }
                                }
                        }
                    }

                TypeDependencyCache.AddAllSystemsDependency(importContext);
            }


            var sceneSections = new List <SceneSectionData>();

            var subSectionList = new List <SceneSection>();

            entityManager.GetAllUniqueSharedComponentData(subSectionList);
            //Order sections by section id
            subSectionList.Sort(Comparer <SceneSection> .Create((a, b) => a.Section.CompareTo(b.Section)));

            var extRefInfoEntities = new NativeArray <Entity>(subSectionList.Count, Allocator.Temp);

            NativeArray <Entity> entitiesInMainSection;

            var sectionQuery = entityManager.CreateEntityQuery(
                new EntityQueryDesc
            {
                All     = new[] { ComponentType.ReadWrite <SceneSection>() },
                Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled
            }
                );

            var sectionBoundsQuery = entityManager.CreateEntityQuery(
                new EntityQueryDesc
            {
                All     = new[] { ComponentType.ReadWrite <SceneBoundingVolume>(), ComponentType.ReadWrite <SceneSection>() },
                Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled
            }
                );

            {
                var section = new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                };
                sectionQuery.SetSharedComponentFilter(new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                });
                sectionBoundsQuery.SetSharedComponentFilter(new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                });
                entitiesInMainSection = sectionQuery.ToEntityArray(Allocator.TempJob);


                var bounds = GetBoundsAndRemove(entityManager, sectionBoundsQuery);

                // Each section will be serialized in its own world, entities that don't have a section are part of the main scene.
                // An entity that holds the array of external references to the main scene is required for each section.
                // We need to create them all before we start moving entities to section scenes,
                // otherwise they would reuse entities that have been moved and mess up the remapping tables.
                for (int sectionIndex = 1; sectionIndex < subSectionList.Count; ++sectionIndex)
                {
                    if (subSectionList[sectionIndex].Section == 0)
                    {
                        // Main section, the only one that doesn't need an external ref array
                        continue;
                    }

                    var extRefInfoEntity = entityManager.CreateEntity();
                    entityManager.AddSharedComponentData(extRefInfoEntity, subSectionList[sectionIndex]);
                    extRefInfoEntities[sectionIndex] = extRefInfoEntity;
                }

                // Public references array, only on the main section.
                var refInfoEntity = entityManager.CreateEntity();
                entityManager.AddBuffer <PublicEntityRef>(refInfoEntity);
                entityManager.AddSharedComponentData(refInfoEntity, section);
                var publicRefs = entityManager.GetBuffer <PublicEntityRef>(refInfoEntity);

//                entityManager.Debug.CheckInternalConsistency();

                //@TODO do we need to keep this index? doesn't carry any additional info
                for (int i = 0; i < entitiesInMainSection.Length; ++i)
                {
                    PublicEntityRef.Add(ref publicRefs,
                                        new PublicEntityRef {
                        entityIndex = i, targetEntity = entitiesInMainSection[i]
                    });
                }

                UnityEngine.Debug.Assert(publicRefs.Length == entitiesInMainSection.Length);

                // Save main section
                var sectionWorld   = new World("SectionWorld");
                var sectionManager = sectionWorld.EntityManager;

                var entityRemapping = entityManager.CreateEntityRemapArray(Allocator.TempJob);
                sectionManager.MoveEntitiesFrom(entityManager, sectionQuery, entityRemapping);

                AddRetainBlobAssetsEntity(sectionManager, framesToRetainBlobAssets);

                // The section component is only there to break the conversion world into different sections
                // We don't want to store that on the disk
                //@TODO: Component should be removed but currently leads to corrupt data file. Figure out why.
                //sectionManager.RemoveComponent(sectionManager.UniversalQuery, typeof(SceneSection));

                var sectionFileSize = WriteEntitySceneSection(sectionManager, "0", importContext, out var objectRefCount, out var objRefs);
                sectionRefObjs?.Add(objRefs);
                sceneSections.Add(new SceneSectionData
                {
                    FileSize             = sectionFileSize,
                    SceneGUID            = sceneGUID,
                    ObjectReferenceCount = objectRefCount,
                    SubSectionIndex      = 0,
                    BoundingVolume       = bounds
                });

                entityRemapping.Dispose();
                sectionWorld.Dispose();
            }

            {
                // Index 0 is the default value of the shared component, not an actual section
                for (int subSectionIndex = 0; subSectionIndex < subSectionList.Count; ++subSectionIndex)
                {
                    var subSection = subSectionList[subSectionIndex];
                    if (subSection.Section == 0)
                    {
                        continue;
                    }

                    sectionQuery.SetSharedComponentFilter(subSection);
                    sectionBoundsQuery.SetSharedComponentFilter(subSection);

                    var bounds = GetBoundsAndRemove(entityManager, sectionBoundsQuery);

                    var entitiesInSection = sectionQuery.ToEntityArray(Allocator.TempJob);

                    if (entitiesInSection.Length > 0)
                    {
                        // Fetch back the external reference entity we created earlier to not disturb the mapping
                        var refInfoEntity = extRefInfoEntities[subSectionIndex];
                        entityManager.AddBuffer <ExternalEntityRef>(refInfoEntity);
                        var externRefs = entityManager.GetBuffer <ExternalEntityRef>(refInfoEntity);

                        // Store the mapping to everything in the main section
                        //@TODO maybe we don't need all that? is this worth worrying about?
                        for (int i = 0; i < entitiesInMainSection.Length; ++i)
                        {
                            ExternalEntityRef.Add(ref externRefs, new ExternalEntityRef {
                                entityIndex = i
                            });
                        }

                        var entityRemapping = entityManager.CreateEntityRemapArray(Allocator.TempJob);

                        // Entities will be remapped to a contiguous range in the section world, but they will
                        // also come with an unpredictable amount of meta entities. We have the guarantee that
                        // the entities in the main section won't be moved over, so there's a free range of that
                        // size at the end of the remapping table. So we use that range for external references.
                        var externEntityIndexStart = entityRemapping.Length - entitiesInMainSection.Length;

                        entityManager.AddComponentData(refInfoEntity,
                                                       new ExternalEntityRefInfo
                        {
                            SceneGUID        = sceneGUID,
                            EntityIndexStart = externEntityIndexStart
                        });

                        var sectionWorld   = new World("SectionWorld");
                        var sectionManager = sectionWorld.EntityManager;

                        // Insert mapping for external references, conversion world entity to virtual index in section
                        for (int i = 0; i < entitiesInMainSection.Length; ++i)
                        {
                            EntityRemapUtility.AddEntityRemapping(ref entityRemapping, entitiesInMainSection[i],
                                                                  new Entity {
                                Index = i + externEntityIndexStart, Version = 1
                            });
                        }

                        sectionManager.MoveEntitiesFrom(entityManager, sectionQuery, entityRemapping);

                        AddRetainBlobAssetsEntity(sectionManager, framesToRetainBlobAssets);
                        // Now that all the required entities have been moved over, we can get rid of the gap between
                        // real entities and external references. This allows remapping during load to deal with a
                        // smaller remap table, containing only useful entries.

                        int highestEntityIndexInUse = 0;
                        for (int i = 0; i < externEntityIndexStart; ++i)
                        {
                            var targetIndex = entityRemapping[i].Target.Index;
                            if (targetIndex < externEntityIndexStart && targetIndex > highestEntityIndexInUse)
                            {
                                highestEntityIndexInUse = targetIndex;
                            }
                        }

                        var oldExternEntityIndexStart = externEntityIndexStart;
                        externEntityIndexStart = highestEntityIndexInUse + 1;

                        sectionManager.SetComponentData
                        (
                            EntityRemapUtility.RemapEntity(ref entityRemapping, refInfoEntity),
                            new ExternalEntityRefInfo
                        {
                            SceneGUID        = sceneGUID,
                            EntityIndexStart = externEntityIndexStart
                        }
                        );

                        // When writing the scene, references to missing entities are set to Entity.Null by default
                        // (but only if they have been used, otherwise they remain untouched)
                        // We obviously don't want that to happen to our external references, so we add explicit mapping
                        // And at the same time, we put them back at the end of the effective range of real entities.
                        for (int i = 0; i < entitiesInMainSection.Length; ++i)
                        {
                            var src = new Entity {
                                Index = i + oldExternEntityIndexStart, Version = 1
                            };
                            var dst = new Entity {
                                Index = i + externEntityIndexStart, Version = 1
                            };
                            EntityRemapUtility.AddEntityRemapping(ref entityRemapping, src, dst);
                        }

                        // The section component is only there to break the conversion world into different sections
                        // We don't want to store that on the disk
                        //@TODO: Component should be removed but currently leads to corrupt data file. Figure out why.
                        //sectionManager.RemoveComponent(sectionManager.UniversalQuery, typeof(SceneSection));
                        var fileSize = WriteEntitySceneSection(sectionManager, subSection.Section.ToString(), importContext, out var objectRefCount, out var objRefs, entityRemapping);
                        sectionRefObjs?.Add(objRefs);
                        sceneSections.Add(new SceneSectionData
                        {
                            FileSize             = fileSize,
                            SceneGUID            = sceneGUID,
                            ObjectReferenceCount = objectRefCount,
                            SubSectionIndex      = subSection.Section,
                            BoundingVolume       = bounds
                        });

                        entityRemapping.Dispose();
                        sectionWorld.Dispose();
                    }

                    entitiesInSection.Dispose();
                }
            }

            {
                var noSectionQuery = entityManager.CreateEntityQuery(
                    new EntityQueryDesc
                {
                    None    = new[] { ComponentType.ReadWrite <SceneSection>() },
                    Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled
                }
                    );
                var sectionEntityQuery = entityManager.CreateEntityQuery(
                    new EntityQueryDesc
                {
                    None    = new[] { ComponentType.ReadWrite <SectionMetadataSetup>() },
                    Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled
                }
                    );
                var notSerializedCount = noSectionQuery.CalculateEntityCount() - sectionEntityQuery.CalculateEntityCount();
                if (notSerializedCount != 0)
                {
                    Debug.LogWarning($"{notSerializedCount} entities in the scene '{sceneName}' had no SceneSection and as a result were not serialized at all.");
                }
            }

            // Save the new header
            var sceneSectionsArray = sceneSections.ToArray();

            WriteSceneHeader(sceneGUID, sceneSectionsArray, sceneName, importContext, entityManager);

            sectionQuery.Dispose();
            sectionBoundsQuery.Dispose();
            entitiesInMainSection.Dispose();

            return(sceneSectionsArray);
        }
        static void WriteHeader(Entities.Hash128 sceneGUID, SceneSectionData[] sections, string sceneName, AssetImportContext ctx)
        {
            k_ProfileEntitiesSceneSaveHeader.Begin();

            string headerPath = GetSceneWritePath(sceneGUID, EntityScenesPaths.PathType.EntitiesHeader, "", ctx);

            EnsureFileIsWritableOrThrow(headerPath, ctx);

            var builder = new BlobBuilder(Allocator.TempJob);

            ref var metaData = ref builder.ConstructRoot <SceneMetaData>();
Beispiel #10
0
 public static void AddAllSystemsDependency(AssetImportContext ctx)
 {
     ctx.DependsOnCustomDependency(SystemsVersion);
 }
Beispiel #11
0
        public static void AddDependency(AssetImportContext ctx, ComponentType type)
        {
            var typeString = TypeString(type.GetManagedType());

            ctx.DependsOnCustomDependency(typeString);
        }
Beispiel #12
0
        static int WriteEntityScene(EntityManager scene, Hash128 sceneGUID, string subsection, AssetImportContext ctx, out int objectReferenceCount, NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapInfos = default)
        {
            k_ProfileEntitiesSceneSave.Begin();

            var entitiesBinaryPath = GetSceneWritePath(sceneGUID, EntityScenesPaths.PathType.EntitiesBinary, subsection, ctx);
            var objRefsPath        = GetSceneWritePath(sceneGUID, EntityScenesPaths.PathType.EntitiesUnityObjectReferences, subsection, ctx);
            ReferencedUnityObjects objRefs;

            objectReferenceCount = 0;

            EnsureFileIsWritableOrThrow(entitiesBinaryPath, ctx);

            // Write binary entity file
            int entitySceneFileSize = 0;

            using (var writer = new StreamBinaryWriter(entitiesBinaryPath))
            {
                if (entityRemapInfos.IsCreated)
                {
                    SerializeUtilityHybrid.Serialize(scene, writer, out objRefs, entityRemapInfos);
                }
                else
                {
                    SerializeUtilityHybrid.Serialize(scene, writer, out objRefs);
                }
                entitySceneFileSize = (int)writer.Length;

                // Write object references
                k_ProfileEntitiesSceneWriteObjRefs.Begin();
                if (objRefs != null)
                {
                    var serializedObjectArray = new List <UnityObject>();
                    serializedObjectArray.Add(objRefs);

                    for (int i = 0; i != objRefs.Array.Length; i++)
                    {
                        var obj = objRefs.Array[i];
                        if (obj != null && !EditorUtility.IsPersistent(obj))
                        {
                            if ((obj.hideFlags & HideFlags.DontSaveInBuild) != 0)
                            {
                                serializedObjectArray.Add(obj);
                            }
                            else
                            {
                                objRefs.Array[i] = null;
                            }
                        }
                    }

                    UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget(serializedObjectArray.ToArray(), objRefsPath, false);
                    objectReferenceCount = objRefs.Array.Length;
                }
                k_ProfileEntitiesSceneWriteObjRefs.End();
            }
            k_ProfileEntitiesSceneSave.End();
            return(entitySceneFileSize);
        }
        static void WriteRefGuids(List <ReferencedUnityObjects> referencedUnityObjects, SceneSectionData[] sectionData, AssetImportContext ctx)
        {
            for (var index = 0; index < referencedUnityObjects.Count; index++)
            {
                var sectionIndex = sectionData[index].SubSectionIndex;

                var objRefs = referencedUnityObjects[index];
                if (objRefs == null)
                {
                    continue;
                }

                var refGuidsPath           = ctx.GetResultPath($"{sectionIndex}.{EntityScenesPaths.GetExtension(EntityScenesPaths.PathType.EntitiesUnityObjectRefGuids)}");
                var runtimeGlobalObjectIds = ReferencedUnityObjectsToRuntimeGlobalObjectIds(objRefs);

                using (var refGuidWriter = new StreamBinaryWriter(refGuidsPath))
                {
                    refGuidWriter.Write(runtimeGlobalObjectIds.Length);
                    refGuidWriter.WriteArray(runtimeGlobalObjectIds.AsArray());
                }

                runtimeGlobalObjectIds.Dispose();
            }
        }