Unity运行时使用C#脚本导出GameObject为FBX/OBJ格式的方案咨询
Unity房间编辑器导出3D文件解决方案
可用工具推荐
- 官方FBX Exporter包:Unity官方维护的导出组件,支持直接选中Hierarchy中的任意父节点(即你的Room节点),批量导出所有子节点内容为标准FBX格式,导出结果兼容Blender及所有主流3D查看工具,可通过参数配置关闭纹理导出,完全匹配你的需求。
- 轻量OBJ导出脚本:如果仅需要OBJ格式,可以直接用社区成熟的OBJ导出工具类,无额外依赖,引入到项目中即可直接调用API导出指定节点下的所有模型数据。
手动实现思路(无第三方依赖场景)
如果不想引入额外工具包,优先选择自定义实现OBJ导出,OBJ为纯文本格式,规则简单,开发成本极低:
- 遍历Room父节点下的所有子物体,筛选出挂载了
MeshFilter组件的可渲染对象 - 对每个Mesh的顶点坐标做空间转换,将本地坐标转换为统一的世界坐标系坐标,同步收集顶点、法线、三角面的对应数据
- 按照OBJ格式的标准语法,用
StreamWriter逐行写入数据即可,你之前用StreamWriter导出失败通常是坐标转换逻辑错误、或者OBJ格式语法不符合规范导致的。
FBX属于闭源二进制格式,不推荐手动编码实现,优先用官方封装好的工具组件即可。
简单代码示例(OBJ导出核心逻辑)
// 传入Room根节点和保存路径即可调用 public void ExportRoomObj(Transform roomRoot, string savePath) { // 遍历所有子节点收集Mesh数据 List<MeshFilter> meshFilters = new List<MeshFilter>(roomRoot.GetComponentsInChildren<MeshFilter>()); using(StreamWriter sw = new StreamWriter(savePath)) { int vertexOffset = 0; foreach(var mf in meshFilters) { Mesh mesh = mf.sharedMesh; // 写入顶点 foreach(Vector3 v in mesh.vertices) { Vector3 worldV = mf.transform.TransformPoint(v); sw.WriteLine($"v {worldV.x} {worldV.y} {worldV.z}"); } // 写入法线 foreach(Vector3 n in mesh.normals) { Vector3 worldN = mf.transform.TransformDirection(n); sw.WriteLine($"vn {worldN.x} {worldN.y} {worldN.z}"); } // 写入面 foreach(int[] triangles in mesh.subMeshes.Select(sm => sm.GetIndices())) { for(int i=0; i<triangles.Length; i+=3) { int v1 = triangles[i] + vertexOffset + 1; int v2 = triangles[i+1] + vertexOffset + 1; int v3 = triangles[i+2] + vertexOffset + 1; sw.WriteLine($"f {v1}//{v1} {v2}//{v2} {v3}//{v3}"); } } vertexOffset += mesh.vertexCount; } } }
内容的提问来源于stack exchange,提问作者Jacine Yatrakos
相关产品推荐
相关产品推荐

