UE4-FindObject & LoadObject

本文介绍了UE4中动态加载UObject和UClass的方法,包括LoadObject<T>()和LoadClass<T>()。FindObject<>适用于资源已加载的情况,而LoadObject<>用于资源尚未加载。通过StaticFindObject()和StaticLoadObject()的详细对比,理解在游戏开发中如何正确地在运行时加载资源。

[UE4]C++实现动态(Runtime)加载的问题:LoadClass<T>()和LoadObject<T>() - 知乎

动态加载UObject和动态加载UClass分别用LoadObject<T>(),和LoadClass<T>() ,两者均在在UObjectGlobals.h中。

FindObject和LoadObject有什么区别?UE4引用资源小结 - 知乎

如果资源已经加载完毕: FindObject<>()

如果资源还没加载: LoadObject<>()

//UObjectGlobals.h
/**
 * Find an optional object.
 * @see StaticFindObject()
 */
template< class T > 
inline T* FindObject( UObject* Outer, const TCHAR* Name, bool ExactClass=false )
{
	return (T*)StaticFindObject( T::StaticClass(), Outer, Name, ExactClass );
}

/** 
 * Load an object. 
 * @see StaticLoadObject()
 */
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 );
}

&lt;think&gt; 在虚幻引擎中,`FindObject` 是一个用于在运行时查找 UObject 的全局函数。它通常在引擎源码和游戏代码中使用,用于根据对象路径查找对象。以下是 `FindObject` 函数的详细参数说明: ### FindObject 函数签名 ```cpp template&lt;typename T&gt; T* FindObject( UObject* Outer, const TCHAR* Name, bool ExactClass = false ); ``` ### 参数详解 1. **Outer (UObject*)** - 要搜索的对象的外部对象(即包或外部对象) - 如果为 `nullptr`,则在整个全局对象范围搜索 - 通常指定为特定包,如 `FindObject&lt;UTexture&gt;(SomePackage, ...)` 2. **Name (const TCHAR*)** - 要查找的对象名称(字符串) - 区分大小写 - 可以是完整路径名(如 &quot;Game/Textures/MyTexture&quot;) 3. **ExactClass (bool)** - 是否要求精确匹配类(默认为 `false`) - 如果为 `true`,则只返回与模板参数 `T` 完全相同的类 - 如果为 `false`,则允许返回 `T` 的子类对象 ### 使用示例 #### 示例1:查找材质资源 ```cpp // 查找位于 /Game/Materials 目录下的名为 &quot;M_Water&quot; 的材质 UMaterial* WaterMaterial = FindObject&lt;UMaterial&gt;( nullptr, TEXT(&quot;/Game/Materials/M_Water&quot;), true // 精确匹配UMaterial类 ); if (WaterMaterial) { UE_LOG(LogTemp, Log, TEXT(&quot;找到材质: %s&quot;), *WaterMaterial-&gt;GetName()); } ``` #### 示例2:在特定包中查找纹理 ```cpp // 加载包(通常在加载后查找) UPackage* MyPackage = LoadPackage(nullptr, TEXT(&quot;/Game/Textures&quot;), LOAD_None); // 在包中查找纹理 UTexture* MyTexture = FindObject&lt;UTexture&gt;( MyPackage, TEXT(&quot;T_Grass&quot;), false // 允许子类(如 UTexture2D) ); ``` ### 重要注意事项 1. **对象必须已加载** `FindObject` 只能查找当前已加载到内存中的对象,不会触发异步加载。 2. **性能考虑** 在大型项目中,全局查找(Outer=nullptr)可能较慢,应尽量避免在性能敏感区域使用。 3. **替代方案** - 对于蓝图生成的对象,考虑使用标记或保存引用 - 对于资产,使用 `FSoftObjectPath` 和异步加载 - 编辑器工具可使用 `ObjectTools::FindObjects()` 等编辑器专用方法 4. **名称冲突** 如果存在同名对象,返回的对象可能不是预期的,建议使用完整路径名。 ### 相关函数 - `StaticFindObject()`:底层实现函数,不检查加载状态 - `FindObjectChecked()`:查找失败时触发断言 - `LoadObject()`:查找失败时尝试加载资产 &sect;&sect;相关问题&sect;&sect;: 1. 虚幻引擎中 `FindObject` 和 `LoadObject` 的区别是什么? 2. 如何在虚幻引擎中使用异步方式加载资源? 3. 如何在 C++ 中获取蓝图生成的对象实例? 4. `FSoftObjectPath` 和 `TSoftObjectPtr` 的用法有哪些? &lt;/think&gt; 在虚幻引擎 C++ 中,`FindObject` 是一个用于在运行时查找已加载对象的全局函数。它主要用于在内存中查找已加载的 UObject 及其派生类对象。以下是 `FindObject` 函数的详细参数说明: ### FindObject 函数签名 ```cpp template&lt;typename T&gt; T* FindObject( UObject* Outer, const TCHAR* NameOrPath, bool ExactClass = false ); ``` ### 参数详解 1. **Outer (UObject*)** - 对象的父对象(包或外部对象) - 通常为包含对象的包(Package) - 可以为 `nullptr` 表示全局查找 - 示例:`FindObject&lt;UWorld&gt;(GetTransientPackage(), ...)` 2. **NameOrPath (const TCHAR*)** - 要查找的对象名称或完整路径 - 如果是名称,则只在该 Outer 范围内查找 - 如果是路径,格式为 `/Path/To/Package.ObjectName` - 示例:`TEXT(&quot;/Game/Blueprints/MyCharacter&quot;)` 3. **ExactClass (bool - 可选参数,默认 false)** - 是否要求精确匹配类(不包括子类) - `false`:返回匹配类或其派生类的对象 - `true`:仅返回精确匹配类的对象 - 示例:`FindObject&lt;AActor&gt;(..., true)` 只返回 AActor 实例,不包括派生类 ### 使用示例 #### 示例1:按路径查找对象 ```cpp // 查找蓝图资源 UBlueprint* MyBlueprint = FindObject&lt;UBlueprint&gt;( nullptr, // 全局查找 TEXT(&quot;/Game/Blueprints/BP_Character&quot;), // 完整资源路径 true // 精确匹配UBlueprint类 ); if (MyBlueprint) { UE_LOG(LogTemp, Warning, TEXT(&quot;找到蓝图: %s&quot;), *MyBlueprint-&gt;GetName()); } ``` #### 示例2:在特定包中查找对象 ```cpp // 获取游戏内容包 UPackage* GameContent = FindPackage(nullptr, TEXT(&quot;/Game&quot;)); // 在指定包中查找材质 UMaterial* WaterMaterial = FindObject&lt;UMaterial&gt;( GameContent, // 指定查找范围 TEXT(&quot;M_Water&quot;), // 对象名称(非完整路径) false // 允许子类(如 UMaterialInstance) ); ``` #### 示例3:查找已加载的关卡 ```cpp // 查找已加载的关卡对象 UWorld* World = GWorld; ULevelStreaming* StreamingLevel = FindObject&lt;ULevelStreaming&gt;( World, TEXT(&quot;PersistentLevel&quot;), false ); ``` ### 重要注意事项 1. **对象必须已加载** `FindObject` 只能查找已加载到内存的对象,不会触发异步加载 2. **使用 LoadObject 加载资源** 如果需要加载磁盘资源,应使用 `LoadObject` 或 `LoadClass` 函数: ```cpp UStaticMesh* Mesh = LoadObject&lt;UStaticMesh&gt;( nullptr, TEXT(&quot;/Game/Meshes/SM_Rock&quot;) ); ``` 3. **性能考虑** 在大规模场景中频繁使用全局查找(Outer=nullptr)可能影响性能 4. **替代方案** 对于更安全的查找: - 使用 `FindObjectWithOuter` 在特定 Outer 内查找 - 使用 `StaticFindObject` 进行底层查找 - 使用 `TSoftObjectPtr` 进行软引用
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值