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

如何从三角形数据创建UStaticMesh?程序崩溃求助

问题:创建UStaticMesh时数组越界崩溃

我尝试从三角形数据创建UStaticMesh,运行代码时程序崩溃,报错“Array index out of bounds: 0 from an array of size 0”,恳请各位提供解决建议。

我的代码

UStaticMesh* staticMesh = NewObject<UStaticMesh>();

// Create the static mesh render data
TUniquePtr<FStaticMeshRenderData> renderData = MakeUnique<FStaticMeshRenderData>();
staticMesh->SetRenderData(MoveTemp(renderData));
FStaticMeshLODResources* lODResource = new FStaticMeshLODResources();
staticMesh->GetRenderData()->LODResources.Add(lODResource);

//For vertices
numberItem2 = data["vertices"].size() / 3;
lODResource->VertexBuffers.PositionVertexBuffer.Init(numberItem2);
lODResource->VertexBuffers.StaticMeshVertexBuffer.Init(numberItem2, 1);
lODResource->VertexBuffers.ColorVertexBuffer.Init(numberItem2);
for (size_t j = 0; j < numberItem2; j++)
{
    FVector3f vertex = FVector3f(data["vertices"][j * 3].get<float>(),
    data["vertices"][j * 3 + 1].get<float>(), data["vertices"][j * 3 + 2].get<float>());

        lODResource->VertexBuffers.PositionVertexBuffer.VertexPosition(j) = vertex;
    lODResource->VertexBuffers.StaticMeshVertexBuffer.SetVertexTangents(j, FVector3f::ZeroVector, FVector3f::ZeroVector, FVector3f::ZeroVector);
    lODResource->VertexBuffers.StaticMeshVertexBuffer.SetVertexUV(j, 0, FVector2f(vertex));
    lODResource->VertexBuffers.ColorVertexBuffer.VertexColor(j) = FColor::White;
}

//For triangle
numberItem2 = data["triangles"].size();
TArray<uint32> indexBuffer;
indexBuffer.SetNum(numberItem2);
for (size_t j = 0; j < numberItem2; j++) {
    indexBuffer[j] = data["triangles"][j].get<uint32>();
}
lODResource->IndexBuffer.SetIndices(indexBuffer, EIndexBufferStride::Type::AutoDetect);

FStaticMeshSourceModel& SourceModel = staticMesh->AddSourceModel();
/*SourceModel.BuildSettings.bRecomputeNormals = true;
SourceModel.BuildSettings.bRecomputeTangents = true;
SourceModel.BuildSettings.bRemoveDegenerates = true;*/
//SourceModel.BuildSettings.bBuildReversedIndexBuffer = true;
/*SourceModel.BuildSettings.bUseFullPrecisionUVs = true;
SourceModel.BuildSettings.bGenerateLightmapUVs = true;
SourceModel.BuildSettings.SrcLightmapIndex = 0;
SourceModel.BuildSettings.DstLightmapIndex = 0;*/

staticMesh->PostEditChange();
staticMesh->MarkPackageDirty();
staticMesh->Build(false);

解决建议

1. 先校验输入数据的有效性

崩溃的直接原因是访问了空数组的索引,首先要确保data["vertices"]和data["triangles"]不为空且格式正确:

  • 在处理顶点前添加判断:
    if (data["vertices"].empty() || data["vertices"].size() % 3 != 0)
    {
        UE_LOG(LogTemp, Error, TEXT("顶点数据为空或数量不是3的倍数"));
        return nullptr;
    }
    
  • 在处理三角形索引前添加判断:
    if (data["triangles"].empty() || data["triangles"].size() % 3 != 0)
    {
        UE_LOG(LogTemp, Error, TEXT("三角形索引数据为空或数量不是3的倍数"));
        return nullptr;
    }
    

2. 修正LOD资源的创建方式

手动new FStaticMeshLODResources并添加到数组的方式容易导致未初始化的资源问题,改用引擎提供的安全方法:

// 替换原来的LOD创建代码
FStaticMeshLODResources& LODResource = staticMesh->GetRenderData()->LODResources.AddDefaulted();

AddDefaulted()会自动创建并初始化一个FStaticMeshLODResources实例,避免手动管理内存的风险。

3. 确保数组操作的安全性

在循环访问data["vertices"]和data["triangles"]的元素时,添加断言确保索引不越界:

// 顶点循环内加断言
check(j*3 +2 < data["vertices"].size());
// 三角形索引循环内加断言
check(j < data["triangles"].size());

开发模式下断言会触发报错,帮助快速定位数据异常的位置。

4. 启用必要的构建设置

注释掉的SourceModel构建建议开启,尤其是法线和切线重计算,否则静态网格可能无法正确渲染:

SourceModel.BuildSettings.bRecomputeNormals = true;
SourceModel.BuildSettings.bRecomputeTangents = true;
SourceModel.BuildSettings.bRemoveDegenerates = true;
SourceModel.BuildSettings.bGenerateLightmapUVs = true;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 06:37:52