【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

Asset Pipeline Version 2(Asset Database v2)

Unity 中存在四种管线(可能更多  别的我不知道):渲染管线,Build管线,Asset pipeline。  目前前两个都是可编程的。 

  • SRP :Universal Render Pipeline, High Definition Render Pipeline ( HDRP) ,       
  • SBP :Scriptable Build Pipeline
  • Script Compilation Pipeline 脚本编译管道  
  • Asset Pipeline : 也是Import Pipeline, Unity也有提供 导入前处理,后处理的API让开发者控制。

 Unity可能会为您想在游戏中使用的不同资产类型提供最全面的支持。Unity具有对模型文件,纹理文件,音频文件,视频文件和文本文件的多种文件格式的本机(内置)支持,

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

      上图中说的不对, 比如模型资源Maya 要导入Unity 需要:

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

        更具体的所有资源类型的导入和设置可以看:   文章内容较老~

 https://www.3dgep.com/introduction-to-unity-3-5-part-2/    

 

 

 

确实有人为这个东西, 但是现在文档确实很少!!!!!

https://forum.unity.com/threads/asset-pipeline-version-2.679366/#post-4548685

          新资产管道的第一部分于2019.2。使用与新的Asset管道一样大的功能通常需要多个版本,然后才能为所有人启用该功能。就是这种情况,我们在2019.2中完成了大部分基础工作,因此我们可以继续开发和测试功能的下一阶段,并使用进入2019.3的较小变更集。

 

2019.3博客文章指出:“一项新的实验功能是,您可以在Asset Pipeline中存储多个修订,这将大大改善平台在先前导入的资产版本之间的切换和交换switching and swapping。” –是我必须以某种方式启用的功能,还是“正常工作”?切换平台似乎并不比以前更快。

 

         不建议您启用新功能。管道,因为它几乎可以肯定对您的项目不起作用。我们确实保留了启用/禁用它的选项,因为我们一直在使用该标志自己测试新管道,并且将其标记为实验性指示其当前状态。

 

         如果一切按计划进行,我们将在2019.3上启用该标记,并使新管道成为将资产导入Unity的默认方式。今年9月,在哥本哈根Unite的新管道上将有更多信息。

https://forum.unity.com/threads/what-is-asset-database-v2.680170/

 

 

视频:  https://www.youtube.com/watch?v=S2P9n5U9xVw

AssetDatabase.Refresh() refresher - Unite Copenhagen

           AssetDatabase已被重写。 您越了解此API的工作原理,您的代码就越强大。 这些信息可以指导您制定自己的资产管理策略的决策。 例如,当您在平台之间跳转时,不需要重新导入资产。 在本课程中,您将对导入修改的资产和跟踪依赖关系有更深入的了解,以显着改善工作流程和迭代时间。

 

https://docs.unity3d.com/2020.1/Documentation/Manual/AssetDatabase.html  

 

视频内容:

  • 介绍新的 AssetDatabase
  • Refresh() 将会发生什么?
  • 平台的快速切换
  • ADB的提示和机巧

 

重写了 AssetDatabase ,   但是API和 V1版本一致。

有一些指导原则 Guiding Principles ,   针对  Determinism  和  Dependency tracking 。 确定性和依赖跟踪

 不会过多的讨论 Cache Server , 支持动态依赖关系

 

        术语:导入结果在 Library 文件夹下

       两个字母的文件夹是啥? 是资源名称的前两个字母。

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

 

任意的数据流的结果 是128位的哈希值。 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

         有静态和动态的依赖关系。 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

            什么是确定性, 就是相同的输入,肯定有相同的输出。 

下面的代码中有不确定的函数和确定的函数处理。             第一个函数在第二次执行的时候会失败,因为Move的目标路径已经有资源了。 所以确保目标路径不存在资源。 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

-- 确保在导入资产时,由于所有依赖项都相同,因此导入结果相同

-- 跨机器相同

-- 对于远程缓存数据非常重要

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

关于 AssetDatabase 

AD 分为两个数据库 。

  • Source Asset Database 
  • Artifact Database

Memory mapped Database   内存映射数据库

交易性的,因此更难腐败

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

 

          有四种方式触发刷新~

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

