Example #1
0
        public static string GetLibraryFullPath(string guid)
        {
            if (String.IsNullOrEmpty(guid))
            {
                return(null);
            }

            string path = AssetDatabase.GUIDToAssetPath(guid);

            if (Path.GetExtension(path).Equals(".asset"))
            {
                return(path);
            }

#if UNITY_2019_2_OR_NEWER
            if (EditorSettings.assetPipelineMode == AssetPipelineMode.Version1)
            {
                return(GetAssetDatabaseVersion1LibraryDataPath(guid));
            }
            else
            {
#if UNITY_2020_2_OR_NEWER
                Hash128 artifactHash = AssetDatabaseExperimental.LookupArtifact(new ArtifactKey(new GUID(guid))).value;
#else
                Hash128 artifactHash = AssetDatabaseExperimental.GetArtifactHash(guid);
#endif

                if (!artifactHash.isValid)
                {
                    return(null);
                }

#if UNITY_2020_2_OR_NEWER
                ArtifactID artifactID = new ArtifactID();
                artifactID.value = artifactHash;
                AssetDatabaseExperimental.GetArtifactPaths(artifactID, out string[] paths);
#else
                AssetDatabaseExperimental.GetArtifactPaths(artifactHash, out string[] paths);
#endif

                foreach (string artifactPath in paths)
                {
                    if (artifactPath.EndsWith(".info"))
                    {
                        continue;
                    }

                    return(Path.GetFullPath(artifactPath));
                }
            }
#else // For older unity versions that dont have asset database V2 yet
            return(return GetAssetDatabaseVersion1LibraryDataPath(guid));
#endif

            return(null);
        }
