目次
仮説
Unity のフレーム単位の読み込み (プログレッシブ読み込みとも呼ばれます) は、リソースを小さなチャンクに分割し、フレームごとに読み込むことで、ゲームのパフォーマンスとユーザー エクスペリエンスを向上させる最適化手法です。フレーム読み込みの利点は次のとおりです。
-
ゲームの読み込み速度の向上: アセットを小さなチャンクに分割して読み込むと、現在のフレームに必要なアセットの部分のみが読み込まれるため、読み込み時間を短縮できます。これは、大規模なゲームやリソースを大量に消費するシーンで特に役立ち、初期ロード時間を短縮し、プレーヤーをより早くゲームに参加させることができます。
-
メモリ フットプリントの削減: リソースをフレームにロードすると、各フレームに必要なメモリ フットプリントを削減できます。現在のフレームに必要なリソースのみをロードする場合、すべてのリソースを一度にメモリにロードすることを回避できるため、メモリ消費量が削減されます。これは、メモリが限られているデバイスや大規模なゲームにとって非常に重要です。
-
ゲームの流暢性の向上: フレームごとにロードすることで、フレーム レートが低下したときの明らかな途切れを回避できます。すべてのリソースを一度にロードする場合と比較して、フレームごとのロードはバックグラウンドでリソースをスムーズにロードすることができ、フレーム レートの速度に応じて適切なロードを実行できます。これにより、リソースの読み込み中もゲームがスムーズに実行されます。
-
ゲーム世界のシームレスな接続を強化: フレームごとの読み込みにより、さまざまなシーンやレベルのシームレスな接続を実現できます。シーンまたはレベルがロードされると、ゲームは次のシーンまたはレベルをスムーズにロードできるため、プレイヤーはゲーム世界の連続性を感じることができます。
-
ゲームの適応性の向上: フレームでロードすることにより、ゲームはデバイスのパフォーマンスとリソースの状態に応じてロード戦略に自動的に適応できます。これは、ゲームがハイエンド PC であってもローエンド モバイル デバイスであっても、さまざまなデバイスで優れたユーザー エクスペリエンスを提供できることを意味します。
全体として、Unity のフレームごとの読み込みにより、ゲームの読み込み速度が向上し、メモリ使用量が削減され、流暢性が向上し、シームレスな接続が実現され、ゲームの適応性が向上します。これは、ゲームのパフォーマンスとユーザー エクスペリエンスを向上させる強力な最適化手法です。
コード部分
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CilpFPS : MonoBehaviour
{
//协程id
private int id;
//协程字典
Dictionary<int, Coroutine> dic=new Dictionary<int, Coroutine>();
public void AddFPS<T>(List<T> list,int num,Action<T> action)
{
int name = id++;
Coroutine coroutine =StartCoroutine(GetFromInfoList(name,list,num,action));
dic.Add(name, coroutine);
}
/// <summary>
/// 添加分帧
/// </summary>
/// <param name="max">分帧加载的总数量<</param>
/// <param name="num">一帧调用的帧的数量</param>
/// <param name="action">具体做什么</param>
public void AddFPS(int max,int num,Action<int> action)
{
int name = id++;
Coroutine coroutine =StartCoroutine(GetFromInfoList(name,max,num,action));
dic.Add(name, coroutine);
}
/// <summary>
/// 开始分帧加载
/// </summary>
/// <param name="name">协程名称</param>
/// <param name="max">分帧加载的总数量</param>
/// <param name="num">一帧调用的帧的数量</param>
/// <param name="action">具体做什么</param>
/// <returns></returns>
IEnumerator GetFromInfoList<T>(int name, List<T> list, int num, Action<T> action)
{
int InfoListIndex = 0;
foreach (T item in list)
{
InfoListIndex++;
action(item);
if (InfoListIndex % num == 0)
{
yield return null; // 在下一帧执行
}
}
StopFPS(name);
}
/// <summary>
/// 开始分帧加载
/// </summary>
/// <param name="name">协程名称</param>
/// <param name="max">分帧加载的总数量</param>
/// <param name="num">一帧调用的帧的数量</param>
/// <param name="action">具体做什么</param>
/// <returns></returns>
IEnumerator GetFromInfoList(int name, int max, int num, Action<int> action)
{
for (int i = 0; i < max; i++)
{
action(i);
if(i% num == 0)
{
//每一帧提取5条数据
Debug.Log("运行时间:"+Time.time + ",创建次数:" + (i+1));
yield return null; // 在下一帧执行
}
}
StopFPS(name);
}
/// <summary>
/// 移除协程
/// </summary>
/// <param name="name"></param>
private void StopFPS(int name)
{
if(dic.ContainsKey(name))
{
StopCoroutine(dic[name]);
dic.Remove(name);
}
}
}
呼び出しコード
using UnityEngine;
public class CreateFps : MonoBehaviour
{
public GameObject game;
public CilpFPS cilpFPS;
void Start()
{
cilpFPS.AddFPS(20,1, (i) =>
{
GameObject game1=Instantiate(game,transform);
game1.transform.position=new Vector3(i,0,i);
});
}
}
エフェクトデモ