如何从三角形数据创建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
相关产品推荐
相关产品推荐