Example #2
0
        // This function is responsible for providing all the subscenes to the build.
        //
        // The way these files get generated is that we have a SceneWithBuildConfiguration file, (which is a bit of a hack to work around the inability for scriptable importers to take arguments, so
        // instead we create a different file that points to the scene we want to import, and points to the buildconfiguration we want to import it for).   The SubsceneImporter will import this file,
        // and it will make 3 (relevant) kind of files:
        // - headerfile
        // - entitybinaryformat file (the actual entities payloads)
        // - a SerializedFile that has an array of UnityEngine.Object PPtrs that are used by this entity file.
        //
        // The first two we deal with very simply: they just need to be copied into the build, and we're done.
        // the third one, we will feed as input to the Scriptable build pipeline (which is actually about creating assetbundles), and create an assetbundle that
        // has all those objects in it that the 3rd file referred to.  We do this with a batch api, first we loop through all subscenes, and register with this batch
        // api which assetbundles we'd like to see produced, and then at the end, we say "okay make them please".  this assetbundle creation api has a caching system
        // that is separate from the assetpipeline caching system, so if all goes well, the call to produce these assetbundles will return very fast and did nothing.
        //
        // The reason for the strange looking api, where a two callbacks get passed in is to make integration of the new incremental buildpipeline easier, as this code
        // needs to be compatible both with the current buildpipeline in the dots-repo, as well as with the incremental buildpipeline.  When that is merged, we can simplify this.

        public static void PrepareAdditionalFiles(string buildConfigurationGuid, Func <Type, IBuildComponent> getRequiredComponent, Action <string, string> RegisterFileCopy, string outputStreamingAssetsDirectory, string buildWorkingDirectory)
        {
            T GetRequiredComponent <T>() => (T)getRequiredComponent(typeof(T));

            var profile = GetRequiredComponent <ClassicBuildProfile>();

            if (profile.Target == BuildTarget.NoTarget)
            {
                throw new InvalidOperationException($"Invalid build target '{profile.Target.ToString()}'.");
            }

            if (profile.Target != EditorUserBuildSettings.activeBuildTarget)
            {
                throw new InvalidOperationException($"ActiveBuildTarget must be switched before the {nameof(SubSceneBuildCode)} runs.");
            }

            var content       = new BundleBuildContent(new AssetBundleBuild[0]);
            var sceneList     = GetRequiredComponent <SceneList>();
            var bundleNames   = new List <string>();
            var subSceneGuids = sceneList.GetScenePathsForBuild().SelectMany(scenePath => SceneMetaDataImporter.GetSubSceneGuids(AssetDatabase.AssetPathToGUID(scenePath))).Distinct().ToList();

            foreach (var subSceneGuid in subSceneGuids)
            {
                var hash128Guid = SceneWithBuildConfigurationGUIDs.EnsureExistsFor(subSceneGuid, new Hash128(buildConfigurationGuid));

                var hash = AssetDatabaseExperimental.GetArtifactHash(hash128Guid.ToString(), typeof(SubSceneImporter));
                AssetDatabaseExperimental.GetArtifactPaths(hash, out var artifactPaths);

                foreach (var artifactPath in artifactPaths)
                {
                    var ext = Path.GetExtension(artifactPath).Replace(".", "");
                    if (ext == EntityScenesPaths.GetExtension(EntityScenesPaths.PathType.EntitiesHeader))
                    {
                        var destinationFile = outputStreamingAssetsDirectory + "/" + EntityScenesPaths.RelativePathInStreamingAssetsFolderFor(subSceneGuid, EntityScenesPaths.PathType.EntitiesHeader, -1);
                        RegisterFileCopy(artifactPath, destinationFile);
                    }

                    if (ext == EntityScenesPaths.GetExtension(EntityScenesPaths.PathType.EntitiesBinary))
                    {
                        var destinationFile = outputStreamingAssetsDirectory + "/" + EntityScenesPaths.RelativePathInStreamingAssetsFolderFor(subSceneGuid, EntityScenesPaths.PathType.EntitiesBinary, EntityScenesPaths.GetSectionIndexFromPath(artifactPath));
                        RegisterFileCopy(artifactPath, destinationFile);
                    }

                    if (ext == EntityScenesPaths.GetExtension(EntityScenesPaths.PathType.EntitiesUnityObjectReferences))
                    {
                        content.CustomAssets.Add(new CustomContent
                        {
                            Asset     = hash128Guid,
                            Processor = (guid, processor) =>
                            {
                                var sectionIndex = EntityScenesPaths.GetSectionIndexFromPath(artifactPath);
                                processor.GetObjectIdentifiersAndTypesForSerializedFile(artifactPath, out ObjectIdentifier[] objectIds, out Type[] types);
 public static string GetBundlePath(string guid, BuildTarget target)
 {
     try
     {
         AssetDatabaseExperimental.GetArtifactPaths(GetHash(guid, target), out string[] paths);
         return(paths.First(o => o.EndsWith(k_BundleExtension)));
     }
     catch (Exception e)
     {
         UnityEngine.Debug.LogError($"Exception thrown getting bundle path for '{guid}'.\n{e.Message}");
     }
     return("");
 }
    public unsafe static Hash128[] GetSubSceneGuids(string guid)
    {
        var hash = AssetDatabaseExperimental.GetArtifactHash(guid, typeof(SceneMetaDataImporter), AssetDatabaseExperimental.ImportSyncMode.Block);

        AssetDatabaseExperimental.GetArtifactPaths(hash, out string[] paths);

        var metaPath = paths.First(o => o.EndsWith("scenemeta"));

        BlobAssetReference <SceneMetaData> sceneMetaDataRef;

        if (!BlobAssetReference <SceneMetaData> .TryRead(metaPath, SceneMetaDataImporter.CurrentFileFormatVersion, out sceneMetaDataRef))
        {
            return(new Hash128[0]);
        }

        Hash128[] guids = sceneMetaDataRef.Value.SubScenes.ToArray();
        sceneMetaDataRef.Dispose();
        return(guids);
    }
        // Recursive until new SBP APIs land in 2020.1
        public unsafe static Hash128[] GetDependencies(string guid, BuildTarget target)
        {
            try
            {
                AssetDatabaseExperimental.GetArtifactPaths(GetHash(guid, target), out string[] paths);
                var metaPath = paths.First(o => o.EndsWith(k_DependenciesExtension));

                BlobAssetReference <BuildMetaData> buildMetaData;
                if (!BlobAssetReference <BuildMetaData> .TryRead(metaPath, k_CurrentFileFormatVersion, out buildMetaData))
                {
                    return(new Hash128[0]);
                }

                Hash128[] guids = buildMetaData.Value.Dependencies.ToArray();
                buildMetaData.Dispose();
                return(guids);
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError($"Exception thrown getting dependencies for '{guid}'.\n{e.Message}");
            }
            return(new Hash128[0]);
        }