Aggiungi funzioni di registrazione del tempo di caricamento

È importante registrare quando il gioco esegue eventi di caricamento per due motivi:

  1. Per evitare di contaminare i dati relativi al tempo di frame durante il caricamento.
  2. Per analizzare i tempi di caricamento e capire quando e dove sono più lunghi del consentito.

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

Un evento di caricamento può anche avere un'annotazione associata. Puoi definirli nello stesso modo delle annotazioni temporali dei frame, utilizzando uno o più campi nel messaggio Annotation.

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

Questa funzione inizia a registrare un evento di 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 avviata in precedenza da StartRecordingLoadingTime(). L'evento viene caricato al successivo svuotamento della sessione.

Caricamento delle funzioni di gruppo in corso…

Nel tuo gioco, potresti registrare diversi eventi di caricamento per un singolo periodo di caricamento visualizzato dall'utente. Alcuni esempi includono il caricamento dei file, il caricamento delle scene, la decompressione e la compilazione degli shader.

È importante comunicare ad Android Performance Tuner che gli eventi di caricamento fanno parte di un gruppo di questo tipo, in modo che possa fornire informazioni migliori. Per farlo, racchiudi gli eventi di caricamento tra le seguenti funzioni di inizio e fine.

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

Questa funzione avvia un gruppo di caricamento associato ai metadati e all'annotazione specificati e compila un Result<ulong>.value da utilizzare nella funzione StopLoadingGroup(). Al momento i metadati e l'annotazione non vengono utilizzati dal backend di Play, ma solo l'annotazione può essere impostata su null. Tutti gli eventi di caricamento successivi vengono taggati con 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 finché non viene chiamato di nuovo StartLoadingGroup().

Figura 1. Esempio del gruppo di caricamento.

Esempi

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

Eventi di caricamento dei file

Il seguente esempio di codice 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 della scena

Il seguente esempio di codice mostra come registrare gli eventi di caricamento della scena 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 gruppi 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);
}