Важно регистрировать, когда ваша игра выполняет события загрузки, по двум причинам:
- Чтобы избежать загрязнения данных времени кадра при загрузке.
- Проанализировать время загрузки, чтобы увидеть, когда и где время загрузки превышает приемлемое.
Событие загрузки может иметь связанные метаданные:
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;
}
Любые поля, которые не соответствуют вашим потребностям, могут быть равны нулю.
Событие загрузки также может иметь связанную аннотацию. Вы можете определить её так же, как аннотации времени кадра, используя одно или несколько полей в сообщении Annotation
.
Result<ulong> StartRecordingLoadingTime(LoadingTimeMetadata eventMetadata, TAnnotation annotation);
Эта функция начинает запись события времени загрузки, связанного с заданными метаданными и аннотацией, и заполняет Result<ulong>.value
для использования в функции StopRecordingLoadingTime()
.
ErrorCode StopRecordingLoadingTime(ulong handle);
Эта функция останавливает запись события, ранее начатого функцией StartRecordingLoadingTime()
. Событие загружается при следующей очистке сеанса.
Загрузка групповых функций
В вашей игре вы можете записывать несколько событий загрузки в течение одного периода загрузки, видимого пользователю. Примеры включают загрузку файла , загрузку сцены , распаковку и компиляцию шейдера.
Важно сообщить Android Performance Tuner, что события загрузки входят в такую группу, чтобы он мог предоставлять более точную информацию. Для этого ограничьте события загрузки следующими функциями запуска и остановки.
Result<ulong> StartLoadingGroup(LoadingTimeMetadata eventMetadata, TAnnotation annotation);
Эта функция запускает группу загрузки, связанную с заданными метаданными и аннотацией, и заполняет значение Result<ulong>.value
для использования в функции StopLoadingGroup()
. Метаданные и аннотация в настоящее время не используются бэкендом Play, но только аннотация может быть установлена в null
. Все последующие события загрузки помечаются уникальным идентификатором группы.
ErrorCode StopLoadingGroup(ulong handle);
Эта функция останавливает группу загрузки, ранее запущенную функцией StartLoadingGroup()
. Последующие события загрузки не будут иметь идентификатор группы, пока не будет вызвана функция StartLoadingGroup()
снова.
Рисунок 1. Пример группы загрузки.
Примеры
Вот несколько примеров того, как добавить функции времени загрузки в вашу игру.
События загрузки файлов
В следующем примере кода показано, как записывать события загрузки файлов в вашей игре.
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;
}
}
}
События загрузки сцены
В следующем примере кода показано, как записывать события загрузки сцены в вашей игре.
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);
}
Загрузка групповых функций
В следующем примере кода показано, как добавить функции загрузки группы в вашу игру.
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);
}