自动刷新,    每当进入和退出Unity的时候 ,会从操作系统那得到一个窗口焦点事件, 那是一个C++ Native层。 通过C# 调用它, 这是唯一被强迫的方法,  同步脚本编译的含义,知道所有脚本被编译然后继续导入的过程

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

     菜单就是  Ctrl + R 刷新。

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

1、Scan 扫描:

            遍历 Assets 文件夹。   检测变化的文件, 如果改变了要对它重新哈希,并存储到数据库中。 

             还要枚举 packages 文件夹, 但他们有一个区别, 只对pachages做一次,因为认为是不可变的(只读)。

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

这里就有一个问题,如果项目很大,有很复杂的文件结构,数以万计的文件数量,这个枚举是需要很长时间的!

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

       本质上是操作系统告诉我们改变了什么, 而不是我们主动去询问了。

 

2、分类 Catagorize Assets :

也许资源没有变化, 但是它所依赖的资源改变了。

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

    颜色空间是线性Linear Space 还是  Gamma Space 

     图形API 是   DX, Metal, Opengl, Valkan 

      脚本运行时脚本  是 .Net 4x  还是 .Net Standard 2.0,  .Net 3.5,         因为切换要用新的API重新编译。 

      贴图的压缩设置: 【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

3、 Compile Scripts

          还有一个脚本编译管道   Script Compilation Pipeline

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

4、 Import

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

5、Post Process All Assets 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

 

Fast Platform  Switch 

      下面的情景,      浪费时间

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

           如果没有改变就不会在重新进行哈希,   现在可以节省很多时间,  如果使用Cache Server 会更快。 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

Tips & Tricks of the AssetDatabase 

        之前的情况:

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

        新版本:    将会生成一个新的文件!!      还是就是为了快速平台切换?

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

        慢的原因是触发的各种回调!

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

        这样可以加快,  之前使用过,但是遇到比较烦的是如果中间遇到报错,但是没有执行到Stop ,Unity就卡死了,       可能是没有使用try catch 的处理方式吧。 (视频中也提到这个问题!)

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

 

 

QA:

         比之前快了  16%

 

 

 

 

 

 

 

 

 

 

 

可编写脚本的构建管道性能:  https://forum.unity.com/threads/scriptable-build-pipeline-performance.712376/

【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节

Scriptable Build Pipeline - 2018.3 Getting Started Guide:   :https://docs.google.com/document/d/1uuiEDV7WqpHEylzE4GQwOztCttrwPu6ak0kfELz6ilc/edit#heading=h.8n3jpqcpbyr0

Addressable Asset System for Unity:  https://docs.google.com/document/d/1hPLNLdrF0qAvjEJTpKf-cuO_d4FCV0H2cqBeP1Zo6mA/edit

Note to readers: this content is for the Scriptable Build Pipeline package and will reside in the package documentation at
https://docs.unity3d.com/Manual/PackagesList.html

Documentation source will reside at
https://gitlab.internal.unity3d.com/build-pipeline/AddressablesDemo/tree/master/AddressablesDemo/Packages/com.unity.scriptablebuildpipeline/Documentation

Table of Contents (tableofcontents.md)

Unity Scriptable Build Pipeline (index.md)

  • Getting started with Scriptable Build Pipeline (gettingstarted.md)
  • Terminology (terminology.md)
  • Usage Examples (usageexamples.md)
  • Upgrade Guide (upgradeguide.md)

Unity Scriptable Build Pipeline

The Scriptable Build Pipeline (SBP) package allows you to control how Unity builds content. The package moves the previously C++-only build pipeline code to a public C# package with a pre-defined build flow for building AssetBundles. The pre-defined AssetBundle build flow reduces build time, improves incremental build processing, and provides greater flexibility than before.

 

If you are moving from using BuildPipeline methods to the SBP, see the Usage Examples and Upgrade Guide.

 

Getting started with Scriptable Build Pipeline

Installing the Scriptable Build Pipeline (SBP) package

Requires Unity 2018.3 or later.

To install this package, follow the instructions in the Package Manager documentation.

