חשוב לתעד את זמן הטעינה של המשחק שתי סיבות:
- כדי לא להעמיס על נתוני זמן הפריימים במהלך הטעינה.
- כדי לנתח את זמני הטעינה כדי לראות מתי ואיפה זמני הטעינה ארוכים מ- מקובל עליי.
לאירוע טעינה יכולים להיות מטא-נתונים משויכים:
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()
האירוע יועלה בזמן הסשן הבא.
הפונקציות של הקבוצה בטעינה
במשחק שלכם, אפשר להקליט מספר אירועי טעינה בתקופת טעינה אחת שהמשתמש רואה. דוגמאות: טעינת קבצים, סצינה טעינה, הסרת דחיסה והידור של תוכנת ההצללה (shader).
חשוב להודיע ל-Android Performance Turre שאירועי טעינה הם חלק של קבוצה כזו כדי שיוכל לספק תובנות טובות יותר. סיום הטעינה כדי לעשות זאת, מופיעים אירועים עם פונקציות ההתחלה והעצירה הבאות.
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);
}