Funktionen zur Aufzeichnung der Ladezeit hinzufügen

Es ist wichtig, dass Sie aufzeichnen, wann Ihr Spiel Ladeereignisse zwei Gründe:

  1. Um eine Verschmutzung Ihrer Frame Time-Daten beim Laden zu vermeiden.
  2. Um Ladezeiten zu analysieren, um zu ermitteln, wann und wo Ladezeiten länger sind als akzeptabel.

Ein Ladeereignis kann zugehörige Metadaten haben:

public class LoadingTimeMetadata
{
    public enum LoadingState
    {
        Unknown = 0,

        /// <summary>
        ///     The first time the game is run.
        /// </summary>
        FirstRun = 1,

        /// <summary>
        ///     App is not backgrounded.
        /// </summary>
        ColdStart = 2,

        /// <summary>
        ///     App is backgrounded.
        /// </summary>
        WarmStart = 3,

        /// <summary>
        ///     App is backgrounded, least work needed.
        /// </summary>
        HotStart = 4,

        /// <summary>
        ///     Asset loading between levels.
        /// </summary>
        InterLevel = 5
    }

    public LoadingState state;

    public enum LoadingSource
    {
        UnknownSource = 0,

        /// <summary>
        ///     Uncompressing data.
        /// </summary>
        Memory = 1,

        /// <summary>
        ///     Reading assets from APK bundle.
        /// </summary>
        Apk = 2,

        /// <summary>
        ///     Reading assets from device storage.
        /// </summary>
        DeviceStorage = 3,

        /// <summary>
        ///     Reading assets from external storage, e.g. SD card.
        /// </summary>
        ExternalStorage = 4,

        /// <summary>
        ///     Loading assets from the network.
        /// </summary>
        Network = 5,

        /// <summary>
        ///     Shader compilation.
        /// </summary>
        ShaderCompilation = 6,

        /// <summary>
        ///     Time spent between process starting and onCreate.
        /// </summary>
        PreActivity = 7,

        /// <summary>
        ///     Total time spent between process starting and first render frame.
        /// </summary>
        FirstTouchToFirstFrame = 8,

        /// <summary>
        ///     Time from start to end of a group of events.
        /// </summary>
        TotalUserWaitForGroup = 9
    }

    public LoadingSource source;

    /// <summary>
    ///     0 = no compression, 100 = max compression
    /// </summary>
    public int compression_level;

    public enum NetworkConnectivity
    {
        Unknown = 0,
        Wifi = 1,
        CellularNetwork = 2
    }

    public NetworkConnectivity network_connectivity;

    /// <summary>
    ///     Bandwidth in bits per second.
    /// </summary>
    public ulong network_transfer_speed_bps;

    /// <summary>
    ///     Latency in nanoseconds.
    /// </summary>
    public ulong network_latency_ns;
}

Alle Felder, die für Ihre Anforderungen nicht relevant sind, können null sein.

Ein Ladeereignis kann auch mit einer Anmerkung verknüpft sein. Sie können im Feld wie bei Frame Time-Anmerkungen, wobei ein oder mehrere Felder im Annotation verwendet werden angezeigt.

Result<ulong> StartRecordingLoadingTime(LoadingTimeMetadata eventMetadata, TAnnotation annotation);

Diese Funktion beginnt mit der Aufzeichnung eines Ladezeitereignisses, das mit der angegebenen Metadaten und Annotationen und füllt eine Result<ulong>.value aus, die im StopRecordingLoadingTime().

ErrorCode StopRecordingLoadingTime(ulong handle);

Diese Funktion beendet die Aufzeichnung eines Ereignisses, das zuvor durch gestartet wurde. StartRecordingLoadingTime() Das Ereignis wird bei der nächsten Leerung der Sitzung hochgeladen.

Gruppenfunktionen werden geladen

Sie können in Ihrem Spiel mehrere Ladeereignisse für einen einzigen Ladezeitraum aufzeichnen. die für die Nutzenden sichtbar sind. Beispiele: Laden von Dateien, Szenen Laden, Dekomprimierung und Shader-Kompilierung.

Es ist wichtig, den Android Performance Tuner darüber zu informieren, dass Ladeereignisse Teil damit sie bessere Erkenntnisse liefern kann. Laden in Klammern setzen mit den folgenden Start- und Stopp-Funktionen verwenden.

