TSoftObjectPtr
IsValid() true 说明在内存中可以直接 调用Get()方法 或者指针
如果IsValid() = false 就需要资源加载,有异步加载和同步加载
以下是案例
auto Iter = ShouldLoadSkills.CreateConstIterator();
FStreamableManager& Manager = UAssetManager::GetStreamableManager();
for (; Iter; ++Iter)
{
FString ContextString;
FName EnumName = UCustomFuncLib_ForWobbo::EnumToFNameCus(TEXT("EWobboSkills"), Iter->Value);
if(FSkillStruct* TablePtr = SkillTable->FindRow<FSkillStruct>(EnumName, ContextString))
{
auto Load = [this, Iter](FSoftObjectPath Path) {
TSoftObjectPtr PathPtr(Path);
if (USkillDataBase_ForWobbo* SkillParam = Cast<USkillDataBase_ForWobbo>(PathPtr.Get()))
{
if (!SkillRecordMap.Contains(Iter->Key))
{
SkillRecordMap.Emplace(Iter->Key, SkillParam);
BroadCastCD(0, 0, true);
}
}
};
const FStreamableDelegate& SD = FStreamableDelegate::CreateLambda(Load, TablePtr->SkillPath);
Manager.RequestAsyncLoad(TablePtr->SkillPath, SD);
}
}
FStreamableManager& Manager = UAssetManager::GetStreamableManager();
auto Load = [this](FSoftClassPath Path) {
TSoftClassPtr PathPtr(Path);
PMClass = PathPtr.Get();
};
const FStreamableDelegate& SD = FStreamableDelegate::CreateLambda(Load, PoseMeshPath);
Manager.RequestAsyncLoad(PoseMeshPath, SD);
Handler = UAssetManager::Get().LoadAssetList(PreloadPaths, FStreamableDelegate::CreateLambda([=]()
{
for (FSoftObjectPath Path : PreloadPaths)
{
if(UObject* Load = Path.TryLoad())
{
PreLoadAudio.Preload.Add(Load);
UE_LOG(LogTemp, Log, TEXT("UAudioAsset::Preload. Asset=%s"), *Load->GetName());
}
}
}));
------------------------------------------------------------------
FSoftObjectPath,FSoftClassPath,FSoftObjectPtr,TSoftObjectPtr,TSoftClassPtr ,TSubclassOf
以上都是软引用,不会直接把资源加载到内存中
同步加载和异步加载
同步加载方法:
LoadClass
// Load a class object.
template< class T >
inline UClass* LoadClass( UObject* Outer, const TCHAR* Name, const TCHAR* Filename=nullptr, uint32 LoadFlags=LOAD_None, UPackageMap* Sandbox=nullptr )
{
return StaticLoadClass( T::StaticClass(), Outer, Name, Filename, LoadFlags, Sandbox );
}
LoadObject
// Load an object.
template< class T >
inline T* LoadObject( UObject* Outer, const TCHAR* Name, const TCHAR* Filename=nullptr, uint32 LoadFlags=LOAD_None, UPackageMap* Sandbox=nullptr )
{
return (T*)StaticLoadObject( T::StaticClass(), Outer, Name, Filename, LoadFlags, Sandbox );
}
FStreamableManager的同步加载和异步加载
RequestSyncLoad 同步加载
RequestAsyncLoad 异步加载
---------------------------------------------------------------------------------------------------------------
分类:
hard reference and soft reference
hard reference
1、直接资源引用
比如A类中有此变量
这种写法别人可以在蓝图中直接指定资源。然后在生成A对象的时候直接加载Material资源
2、构造时创建资源
在A类的构造函数中用ConstructorHelpers加载资源。
(ConstructorHelpers先在内存中查找,没有就加载)
UPROPERTY()
class C* x;
MyClass::MyClass(const FObcjectInitializen& ObjectInitializer) : SuCper(ObjectInitializer)
{
static ConstructorHelpers::FObjectFinder<C> c(TEXT("assetPath"));
x = c.Object;
}
soft reference
1、间接资源引用,通过存放资源路径或者资源模板(TSoftObjectPtr),来引用资源。而不是直接存放资源指针。IsPending()方法来判断该资源是否准备好可供访问。
需要手动加载才能用,加载方法有(LoadObject, StaticLoadObject, FStreamingManager),同样也分同步加载和异步加载,一次性同步加载过多资源会引起同帧卡顿。
TSoftClassPtr.同理。
UPROPERTY()
TSoftObjectPtr<B> b;
B* func()
{
if (b.IsPending()) {
const FSoftObjectPath& AssetRef = b.ToStringReference();
b = Cast<B>(Streamble.SynchronousLoad(AssetRef));
}
return b.Get();
}
2、runtime时候加载
以上三种方法都是基于UPROPERTY()
如果A类对象已经创建完了,这个时候再加载资源就是runtime动态加载。
如果已经在内存中,通过FindObject<>()方法获得资源。
如果资源还没加载: LoadObject<>()
不过LoadObject内部已经有了FindObject。