Unity SolidGeometryLib初始化sgObject时空指针异常求助
问题:SolidGeometryLib自定义OBJ网格初始化空指针异常
我从Unity Asset Store购买了SolidGeometryLib插件用于项目中的网格布尔运算,尝试用加载自定义.obj文件的GameObject初始化sgObject时触发空指针异常,以下是我的实现代码:
void initGameObjectAsSGObject() { GameObject skullGameObject = GameObject.Find("Skull"); Mesh mesh = skullGameObject.GetComponent<MeshFilter>().mesh; var verts = mesh.vertices; float[] vertices = new float[verts.Length * 3]; Debug.Log(verts[0].x); foreach (Vector3 vertex in verts) { vertices.Append(vertex.x); vertices.Append(vertex.y); vertices.Append(vertex.z); } int[] triangles = mesh.triangles; Debug.Log(triangles[10]); // Skull IntPtr pnts = sg_array_create_points(); for (int i = 0; i < vertices.Length; i += 3) sg_array_add_point(pnts, vertices[i], vertices[i + 1], vertices[i + 2]); IntPtr indxs = sg_array_create_int(); for (int i = 0; i < triangles.Length; i++) sg_array_add_int(indxs, triangles[i]); IntPtr customMeshObj = sg_object_custom_mesh(pnts, indxs); Debug.Log(customMeshObj); if (customMeshObj == IntPtr.Zero) { Debug.Log("customMeshObj is null"); return; } skullGameObject.AddComponent<sgObject>().InitObject(customMeshObj); skullGameObject.transform.parent = gameObject.transform; sg_array_free_points(pnts); sg_array_free_int(indxs); }
插件卖家提供的自定义网格创建示例代码:
public void AddCustomMesh() { float[] vertexes = { 0.0f, 0.0f, 2.0f, // v1 1.788854f, 0.000000f, 0.894427f, // v2 0.552786f, 1.701302f, 0.894427f, // v3 -1.447214f, 1.051462f, 0.894427f, // v4 -1.447214f, -1.051462f, 0.894427f, // v5 0.552786f, -1.701302f, 0.894427f, // v6 1.447214f, 1.051462f, -0.894427f, // v7 -0.552786f, 1.701302f ,-0.894427f, // v8 -1.788854f, 0.000000f, -0.894427f, // v9 -0.552786f, -1.701302f, -0.894427f, // v10 1.447214f, -1.051462f, -0.894427f, // v11 0.0f, 0.0f, -2.0f }; // v12 int[] icosahedron_indexes = { 2, 0, 1, // triangle 1 3, 0, 2, // triangle 2 4, 0, 3, // triangle 3 5, 0, 4, // triangle 4 1, 0, 5, // triangle 5 2, 1, 6, // triangle 6 7, 2, 6, // triangle 7 3, 2, 7, // triangle 8 8, 3, 7, // triangle 9 4, 3, 8, // triangle 10 9, 4, 8, // triangle 11 5, 4, 9, // triangle 12 10, 5, 9, // triangle 13 6, 1, 10, // triangle 14 1, 5, 10, // triangle 15 6, 11, 7, // triangle 16 7, 11, 8, // triangle 17 8, 11, 9, // triangle 18 9, 11, 10, // triangle 19 10, 11, 6 // triangle 20 }; GameObject cmO = new GameObject("CustomMesh"); float randRad = UnityEngine.Random.Range(0.9f, 3.5f); IntPtr pnts = sg_array_create_points(); for (int i = 0; i < vertexes.Length; i += 3) sg_array_add_point(pnts, vertexes[i] * randRad, vertexes[i + 1] * randRad, vertexes[i + 2] * randRad); IntPtr indxs = sg_array_create_int(); for (int i = 0; i < icosahedron_indexes.Length; i++) sg_array_add_int(indxs, icosahedron_indexes[i]); IntPtr customMeshObj = sg_object_custom_mesh(pnts, indxs); sg_array_free_points(pnts); sg_array_free_int(indxs); if (customMeshObj == IntPtr.Zero) { DestroyImmediate(cmO); return; } randomTransform(customMeshObj); cmO.AddComponent<sgObject>().InitObject(customMeshObj); cmO.transform.parent = gameObject.transform; }
错误排查与修复
核心错误点
顶点数组填充逻辑错误
你使用vertices.Append(vertex.x)填充数组,但Append方法不会修改原数组,而是返回一个包含新增元素的新数组,导致vertices始终是初始的全0数组。插件接收无效的顶点数据后无法生成有效网格,最终customMeshObj为IntPtr.Zero,后续调用InitObject触发空指针。缺少空值检查
未对skullGameObject、MeshFilter、mesh、triangles做空值判断,若GameObject找不到、缺少组件或网格数据为空,直接访问会触发空指针。资源释放不完整
当customMeshObj为空时,未释放已创建的pnts和indxs数组,会造成内存泄漏。
修正后的代码
void initGameObjectAsSGObject() { // 检查目标GameObject是否存在 GameObject skullGameObject = GameObject.Find("Skull"); if (skullGameObject == null) { Debug.LogError("找不到名为Skull的GameObject"); return; } // 检查MeshFilter组件及Mesh是否有效 MeshFilter meshFilter = skullGameObject.GetComponent<MeshFilter>(); if (meshFilter == null || meshFilter.mesh == null) { Debug.LogError("Skull GameObject缺少MeshFilter组件或Mesh为空"); return; } Mesh mesh = meshFilter.mesh; var verts = mesh.vertices; float[] vertices = new float[verts.Length * 3]; // 正确填充顶点数组:通过索引直接赋值 for (int i = 0; i < verts.Length; i++) { Vector3 vertex = verts[i]; vertices[i * 3] = vertex.x; vertices[i * 3 + 1] = vertex.y; vertices[i * 3 + 2] = vertex.z; } // 检查三角形索引是否有效 int[] triangles = mesh.triangles; if (triangles == null || triangles.Length == 0) { Debug.LogError("Mesh的三角形索引数组为空"); return; } IntPtr pnts = sg_array_create_points(); for (int i = 0; i < vertices.Length; i += 3) sg_array_add_point(pnts, vertices[i], vertices[i + 1], vertices[i + 2]); IntPtr indxs = sg_array_create_int(); for (int i = 0; i < triangles.Length; i++) sg_array_add_int(indxs, triangles[i]); IntPtr customMeshObj = sg_object_custom_mesh(pnts, indxs); Debug.Log(customMeshObj); if (customMeshObj == IntPtr.Zero) { Debug.Log("customMeshObj is null"); // 释放已创建的资源,避免内存泄漏 sg_array_free_points(pnts); sg_array_free_int(indxs); return; } skullGameObject.AddComponent<sgObject>().InitObject(customMeshObj); skullGameObject.transform.parent = gameObject.transform; sg_array_free_points(pnts); sg_array_free_int(indxs); }
额外注意事项
- 若OBJ模型的顶点是世界空间坐标,需转换为GameObject的局部空间坐标(Unity的
Mesh.vertices默认是局部空间),否则可能导致网格位置异常。 - 确保OBJ模型的三角形索引是顺时针顺序,部分布尔运算插件对三角面的 winding order 有要求。
内容的提问来源于stack exchange,提问作者Runnan
相关产品推荐
相关产品推荐

