# 在运行时使用 Build Automation 的构建清单

> Access build manifest data at runtime for analytics and bug reporting in Unity Build Automation.

让游戏的运行时代码了解构建本身的关键信息通常很有用。构建名称和构建编号等信息在报告错误或跟踪分析数据时非常有用。为了便于实现这一点，Build Automation 会在构建时向游戏中注入一个清单，以便稍后在运行时可以访问这些关键数据。

Build Automation 以 JSON 格式的 [`TextAsset`](https://docs.unity3d.com/Manual/class-TextAsset.html) 形式提供该清单。Build Automation 会将清单存储为游戏资源，并可以通过 `Resources.Load()` 来访问。构建清单包含以下值：

| **值**                  | **属性**                                                        |
| ---------------------- | ------------------------------------------------------------- |
| `scmCommitId`          | 已构建的提交或变更列表。                                                  |
| `scmBranch`            | 已构建的分支名称。                                                     |
| `buildNumber`          | 与此构建对应的 Build Automation 构建编号。                                |
| `buildStartTime`       | 构建过程开始时的 UTC 时间戳。                                             |
| `projectId`            | Unity 项目标识符。                                                  |
| `bundleId`             | 在 Build Automation 中配置的 `bundleIdentifier`（仅限 iOS 和 Android）。 |
| `unityVersion`         | Build Automation 用于创建构建的 Unity 版本。                            |
| `xcodeVersion`         | 用于构建项目的 XCode 版本（仅限 iOS）。                                     |
| `cloudBuildTargetName` | 已构建的构建目标的名称。                                                  |

名为 **UnityCloudBuildManifest.json** 的清单 TextAsset 会写入 `Assets/UnityCloud/Resources` 文件夹。

## 用于本地测试##for-local-testing

要在本地测试构建清单功能，请将文件命名为 `UnityCloudBuildManifest.json.txt`。不要将此文件提交到项目代码仓库中的 **Assets/UnityCloud/Resources** 文件夹，因为它可能会干扰 Build Automation 清单文件。

## 使用清单##use-the-manifest

您可以在运行时通过以下方式访问清单：

* [以 JSON 格式访问清单](#build-manifest-as-json)。
* [以 ScriptableObject 形式访问清单](#build-manifest-as-scriptableobject)。

### 以 JSON 格式访问构建清单##build-manifest-as-json

您可以在运行时以 JSON 格式访问 Build Automation 清单。此资源需要自定义解析逻辑，或使用第三方 JSON 解析器。

以下 C# 代码示例演示了如何使用 [GitHub Gist](https://gist.github.com/darktable/1411710) 上的 MiniJSON 解析器来加载和解析构建清单：

```cs
using UnityEngine;
using System.Collections.Generic;
using MiniJSON;

public class MyGameObject: MonoBehaviour
{
    void Start()
    {
        var manifest = (TextAsset) Resources.Load("UnityCloudBuildManifest.json");
        if (manifest != null)
        {
            var manifestDict = Json.Deserialize(manifest.text) as Dictionary<string,object>;
            foreach (var kvp in manifestDict)
            {
                // Be sure to check for null values!
                var value = (kvp.Value != null) ? kvp.Value.ToString() : "";
                Debug.Log(string.Format("Key: {0}, Value: {1}", kvp.Key, value));
            }
        }
    }
}
```

### 以 `ScriptableObject` 形式访问构建清单##build-manifest-as-scriptableobject

`BuildManifestObject` 是一种 [`ScriptableObject`](https://docs.unity3d.com/ScriptReference/ScriptableObject.html)，可用于通过脚本访问构建清单中的值，而无需手动加载 `UnityCloudBuildManifest.json` TextAsset。

如果尚未写入 `UnityCloudBuildManifest.json` TextAsset，则 `BuildManifestObject` 是 Build Automation 调用的导出前方法的一个可选参数。有关更多信息，请参阅[以 JSON 格式访问清单](#build-manifest-as-json)。

以下 C# 代码示例演示了一种导出前方法，该方法根据清单中提供的 `buildNumber` 更新 `PlayerSettings` 中的 `bundleVersion`。有关导出前方法的更多信息，请参阅[导出前和导出后方法](../advanced-build-configuration/run-custom-scripts-during-the-build-process#pre-export-and-post-export-methods)。

```cs
using UnityEngine;
using UnityEditor;
using System;

public class CloudBuildHelper : MonoBehaviour
{
    #if UNITY_CLOUD_BUILD
        public static void PreExport(UnityEngine.CloudBuild.BuildManifestObject manifest)
        {
            PlayerSettings.bundleVersion = string.Format("1.0.{0}", manifest.GetValue<int>("buildNumber"));
        }
    #endif
}
```

以下是 `BuildManifestObject` 类的公共接口：

```cs
namespace UnityEngine.CloudBuild
{
    public class BuildManifestObject : ScriptableObject
    {
        // Try to get a manifest value - returns true if key was found and could be cast to type T, otherwise returns false.
        public bool TryGetValue<T>(string key, out T result);
        // Retrieve a manifest value or throw an exception if the given key isn't found.
        public T GetValue<T>(string key);
        // Set the value for a given key.
        public void SetValue(string key, object value);
        // Copy values from a dictionary. ToString() will be called on dictionary values before being stored.
        public void SetValues(Dictionary<string, object> sourceDict);
        // Remove all key/value pairs.
        public void ClearValues();
        // Return a dictionary that represents the current BuildManifestObject.
        public Dictionary<string, object> ToDictionary();
        // Return a JSON formatted string that represents the current BuildManifestObject
        public string ToJson();
        // Return an INI formatted string that represents the current BuildManifestObject
        public override string ToString();
    }
}
```
