You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UE4 C++ TMap中存储的FActorSpawnParameters.Template调用GetOwner返回空

问题原因分析
  • 核心原因为UObject引用未被UE垃圾回收(GC)系统识别,导致对象被意外回收:
    你将FActorSpawnParameters存储在非UObject类型的FInventoryTupleKey结构体中,且该结构体通过普通C++智能指针TSharedPtr包装,结构体内部的Template、Owner等UObject指针成员没有被标记为UPROPERTY,UE的GC扫描时无法识别到这些指针还在引用对应的UObject。一旦对应的Actor没有其他被GC识别的引用持有,就会被GC回收,导致访问时指针失效,GetOwner()自然返回空值。
  • 验证方法:你可以在存入参数和遍历读取的位置分别打印SpawnParams.Template的指针地址,确认两次访问的指针是否一致,如果后续指针变为0x0,即可确定是GC回收导致的问题。
修复方案
  1. 首选方案:调整存储结构,让UObject引用被GC正确识别
    将FInventoryTupleKey改为继承自UObject的类型,内部涉及UObject的成员标记为UPROPERTY(),这样GC扫描时会保留对应的对象引用,不会被意外回收,同时废弃TSharedPtr,直接使用UE的对象指针管理生命周期。
    示例修改参考:
UCLASS()
class UInventoryTupleKey : public UObject
{
    GENERATED_BODY()
public:
    UPROPERTY()
    FActorSpawnParameters ActorSpawnParams;
    int32 Count; // 你的其他自定义成员
};

对应的TMap定义修改为:

UPROPERTY()
TMap< TSubclassOf<class ACollectable>, UInventoryTupleKey* > InventoryElements;
  1. 临时方案:手动添加根引用避免GC回收
    如果不想修改原有结构体定义,可以在存入TMap时给需要保留的UObject手动添加根引用:
SpawnParams.Template->AddToRoot();

在对应元素从TMap中移除、不再需要时调用SpawnParams.Template->RemoveFromRoot()释放引用即可。该方案需要手动管理生命周期,处理不当容易出现内存泄漏,仅推荐临时调试使用。
3. 额外优化建议:FActorSpawnParameters本身是用于生成Actor的临时参数结构,并不适合长期存储,你可以直接拆分存储模板Actor、Owner、生成碰撞规则等你实际需要的字段,不需要完整存储整个FActorSpawnParameters结构,避免引入不必要的问题。

内容的提问来源于stack exchange,提问作者محمد خير الخلق

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 20:12:01