Aggiungi funzioni di registrazione del tempo di caricamento

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

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

Un evento di caricamento può essere associato a metadati:

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 zero.

A un evento di caricamento può anche essere associata un'annotazione. Puoi definire la durata come le 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 del tempo di caricamento associato ai metadati e all'annotazione specificati e compila un valore 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 rilevati dall'utente. Alcuni esempi includono il caricamento di file, il caricamento delle scene, la decompressione e la compilazione dello mesh.

È importante comunicare ad Android Performance Tuner che gli eventi di caricamento fanno parte di questo gruppo, in modo che possa fornire informazioni migliori. A tale scopo, racchiudi 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 valore Result<ulong>.value da utilizzare nella funzione StopLoadingGroup(). I metadati e l'annotazione non vengono attualmente utilizzati dal backend di Google Play, ma solo l'annotazione può essere impostata su null. Tutti gli eventi di caricamento successivi sono codificati da un ID gruppo univoco.

ErrorCode StopLoadingGroup(ulong handle);

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

Figura 1. Esempio del gruppo di caricamento.

Esempi

Di seguito sono riportati alcuni esempi di come aggiungere funzioni relative al tempo di caricamento al gioco.

Eventi di caricamento file

Il seguente esempio di codice mostra come registrare gli eventi di caricamento file nel tuo 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 delle scene

Il seguente esempio di codice mostra come registrare gli eventi di caricamento delle scene nel tuo 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...

Il seguente esempio di codice mostra come aggiungere funzioni di caricamento di gruppo 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);
}