【UE 4のリソースロードとリリース】
6117 ワード
リソースロードといえば、まずUEのリソースへの参照について述べる.
FSoftObjectPath&FsoftClassPath
UEゲーム実行時には通常メモリブラウザのリソースをロードする必要があり、FSoftObjectPath&FsoftClassPathは対応するリソースのパスを表す
FSoftObjectPath
ここで、FSoftObjectPathは、青写真リソースまたは非青写真リソースを含むすべてのリソースのパスを指すことができる.C++で変数を宣言する場合は、対応するmetaメソッドを追加するなど、Upropertyを使用してリソースタイプを制限できます.
FsoftClassPathは、青写真リソースのパスのみを指します.
使用方法は、Pathのtostringメソッドを呼び出してリソースパスを取得することです.
FSoftObjectPtr&TSoftObjectPtr&TSoftClassPtr
ソフトオブジェクトポインタは、非同期ロードリソースがコールバック関数のトリガを完了したときにリソースポインタを取得するために使用され、UEの非同期ロードは直接オブジェクトポインタを取得できない.非同期でロードされた関数は後で話します.
TSoftObjectPtrは、FSoftObjectPtrをカプセル化したテンプレートであり、ファイルパス下のリソースがメモリにロードされているかどうかを検出し、リソースポインタを取得する.違いはポインタを必要とせずにCastタイプ変換操作をもう一度行うことです.
TSoftClassPtrとPath変数の命名は、青写真リソースのロードされたオブジェクトを検出するために使用されます.
UEのリソースロード
UEのリソースロードは、同期ロードと非同期ロードに分けられる
同期ロード
同期ロードには2つのAPIがあります FStreamableManager::LoadSynchronous FStreamableManager::RequestSyncLoad
読み込みは、FStreamableHandleタイプのポインタ="Handleを返します.同期ロード内部は実は非同期ロードであり、FStreamableHandle::WaitUntilComplete()ブロック待ちを呼び出す.
RequestSyncLoad関数の内部では、非同期ロードが行われ、WaitUntilComplete関数が呼び出されるか、LoadObject関数が直接呼び出されます.どちらが速いかは、どちらを調整します.
非同期ロード
API FStreamableManager::RequestAsyncLoad
非同期ロードの終了は、ロードされたコールバック関数を使用してロードされたリソースオブジェクトポインタを得るコールバック関数を設定することもできます.
現在、非同期ロードはUserWidgetリソースをロードするために使用できません.
青写真ロード
StreamManagerで青写真をロードする場合、デフォルトのパスは使用できません(接尾辞に_Cが付いていても)、ロードされたClassは使用できません.空ではありませんが.正しい方法:接頭辞はClassで統一され、接尾辞に_Cが追加されます.
じどうかいしゅう
上記の方法でリソースをロードすると、オブジェクトが参照を失うと自動的に解放され、非同期ロードの場合、オブジェクトはコールバック関数でのみ有効になり、コールバック関数の実行が完了すると回収可能とマークされます.では、非同期ロードされたリソースをどのように保存しますか?
プロジェクトには、コールバックでロードされたオブジェクトが保存されていないのではなく、非同期リソースロードが保存されているHandleが表示され、Handleによって取得されたGetLoadedAssetsによってロードされたオブジェクトが取得されます.オブジェクトプールに保存してからHandleを解放します.
手動回収
リソースをロードするときにbManageActiveHandleがtrueに設定されている場合、オブジェクトは手動で解放されるまでメモリを常駐させます.
オブジェクトが不要な場合は、unloadを手動で実行します.
エディタモードでは、上記の2つの方法は有効になりません.パッケージバージョンのみです.エディタモードでDestroyまたはMarkPendingKill()を強制すると、オブジェクトはメモリから破棄できますが、エディタを再起動しない限り、再度ロードすることはできません(検証待ち)
に注意 FStreamableManager::Unload()は、現在のリソースに関連するすべてのFStreamableHandleを削除します.たとえば、bManageActiveHandleがtrueに設定されている場合でも、3つのFStreamableHandleオブジェクトを1回呼び出すだけで、メモリからオブジェクトを解放することができます.この3つのFStreamableHandleオブジェクトに対してそれぞれReleaseを実行すると、最後のHandleがReleaseされた場合にのみ、リソースがメモリから解放されます. が非同期でロードされた場合、誰が先に要求するかは、誰のコールバック関数が先に実行され、コールバック関数の実行順序が乱れているという問題はありません(TAsyncLoadPriorityを変更しない限り)、エンジン内部でコールバック要求を受信したコンテナはTArrayを使用し、インデックスが0のコールバックを実行するたびにRemoveAt(0)が使用されるためです. 非同期ロード時、リソースのロードが完了していない場合(ロード時にbManageActiveHandleがtrueであると仮定)にReleaseHandleを実行します.たとえば、コールバック関数を実行する前にRelease Handleを実行すると、リソースのロードが完了した後(コールバック関数が実行された後)にメモリから自動的に回収されます.ただし、コールバック関数内のForceGCを除いて、オブジェクトはコールバック関数で有効です. UPROPERTY()修飾メンバー変数は、保持するリソースオブジェクトをメモリに常駐させることができ、メモリを常駐させる必要がなくなると、そのメンバー変数値をNULLとし、次回GC時まで自動的に を回収する. GEngine->ForceGarbageCollection();実行後、メモリ回収は少なくとも次のフレームまで待たなければなりません.現在のフレーム内では、オブジェクトがConditionalBeginDestroy()を実行し、ForceGarbageCollectionを実行しても、現在のフレーム内のオブジェクトは有効です. C o n d i tionalBeginDestroy()は、すべてのUObjectに存在するAPIであり、そのオブジェクト破棄は非同期実行であり、オブジェクトは現在のフレーム内で持続的に有効である.AActor::Destroy()は、現在のフレームの終了時にオブジェクト回収が発生するAActor固有のAPIです.
参照先:
https://zhuanlan.zhihu.com/p/33303645
https://blog.csdn.net/qq_29523119/article/details/84929384
プロジェクト関連のコード
FSoftObjectPath&FsoftClassPath
UEゲーム実行時には通常メモリブラウザのリソースをロードする必要があり、FSoftObjectPath&FsoftClassPathは対応するリソースのパスを表す
FSoftObjectPath
ここで、FSoftObjectPathは、青写真リソースまたは非青写真リソースを含むすべてのリソースのパスを指すことができる.C++で変数を宣言する場合は、対応するmetaメソッドを追加するなど、Upropertyを使用してリソースタイプを制限できます.
UPROPERTY(EditAnywhere, meta = (AllowedClasses ="Material,StaticMesh"))
FSoftObjectPath softObjectPath;
FsoftClassPathは、青写真リソースのパスのみを指します.
使用方法は、Pathのtostringメソッドを呼び出してリソースパスを取得することです.
FSoftObjectPtr&TSoftObjectPtr&TSoftClassPtr
ソフトオブジェクトポインタは、非同期ロードリソースがコールバック関数のトリガを完了したときにリソースポインタを取得するために使用され、UEの非同期ロードは直接オブジェクトポインタを取得できない.非同期でロードされた関数は後で話します.
void ATestLoadObjectCharacter::BeginPlay()
{
Super::BeginPlay();
FStreamableManager streamableManager;
FString strMeshFileName = "/Game/Geometry/Meshes/1M_Cube.1M_Cube";
FStreamableDelegate streamableDelegate;
FSoftObjectPath strMeshObjectFileName = FSoftObjectPath(strMeshFileName);
streamableDelegate.BindUObject(this, &ThisClass::LoadFinish, strMeshObjectFileName);
streamableManager.RequestAsyncLoad(strMeshObjectFileName, streamableDelegate);
}
void ATestLoadObjectCharacter::LoadFinish(FSoftObjectPath meshFilePath)
{
FSoftObjectPtr meshObjectPtr = FSoftObjectPtr(meshFilePath);
UObject* pObject = meshObjectPtr.Get();
if (nullptr == pObject)
return;
UStaticMesh* pStaticMesh = Cast(pObject);
if (pStaticMesh)
{
UE_LOG(LogTemp, Error, TEXT("UStaicMesh name is %s"), *pStaticMesh->GetName());
}
}
TSoftObjectPtrは、FSoftObjectPtrをカプセル化したテンプレートであり、ファイルパス下のリソースがメモリにロードされているかどうかを検出し、リソースポインタを取得する.違いはポインタを必要とせずにCastタイプ変換操作をもう一度行うことです.
TSoftClassPtrとPath変数の命名は、青写真リソースのロードされたオブジェクトを検出するために使用されます.
void AMyProject7Character::BeginPlay()
{
Super::BeginPlay();
FStreamableManager streamableManager;
FString strBPClassPath = "/Game/testActor.testActor_C";
FStreamableDelegate streamableDelegate;
FSoftClassPath SoftBPClassPathName = FSoftClassPath(strBPClassPath);
streamableDelegate.BindUObject(this, &ThisClass::LoadFinish, SoftBPClassPathName);
streamableManager.RequestAsyncLoad(SoftBPClassPathName, streamableDelegate);
}
void AMyProject7Character::LoadFinish(FSoftClassPath SoftBPClassPathName)
{
TSoftClassPtr ActorClassPtr = TSoftClassPtr(SoftBPClassPathName);
UClass* pClass = ActorClassPtr.Get();
if (pClass)
{
UE_LOG(LogTemp, Error, TEXT("UStaicMesh name is %s"), *pClass->GetName());
}
}
UEのリソースロード
UEのリソースロードは、同期ロードと非同期ロードに分けられる
同期ロード
同期ロードには2つのAPIがあります
読み込みは、FStreamableHandleタイプのポインタ="Handleを返します.同期ロード内部は実は非同期ロードであり、FStreamableHandle::WaitUntilComplete()ブロック待ちを呼び出す.
RequestSyncLoad関数の内部では、非同期ロードが行われ、WaitUntilComplete関数が呼び出されるか、LoadObject関数が直接呼び出されます.どちらが速いかは、どちらを調整します.
非同期ロード
API
非同期ロードの終了は、ロードされたコールバック関数を使用してロードされたリソースオブジェクトポインタを得るコールバック関数を設定することもできます.
現在、非同期ロードはUserWidgetリソースをロードするために使用できません.
青写真ロード
StreamManagerで青写真をロードする場合、デフォルトのパスは使用できません(接尾辞に_Cが付いていても)、ロードされたClassは使用できません.空ではありませんが.正しい方法:接頭辞はClassで統一され、接尾辞に_Cが追加されます.
FStreamableManager& AssetLoader = UAssetManager::GetStreamableManager();
UClass* WidgetClass = AssetLoader.LoadSynchronous(FSoftObjectPath("Class'/Game/TopDownCPP/Blueprints/NewWidgetBlueprint.NewWidgetBlueprint_C'"));
if (WidgetClass)
{
UUserWidget* Widget = CreateWidget(this, WidgetClass);
if (Widget)
{
Widget->AddToViewport();
}
}
じどうかいしゅう
上記の方法でリソースをロードすると、オブジェクトが参照を失うと自動的に解放され、非同期ロードの場合、オブジェクトはコールバック関数でのみ有効になり、コールバック関数の実行が完了すると回収可能とマークされます.では、非同期ロードされたリソースをどのように保存しますか?
プロジェクトには、コールバックでロードされたオブジェクトが保存されていないのではなく、非同期リソースロードが保存されているHandleが表示され、Handleによって取得されたGetLoadedAssetsによってロードされたオブジェクトが取得されます.オブジェクトプールに保存してからHandleを解放します.
手動回収
リソースをロードするときにbManageActiveHandleがtrueに設定されている場合、オブジェクトは手動で解放されるまでメモリを常駐させます.
FStreamableManager& AssetLoader = UAssetManager::GetStreamableManager();
UParticleSystem* AimObj = AssetLoader.LoadSynchronous(FSoftObjectPath(AssetPath), true);
オブジェクトが不要な場合は、unloadを手動で実行します.
FStreamableManager& AssetLoader = UAssetManager::GetStreamableManager();
AssetLoader.Unload(FSoftObjectPath(AssetPath));
エディタモードでは、上記の2つの方法は有効になりません.パッケージバージョンのみです.エディタモードでDestroyまたはMarkPendingKill()を強制すると、オブジェクトはメモリから破棄できますが、エディタを再起動しない限り、再度ロードすることはできません(検証待ち)
に注意
参照先:
https://zhuanlan.zhihu.com/p/33303645
https://blog.csdn.net/qq_29523119/article/details/84929384
プロジェクト関連のコード