UE4 C++ 从RenderTarget创建独立Texture2D解决同指针内容重复问题
问题根因
- 每次调用
ConstructTexture2D时传入的纹理名称固定为"Test",UE的UObject管理机制会对同Outer、同名称的对象直接复用已有实例,导致你每次调用接口拿到的都是同一个Texture2D指针,后续RenderTarget的内容更新会直接覆盖该纹理的内存数据,所以数组内所有元素显示内容完全一致。 - 生成的Texture2D未设置独立的生命周期标记,容易被UE的GC自动回收,也可能出现内容被意外覆盖的问题。
解决方案
代码修改
头文件(ScreenShotToTexture.h)调整
删掉不必要的成员变量Picture,避免每次调用覆盖同一个成员引用:
// 移除以下两行代码即可 // UPROPERTY(EditAnywhere) // UTexture2D* Picture;
实现文件(ScreenShotToTexture.cpp)修改TakePic函数
UTexture2D* UScreenShotToTexture::TakePic() { if(RenderTarget == nullptr) { UE_LOG(LogTemp, Error, TEXT("No RenderTarget set.")); return nullptr; } // 生成唯一的纹理名称,避免对象复用,也可以用FGuid::NewGuid().ToString()生成全局唯一名称 static uint32 TextureIndex = 0; FString UniqueTextureName = FString::Printf(TEXT("CapturedTexture_%d"), TextureIndex++); // 创建新的Texture2D,添加RF_Standalone标记避免被GC自动回收 UTexture2D* NewTexture = RenderTarget->ConstructTexture2D(this, *UniqueTextureName, RF_Public | RF_Standalone, CTF_Default); return NewTexture; }
补充说明
- 如果你需要将纹理永久存储为本地工程资源,可以调用
UPackage::SavePackage相关接口把生成的Texture2D保存为uasset文件,运行时生成的纹理默认只存在于内存中,退出游戏就会丢失。 - 蓝图侧直接把每次调用
TakePic返回的纹理添加到数组即可,不要复用同一个变量存储返回值。 - 如果后续不需要再使用数组中的纹理,记得调用
NewTexture->ClearFlags(RF_Standalone),避免纹理一直占用内存无法被GC回收。
内容的提问来源于stack exchange,提问作者Mad_Jackal
相关产品推荐
相关产品推荐