To build AssetBundles, use the ContentPipeline.BuildAssetBundles() method. In its simplest form, you supply the following parameters:

 

  • Build Parameters - An object that implements the IBuildParameters interface. The object specifies the BuildTarget, the BuildTargetGroup, the output path, and additional optional properties.
  • The content to build - An object that implements the IBundleBuildContent interface. The object specifies the content to build (the assets) and its layout (what assets in which bundles.)
  • A results object - An object that implements the IBundleBuildResults interface. The object receives the details of the built AssetBundles.

 

Note: The UnityEditor.Build.Pipeline namespace contains default implementations for all of the SBP required interfaces.  Implementation names mirror the interfaces, with the leading ‘I’ removed. For example, the IBuildParameters interface is implemented as BuildParameters.

 

To quickly switch to building AssetBundles with SBP, use the CompatibilityBuildPipeline.BuildAssetBundles() method as a drop in replacement for existing code. This method has the nearly identical parameters as the BuildPipeline.BuildAssetBundles() method. For additional information, see the Usage Examples and Upgrade Guide.

 

Terminology

Asset - A source file on disk, typically located in the Project’s Assets folder. This file is imported to a game-ready representation of your Asset internally which can contain multiple Objects (SubAssets.)

 

Object (SubAsset) - A single Unity serializable unit. Also known as a SubAsset. An imported Asset is made up of one or more Objects. 

 

Includes - The unique set of Objects from which an Asset is constructed.

 

References - The unique set of Objects that are needed (referenced) by the Includes of an Asset, but not included in the Asset.

 

Usage Examples

Basic Example

This example assumes that your are already familiar with the basic usage of the two BuildPipeline.BuildAssetBundles methods and want to switch to using Scriptable Build Pipeline with as little effort  as possible. 

 

The following code example shows how AssetBundles are currently built:

 

using System.IO;

using UnityEditor;

 

public static class BuildAssetBundlesExample

{

    public static bool BuildAssetBundles(string outputPath, bool forceRebuild, bool useChunkBasedCompression, BuildTarget buildTarget)

    {

        var options = BuildAssetBundleOptions.None;

        if (useChunkBasedCompression)

            options |= BuildAssetBundleOptions.ChunkBasedCompression;

 

        if (forceRebuild)

            options |= BuildAssetBundleOptions.ForceRebuildAssetBundle;

 

        Directory.CreateDirectory(outputPath);

        var manifest = BuildPipeline.BuildAssetBundles(outputPath, options, buildTarget);

        return manifest != null;

    }

}

 

To update the previous code example to use SBP instead, replace the call to BuildPipeline.BuildAssetBundles with CompatibilityBuildPipeline.BuildAssetBundles as shown below:

 

using System.IO;

using UnityEditor;

using UnityEditor.Build.Pipeline;

 

public static class BuildAssetBundlesExample

{

    public static bool BuildAssetBundles(string outputPath, bool forceRebuild, bool useChunkBasedCompression, BuildTarget buildTarget)

    {

        var options = BuildAssetBundleOptions.None;

        if (useChunkBasedCompression)

            options |= BuildAssetBundleOptions.ChunkBasedCompression;

 

        if (forceRebuild)

            options |= BuildAssetBundleOptions.ForceRebuildAssetBundle;

 

        Directory.CreateDirectory(outputPath);

        var manifest = CompatibilityBuildPipeline.BuildAssetBundles(outputPath, options, buildTarget);

        return manifest != null;

    }

}

 

Notes: Some changes in the SBP building and loading process do not match the BuildPipeline behavior. For more information on these changes, see the Upgrade Guide.

 

Cache Server Integration Example

This following example shows how to share build artifacts between team members or multiple machines to achieve faster build times.

 

Requirements:

  1. A separate Cache Server instance dedicated to build artifacts. It cannot be shared as an Asset Cache Server as data collisions will occur.
  2. The build code must use the ContentPipeline.BuildAssetBundles method. 
  3. BundleBuildParameters.UseCache is set to true.
  4. BundleBuildParameters.CacheServerHost and BundleBuildParameters.CacheServerPort are set to the cache server instance host or IP address and port respectively.

 

Example code:

 

using UnityEditor;

using UnityEditor.Build.Content;

using UnityEditor.Build.Pipeline;

