【UE 4のリソースロードとリリース】

6117 ワード

リソースロードといえば、まずUEのリソースへの参照について述べる.
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があります
  • FStreamableManager::LoadSynchronous
  • FStreamableManager::RequestSyncLoad

  • 読み込みは、FStreamableHandleタイプのポインタ="Handleを返します.同期ロード内部は実は非同期ロードであり、FStreamableHandle::WaitUntilComplete()ブロック待ちを呼び出す.
    RequestSyncLoad関数の内部では、非同期ロードが行われ、WaitUntilComplete関数が呼び出されるか、LoadObject関数が直接呼び出されます.どちらが速いかは、どちらを調整します.
    非同期ロード
    API
  • FStreamableManager::RequestAsyncLoad

  • 非同期ロードの終了は、ロードされたコールバック関数を使用してロードされたリソースオブジェクトポインタを得るコールバック関数を設定することもできます.
    現在、非同期ロードは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()を強制すると、オブジェクトはメモリから破棄できますが、エディタを再起動しない限り、再度ロードすることはできません(検証待ち)
    に注意
  • 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
    プロジェクト関連のコード