Unity导出兼容SketchUp的3D模型方案及OBJ材质缺失解决
解决Unity导出OBJ带材质兼容SketchUp的问题
你遇到的核心问题是SketchUp对OBJ/MTL格式的解析有特定要求,当前脚本生成的MTL文件在颜色格式、材质属性上不完全匹配SketchUp的预期,同时纹理导出逻辑未实现。以下是具体的修复方案:
一、修复MTL文件的材质颜色输出
SketchUp对MTL中的RGB颜色值解析更倾向于0-255的整数格式,且需要明确的环境光颜色(Ka)才能正确识别材质颜色。修改MaterialToString方法:
string MaterialToString(Material m) { StringBuilder sb = new StringBuilder(); sb.AppendLine("newmtl " + m.name); // 处理基础颜色(适配SketchUp解析规则) if (m.HasProperty("_BaseColor")) { Color baseColor = m.GetColor("_BaseColor"); // 转换为0-255整数格式,避免浮点精度问题 int r = Mathf.RoundToInt(baseColor.r * 255); int g = Mathf.RoundToInt(baseColor.g * 255); int b = Mathf.RoundToInt(baseColor.b * 255); // 漫反射颜色(Kd) sb.AppendLine($"Kd {r} {g} {b}"); // 环境光颜色(Ka),SketchUp必须读取这个值才能正确显示颜色 sb.AppendLine($"Ka {r} {g} {b}"); // 透明度处理,SketchUp优先识别Tr(1-不透明度) if (baseColor.a < 1.0f) { sb.AppendLine($"Tr {1f - baseColor.a:F6}"); } } // 光照模型:illum 2对应带高光的漫反射,符合SketchUp默认材质逻辑 sb.AppendLine("illum 2"); // 高光系数(Ns),控制SketchUp中材质的高光强度 sb.AppendLine("Ns 100.0"); // 导出纹理(如果开启选项) if (exportTextures) { string texturePath = TryExportTexture("_BaseMap", m); if (!string.IsNullOrEmpty(texturePath)) { sb.AppendLine($"map_Kd {texturePath}"); } } return sb.ToString(); }
二、实现纹理导出逻辑
当前脚本的TryExportTexture方法为空,需要补充代码将Unity中的纹理文件复制到导出目录,确保SketchUp能找到:
string TryExportTexture(string propertyName, Material m) { if (!m.HasProperty(propertyName)) return null; Texture2D texture = m.GetTexture(propertyName) as Texture2D; if (texture == null) return null; // 自动设置纹理为可读(如果开启选项) if (autoMarkTexReadable) { var textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture)) as TextureImporter; if (textureImporter != null && !textureImporter.isReadable) { textureImporter.isReadable = true; textureImporter.SaveAndReimport(); } } // 跳过不可读的纹理 if (!texture.isReadable) return null; // 纹理导出路径:与OBJ文件同目录 string textureFileName = System.IO.Path.GetFileName(AssetDatabase.GetAssetPath(texture)); string exportTexturePath = System.IO.Path.Combine(lastExportFolder, textureFileName); // 复制纹理文件到导出目录 string sourcePath = Application.dataPath + "/" + AssetDatabase.GetAssetPath(texture).Substring(7); if (System.IO.File.Exists(sourcePath)) { System.IO.File.Copy(sourcePath, exportTexturePath, true); // 返回相对路径,SketchUp能正确识别 return textureFileName; } return null; }
三、修复MTL文件路径的跨平台问题
修改Export方法中MTL文件的写入代码,用Path.Combine避免Windows/Linux路径分隔符冲突:
// 替换原MTL写入代码 string mtlPath = System.IO.Path.Combine(exportFileInfo.Directory.FullName, baseFileName + ".mtl"); System.IO.File.WriteAllText(mtlPath, sbMaterials.ToString());
四、SketchUp导入时的关键设置
导入OBJ文件时,在SketchUp的导入窗口中必须勾选:
- 「导入材质」
- 「使用纹理图像」
- 若模型有透明部分,勾选「导入透明度」
五、额外注意事项
- Unity中使用的材质需为基础Shader(如URP Lit、Standard),复杂Shader的特殊属性SketchUp无法识别
- 导出前检查模型UV是否正确,无UV的模型无法显示纹理
- 批量导出时建议关闭
splitObjects选项,避免生成过多组,SketchUp处理更顺畅
内容的提问来源于stack exchange,提问作者Axay Gadhiya
相关产品推荐
相关产品推荐