using UnityEditor.Build.Pipeline.Interfaces;

 

public static class BuildAssetBundlesExample

{

    public static bool BuildAssetBundles(string outputPath, bool useChunkBasedCompression, BuildTarget buildTarget, BuildTargetGroup buildGroup)

    {

        var buildContent = new BundleBuildContent(ContentBuildInterface.GenerateAssetBundleBuilds());

        var buildParams = new BundleBuildParameters(buildTarget, buildGroup, outputPath);

        buildParams.UseCache = true;

        buildParams.CacheServerHost = "buildcache.unitygames.com";

        buildParams.CacheServerPort = 8126;

 

        if (useChunkBasedCompression)

            buildParams.BundleCompression = BuildCompression.DefaultLZ4;

 

        IBundleBuildResults results;

        ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParams, buildContent, out results);

        return exitCode == ReturnCode.Success;

    }

}

 

Per-Bundle Compression Example

The following example shows how to build your AssetBundles using different compression levels for each AssetBundle.This is useful if you are planning on shipping part of your bundles as Lz4 or Uncompressed with Player and want to download the remainder as Lzma later. 

 

The simplest implementation is to create a custom build parameters class that inherits from BundleBuildParameters and override the GetCompressionForIdentifier method. Then construct and pass this into the ContentPipeline.BuildAssetBundles method.

 

using UnityEditor;

using UnityEditor.Build.Content;

using UnityEditor.Build.Pipeline;

using UnityEditor.Build.Pipeline.Interfaces;

 

public static class BuildAssetBundlesExample

{

    class CustomBuildParameters : BundleBuildParameters

    {

        public Dictionary<string, BuildCompression> PerBundleCompression { get; set; }

 

        public CustomBuildParameters(BuildTarget target, BuildTargetGroup group, string outputFolder) : base(target, group, outputFolder)

        {

            PerBundleCompression = new Dictionary<string, BuildCompression>();

        }

 

        public override BuildCompression GetCompressionForIdentifier(string identifier)

        {

            BuildCompression value;

            if (PerBundleCompression.TryGetValue(identifier, out value))

                return value;

            return BundleCompression;

        }

    }

 

    public static bool BuildAssetBundles(string outputPath, bool useChunkBasedCompression, BuildTarget buildTarget, BuildTargetGroup buildGroup)

    {

        var buildContent = new BundleBuildContent(ContentBuildInterface.GenerateAssetBundleBuilds());

        var buildParams = new CustomBuildParameters(buildTarget, buildGroup, outputPath);

        buildParams.PerBundleCompression.Add("Bundle1", BuildCompression.DefaultUncompressed);

        buildParams.PerBundleCompression.Add("Bundle2", BuildCompression.DefaultLZMA);

 

        if (m_Settings.compressionType == CompressionType.None)

            buildParams.BundleCompression = BuildCompression.DefaultUncompressed;

        else if (m_Settings.compressionType == CompressionType.Lzma)

            buildParams.BundleCompression = BuildCompression.DefaultLZMA;

        else if (m_Settings.compressionType == CompressionType.Lz4 || m_Settings.compressionType == CompressionType.Lz4HC)

            buildParams.BundleCompression = BuildCompression.DefaultLZ4;

 

        IBundleBuildResults results;

        ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParams, buildContent, out results);

        return exitCode == ReturnCode.Success;

    }

}

Load By Filename Example

The following example shows how to use the CompatibilityBuildPipeline methods to load by a filename instead of the full path.

 

The example uses the ContentBuildInterface.GenerateAssetBundleBuilds() method to get the set of bundles and assets to build, then modifies addressableNames field to set the loading path of the filename instead of the full path.

 

using System.IO;

using System.Linq;

using UnityEditor;

using UnityEditor.Build.Content;

using UnityEditor.Build.Pipeline;

 

public static class BuildAssetBundlesExample

{

    public static bool BuildAssetBundles(string outputPath, bool forceRebuild, bool useChunkBasedCompression, BuildTarget buildTarget)

