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

C++更新UTextureRenderTarget2D出现Assertion Failed报错如何解决

报错原因
  • RenderTarget->InitCustomFormat触发的渲染资源初始化是异步操作:游戏线程调用该接口后仅会向渲染线程提交资源创建请求,不会等待渲染线程完成初始化,此时立刻在游戏线程调用GetRenderTargetTexture()大概率会拿到未完成初始化的无效RHI引用。
  • 跨线程捕获RHI引用存在生命周期风险:RHI资源的引用计数管理和生命周期与渲染线程强绑定,在游戏线程获取的FTexture2DRHIRef直接捕获到渲染线程命令的lambda中时,可能出现资源被提前释放、引用失效的问题。
  • 异常参数问题:如果传入的Width/Height数值为0或负数,或者RenderTarget本身是被标记为待销毁的无效对象,也会导致获取的RHI引用为空。
修复方案

核心逻辑是将RHI资源的获取操作移到渲染线程内部执行,同时增加对象生命周期校验,避免空引用问题,修复后代码如下:

void AWorldCreator::BeginPlay()
{
    Super::BeginPlay();
    // 提前做参数合法性校验
    if (RenderTarget == nullptr || Width <= 0 || Height <= 0)
    {
        return;
    }
    RenderTarget->InitCustomFormat(Width, Height, PF_B8G8R8A8, true);

    // 用弱指针捕获RenderTarget,避免渲染线程执行前对象被GC销毁
    TWeakObjectPtr<UTextureRenderTarget2D> WeakRT = RenderTarget;
    const int32 RTWidth = Width;
    const int32 RTHeight = Height;

    ENQUEUE_RENDER_COMMAND(UpdateTextureRegionsData)(
    [WeakRT, RTWidth, RTHeight](FRHICommandListImmediate& RHICmdList)
    {
        // 渲染线程内部依次校验各资源有效性
        UTextureRenderTarget2D* ValidRT = WeakRT.Get();
        if (!ValidRT)
        {
            return;
        }
        FTextureRenderTargetResource* RTResource = ValidRT->GetRenderTargetResource();
        if (!RTResource)
        {
            return;
        }
        FTexture2DRHIRef TextureRHI = RTResource->GetRenderTargetTexture();
        check(TextureRHI.IsValid());
        
        // 后续纹理更新逻辑可在此处编写
    });
}

额外注意事项

  • 如果业务逻辑允许,建议尽量提前初始化RenderTarget(比如在编辑器中预先配置好尺寸,或在构造函数、PostInitializeComponents阶段完成InitCustomFormat调用),避免在BeginPlay中刚完成初始化就立刻操作的时序风险。
  • 你当前已引入的模块依赖是齐全的,无需额外新增模块。

内容的提问来源于stack exchange,提问作者NedCrow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 14:39:02