Result<ulong> StartLoadingGroup(LoadingTimeMetadata eventMetadata, TAnnotation annotation);

Diese Funktion startet eine Ladegruppe, die mit den angegebenen Metadaten verknüpft ist, und füllt eine Result<ulong>.value aus, die im StopLoadingGroup(). Die Metadaten und die Anmerkung sind derzeit nicht wird vom Play-Back-End verwendet, aber nur die Annotation kann auf null gesetzt werden. Alle nachfolgenden Ladeereignisse mit einer eindeutigen Gruppen-ID gekennzeichnet.

ErrorCode StopLoadingGroup(ulong handle);

Diese Funktion stoppt eine zuvor von StartLoadingGroup() gestartete Ladegruppe. Nachfolgende Ladeereignisse haben bis StartLoadingGroup() keine Gruppen-ID. erneut aufgerufen wird.

Abbildung 1: Beispiel für die Ladegruppe.

Beispiele

Im Folgenden finden Sie einige Beispiele dafür, wie Sie Ladezeitfunktionen zu Ihrem Spiel hinzufügen können.

Ladeereignisse für Dateien

Das folgende Codebeispiel zeigt, wie Sie Ladeereignisse für Dateien in Ihrem Spiel aufzeichnen.

public RawImage image;

IEnumerator LoadImageFromStreamingAssets(string imageName)
{
    string imagePath = "file://" + Path.Combine(Application.streamingAssetsPath, imageName);
    using (var r = UnityWebRequestTexture.GetTexture(imagePath))
    {
        LoadingTimeMetadata fileLoadingMetadata = new LoadingTimeMetadata()
        {
            state = LoadingTimeMetadata.LoadingState.InterLevel,
            source = LoadingTimeMetadata.LoadingSource.DeviceStorage,
            // Fields are zero by default but they could be set as follows
            compression_level = 0,
            network_connectivity = 0,
            network_transfer_speed_bps = 0,
            network_latency_ns = 0
        };
        Annotation annotation = new Annotation()
        {
            Scene = Scene.MagicalForest
        };
        // Start recording loading time.
        Result<ulong> result = performanceTuner.StartRecordingLoadingTime(fileLoadingMetadata, annotation);
        yield return r.SendWebRequest();
        // Stop recording loading time.
        performanceTuner.StopRecordingLoadingTime(result.value);
        if (r.isNetworkError || r.isHttpError)
        {
            Debug.Log(r.error);
        }
        else
        {
            Texture2D tex = DownloadHandlerTexture.GetContent(r);
            image.texture = tex;
        }
    }
}

Ereignisse zum Laden von Szenen

Das folgende Codebeispiel zeigt, wie Sie Ereignisse zum Laden von Szenen in Ihrem Spiel.

IEnumerator LoadScene(int sceneIndex)
{
    LoadingTimeMetadata metadata = new LoadingTimeMetadata()
        {state = LoadingTimeMetadata.LoadingState.InterLevel};
    Annotation annotation = new Annotation() {Scene = (Scene) (sceneIndex + 1)};
    Result<ulong> result = performanceTuner.StartRecordingLoadingTime(metadata, annotation);
    AsyncOperation asyncSceneLoad = SceneManager.LoadSceneAsync(sceneIndex, LoadSceneMode.Single);
    while (!asyncSceneLoad.isDone)
    {
        yield return null;
    }

    performanceTuner.StopRecordingLoadingTime(result.value);
}

Gruppenfunktionen werden geladen

Das folgende Codebeispiel zeigt, wie Sie Ladegruppenfunktionen zu Ihrem Spiel.

IEnumerator LoadImages()
{
    LoadingTimeMetadata groupMetadata = new LoadingTimeMetadata()
    {
        state = LoadingTimeMetadata.LoadingState.InterLevel,
        source = LoadingTimeMetadata.LoadingSource.DeviceStorage,
    };
    Result<ulong> result = performanceTuner.StartLoadingGroup(groupMetadata, null);
    yield return StartCoroutine(LoadImageFromStreamingAssets("image1.jpeg"));
    yield return StartCoroutine(LoadImageFromStreamingAssets("image2.jpeg"));
    yield return StartCoroutine(LoadImageFromStreamingAssets("image3.jpeg"));
    yield return StartCoroutine(LoadImageFromStreamingAssets("image4.jpeg"));
    var stopErrorCode = performanceTuner.StopLoadingGroup(0);
}