    {

        var options = BuildAssetBundleOptions.None;

        if (useChunkBasedCompression)

            options |= BuildAssetBundleOptions.ChunkBasedCompression;

 

        if (forceRebuild)

            options |= BuildAssetBundleOptions.ForceRebuildAssetBundle;

 

        var bundles = ContentBuildInterface.GenerateAssetBundleBuilds();

        for (var i = 0; i < bundles.Length; i++)

            bundles[i].addressableNames = bundles[i].assetNames.Select(Path.GetFileNameWithoutExtension).ToArray();

 

        var manifest = CompatibilityBuildPipeline.BuildAssetBundles(m_Settings.outputPath, bundles, options, m_Settings.buildTarget);

        return manifest != null;

    }

}

 

Custom Build Task Example

 

// TODO: make code example

 

Assign Built-In Objects to Bundles Example

 

// TODO: Maybe this should just be built-in shader extraction?

 

Upgrade Guide

To build your AssetBundles with the SBP package, use the CompatibilityBuildPipeline.BuildAssetBundles method wherever you used the BuildPipeline.BuildAssetBundle method.

 

Note: Not all of the features that were supported previously are supported in SBP. 

 

The following tables list the features of the CompatibilityBuildPipeline.BuildAssetBundles method in comparison to the BuildPipeline.BuildAssetBundle method. 

 

Feature

Support

Notes

AssetBundles

Supported

SBP builds AssetBundles that are built nearly identically to the previous build pipeline. You load them in a similar manner to how you currently load AssetBundles. 

Incremental Building 

Supported

SBP implements this feature using the BuildCache.

Asset loading path

Behavior changed

AssetBundles built with BuildPipeline today support loading an Asset by full path (“Assets/ExampleFolder/Asset.prefab”) file name (“Asset”) or file name with extension (“Asset.prefab”). However AssetBundles built with SBP by default only support loading an Asset by full path (“Assets/ExampleFolder/Asset.prefab”). This is to avoid loading collision that can occur if two Assets in the same AssetBundle have the different full paths, but the same file name. To change this behavior, the loading path can be set using IBundleBuildContent.Addresses with the ContentPipeline API or AssetBundleBuild.addressableNames field. See Code Examples.

AssetBundle Manifest 

Behavior changed

SBP implements replacement functionality using the new class name CompatibilityAssetBundleManifest. This has an identical API to the existing AssetBundleManifest class, and has an additional method to get the CRC value for a bundle which did not exist before.

AssetBundle Variants

Not supported

There is currently no replacement functionality for AssetBundle Variants.

 

 

 

BuildAssetBundleOptions Enum:

 

Value

Support

Notes

UncompressedAssetBundle

Supported

Identical to using BuildCompression.DefaultUncompressed with the new API.

ChunkBasedCompression 

Supported

Identical to using BuildCompression.DefaultLZ4 with the new API. 

Note: This has always been LZ4HC in the Editor, and LZ4 if it was recompressed at Runtime.

DisableWriteTypeTree 

Supported

Identical to using ContentBuildFlags.DisableWriteTypeTree with the new API.

DeterministicAssetBundle 

Supported

This is enabled by default, and it can’t be disabled. SBP builds deterministically.

ForceRebuildAssetBundle 

Supported

Identical to using IBuildParameters.UseCache = false; with the new API.

AppendHashToAssetBundleName 

Supported

Identical to using IBundleBuildParameters.AppendHash = true; with the new API. 

DisableLoadAssetByFileName 

Always enabled

This is enabled by default, and can’t be disabled. SBP is strict about the rule: “what you pass in is exactly what you get out”. If you pass in “My/Example1/Example2/Asset.asset” as the file name to use to load the Asset, you must use that identifier exactly, including the correct upper and lower case, and all punctuation.

DisableLoadAssetByFileNameWithExtension 

Always enabled

See above details on DisableLoadAssetByFileName.

IgnoreTypeTreeChanges 

Not supported

The incremental build system used this value to prevent rebuilding AssetBundles when an Asset's serialization layout changed, but the data for the Asset itself did not change. SBP currently rebuilds if there are any changes.

StrictMode 

Not supported

The SBP is stricter about properly building AssetBundles and knowing when builds fail. 

DryRunBuild 

Not supported

SBP works fundamentally differently. It is faster to do a full build to determine if anything has changed.