ue的资源管理

一、资源加载

1、同步加载
注意:加载蓝图时,要使用_C路径,否则加载不出来

{
    1、
    UAnimSequence* obj = AssetLoader.LoadSynchronous<UAnimSequence>(FSoftObjectPath(TEXT("/Game/Assets/TestObj.TestObj")));
    // 加载完成之后

    2、
    TSharedPtr<FStreamableHandle> Handle = AssetLoader.RequestSyncLoad(FSoftObjectPath(TEXT("/Game/Assets/TestObj.TestObj")));
    if (Handle.IsValid())
    {
        UAnimSequence* obj = Cast<UAnimSequence>(Handle->GetLoadedAsset());
        // 加载完成之后
    }
}

2、异步加载
异步加载中的回调函数是按顺序执行的

.h
{
    UPROPERTY()
    TArray<FSoftObjectPath> TestAssets;
}
.cpp
void AAssetLoadObj::BeginPlay()
{
    Super::BeginPlay();
    FStreamableManager& AssetLoader = UAssetManager::GetStreamableManager();
    AssetLoader.RequestAsyncLoad(TestAssets, FStreamableDelegate::CreateUObject(this, &AAssetLoadObj::AssetLoadCallback));
}

void AAssetLoadObj::AssetLoadCallback()
{
    for (FSoftObjectPath ArrayElem: TestAssets)
    {
        TAssetPtr<UAnimSequence> AnimAsset(ArrayElem);
        UAnimSequence* Obj= AnimAsset.Get();
        if (Obj)
        {
            // 加载完成之后
        }
    }
}

LoadSynchronous和RequestSyncLoad时对异步加载的封装,调用FStreamableHandle::WaitUntilComplete()阻塞等待

二、资源释放

1、自动回收:当对象失去引用之后会被自动释放,异步加载时,对象会在回调函数中标记为可回收

2、手动回收:

a、将bManageActiveHandle标记为true(默认为false),当不使用时执行Unload,将手动回收变为自动回收

{
    FStreamableManager& AssetLoader = UAssetManager::GetStreamableManager();
    UParticleSystem* AimObj = AssetLoader.LoadSynchronous<UParticleSystem>(FSoftObjectPath(AssetPath), true);

    AssetLoader.Unload(FSoftObjectPath(AssetPath));
}

b、ForceGC立即回收

{
    GEngine->ForceGarbageCollection(true);
}

三、防止GC

1、成员变量可添加UPROPERTY()修饰,若不需要时,可以将变量设为NULL

2、创建对象之后,将对象变为顶部节点AddToRoot(),游戏结束时使用RemoveFromRoot()释放

3、FStreamableManger Load资源时,bManageActiveHandle设为true

4、FGCObjectScopeGuard在指定代码区域内保持对象

{
    FGCObjectScopeGuard(UObject* GladOS = NewObject<...>(...));
    GladOS->SpawnCell();
    RunGC();
    GladOS->IsStillAlive();   // Object will not be removed by GC
}

5、在蓝图中用一个变量引用住(升级为变量),只有将改变量置为空才会被GC掉

注意:Uobject不能使用TSharedPtr进行引用计数,如果一个非UObject的类想加入GC,那么必须继承FGCObject类。

posted @ 2026-02-10 17:05  DarkShadow  阅读(1)  评论(0)    收藏  举报