Aggiungi funzioni di registrazione del tempo di caricamento

È importante registrare gli eventi di caricamento del gioco per due motivi:

  1. Per evitare di contaminare i dati sulla durata frame durante il caricamento.
  2. Per analizzare i tempi di caricamento per capire quando e dove i tempi di caricamento sono più lunghi di quelli accettabili.

Un evento di caricamento può avere metadati associati:

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;
}

Tutti i campi non pertinenti alle tue esigenze possono essere uguali a zero.

Un evento di caricamento può anche avere un'annotazione associata. Puoi definire la durata allo stesso modo delle annotazioni della durata frame, utilizzando uno o più campi nel messaggio Annotation.

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

Questa funzione inizia a registrare un evento relativo al tempo di caricamento associato ai metadati e all'annotazione specificati e compila un Result<ulong>.value da utilizzare nella funzione StopRecordingLoadingTime().

ErrorCode StopRecordingLoadingTime(ulong handle);

Questa funzione interrompe la registrazione di un evento avviato in precedenza da StartRecordingLoadingTime(). L'evento viene caricato al successivo svuotamento della sessione.

Caricamento delle funzioni di gruppo in corso...

Nel tuo gioco, puoi registrare diversi eventi di caricamento per un singolo periodo di caricamento rilevato dall'utente. Alcuni esempi includono il caricamento dei file, il caricamento delle scene, la decompressione e la compilazione dello Shadr.

È importante comunicare ad Android Performance Tuner che gli eventi di caricamento fanno parte di questo gruppo in modo che possa fornire informazioni migliori. A questo scopo, associa gli eventi di caricamento con le seguenti funzioni di avvio e arresto.

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

Questa funzione avvia un gruppo di caricamento associato ai metadati e all'annotazione specificati e compila un elemento Result<ulong>.value da utilizzare nella funzione StopLoadingGroup(). I metadati e le annotazioni non sono attualmente utilizzati dal backend di Google Play, ma solo l'annotazione può essere impostata su null. A tutti gli eventi di caricamento successivi viene assegnato un ID gruppo univoco.

ErrorCode StopLoadingGroup(ulong handle);

Questa funzione interrompe il caricamento di un gruppo avviato in precedenza da StartLoadingGroup(). Gli eventi di caricamento successivi non avranno un ID gruppo fino a quando StartLoadingGroup() non verrà richiamato di nuovo.

Figura 1. Esempio del gruppo di caricamento.

Esempi

Ecco alcuni esempi di come aggiungere funzioni relative al tempo di caricamento al gioco.

Eventi di caricamento file

L'esempio di codice seguente mostra come registrare gli eventi di caricamento dei file nel gioco.

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;
        }
    }
}

Eventi di caricamento scena

L'esempio di codice seguente mostra come registrare eventi di caricamento delle scene nel gioco.

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);
}

Caricamento delle funzioni di gruppo in corso...

L'esempio di codice seguente mostra come aggiungere funzioni di gruppo di caricamento al tuo gioco.

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);
}