【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具有對模型文件,紋理文件,音頻文件,視頻文件和文本文件的多種文件格式的本機(內置)支持,

image.png

image.png

      上圖中說的不對, 比如模型資源Maya 要導入Unity 需要:

image.png

        更具體的所有資源類型的導入和設置可以看:   文章內容較老~

 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 文件夾下

       兩個字母的文件夾是啥? 是資源名稱的前兩個字母。

image.png

 

 

任意的數據流的結果 是128位的哈希值。 

image.png

 

image.png

         有靜態和動態的依賴關係。 

image.png

            什麼是確定性, 就是相同的輸入,肯定有相同的輸出。 

下面的代碼中有不確定的函數和確定的函數處理。             第一個函數在第二次執行的時候會失敗,因爲Move的目標路徑已經有資源了。 所以確保目標路徑不存在資源。 

image.png

 

-- 確保在導入資產時,由於所有依賴項都相同,因此導入結果相同

-- 跨機器相同

-- 對於遠程緩存數據非常重要

image.png

 

關於 AssetDatabase 

AD 分爲兩個數據庫 。

  • Source Asset Database 
  • Artifact Database

Memory mapped Database   內存映射數據庫

交易性的,因此更難腐敗

image.png

 

image.png

 

image.png

 

 

          有四種方式觸發刷新~

image.png

自動刷新,    每當進入和退出Unity的時候 ,會從操作系統那得到一個窗口焦點事件, 那是一個C++ Native層。 通過C# 調用它, 這是唯一被強迫的方法,  同步腳本編譯的含義,知道所有腳本被編譯然後繼續導入的過程

image.png

     菜單就是  Ctrl + R 刷新。

image.png

 

image.png

 

1、Scan 掃描:

            遍歷 Assets 文件夾。   檢測變化的文件, 如果改變了要對它重新哈希,並存儲到數據庫中。 

             還要枚舉 packages 文件夾, 但他們有一個區別, 只對pachages做一次,因爲認爲是不可變的(只讀)。

image.png

 

這裏就有一個問題,如果項目很大,有很複雜的文件結構,數以萬計的文件數量,這個枚舉是需要很長時間的!

image.png

       本質上是操作系統告訴我們改變了什麼, 而不是我們主動去詢問了。

 

2、分類 Catagorize Assets :

也許資源沒有變化, 但是它所依賴的資源改變了。

image.png

 

image.png

 

image.png

 

    顏色空間是線性Linear Space 還是  Gamma Space 

     圖形API 是   DX, Metal, Opengl, Valkan 

      腳本運行時腳本  是 .Net 4x  還是 .Net Standard 2.0,  .Net 3.5,         因爲切換要用新的API重新編譯。 

      貼圖的壓縮設置: image.png

image.png

 

3、 Compile Scripts

          還有一個腳本編譯管道   Script Compilation Pipeline

image.png

 

image.png

 

4、 Import

image.png

 

5、Post Process All Assets 

image.png

 

 

Fast Platform  Switch 

      下面的情景,      浪費時間

image.png

 

image.png

 

image.png

           如果沒有改變就不會在重新進行哈希,   現在可以節省很多時間,  如果使用Cache Server 會更快。 

image.png

 

image.png

 

Tips & Tricks of the AssetDatabase 

        之前的情況:

image.png

        新版本:    將會生成一個新的文件!!      還是就是爲了快速平臺切換?

image.png

 

image.png

 

image.png

        慢的原因是觸發的各種回調!

image.png

        這樣可以加快,  之前使用過,但是遇到比較煩的是如果中間遇到報錯,但是沒有執行到Stop ,Unity就卡死了,       可能是沒有使用try catch 的處理方式吧。 (視頻中也提到這個問題!)

image.png

 

image.png

 

 

QA:

         比之前快了  16%

 

 

 

 

 

 

 

 

 

 

 

可編寫腳本的構建管道性能:  https://forum.unity.com/threads/scriptable-build-pipeline-performance.712376/

image.png

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.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章