UnityEditor代码分享导出材质贴图和Mesh本体

运行时可导出

可导出多个材质

导出Mesh_0到Assets/目录下

#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(ComperhenceMeshMonoViewer))]
public class ComperhenceMeshMonoViewerEditor : Editor
{
	public override void OnInspectorGUI()
	{
		base.OnInspectorGUI();

		if (GUILayout.Button("导出 Mesh & Mat"))
        {
			string folderPath = EditorUtility.SaveFolderPanel("", "选择目录", "");
			if (string.IsNullOrEmpty(folderPath)) {
				
				return;
			}
			ComperhenceMeshMonoViewer _target = target as ComperhenceMeshMonoViewer;


			//Material mat = _target.GetComponent<Renderer>().sharedMaterial;
			List<string> lstNameIdentity = new List<string>();
			Material[] mats = _target.GetComponent<Renderer>().sharedMaterials;
			int cursor = 0;
			foreach (var mat in mats)
			{
				var texs = GetCertainMaterialTextures(mat);
				string go_name = _target.gameObject.name;
				foreach (var tex in texs)
				{
					if (tex == null) continue;
					//string saveRelativePath = tex;

					//string frmPath = Application.dataPath + "/../" + saveRelativePath;
					//GameUtility.SafeCopyFile(frmPath, folderPath + "/" + saveRelativePath);
					Texture2D tt = TextureUtils.TextureToTexture2D(tex);
					string tex_name = tex.name;
					if (lstNameIdentity.Contains(tex_name) == false)
					{
						lstNameIdentity.Add(tex_name);
					}
					else
					{
						tex_name = tex.name + "_" + cursor;
					}
					GameUtility.SaveTexture(string.Format("{0}/{1}/{2}.png", folderPath, go_name, tex.name), tt);
					cursor++;
				}


				GameUtility.SaveConfig(string.Format("{0}/{1}/{2}", folderPath, go_name, mat.shader.name), "");
			}
			}
    }

	public Texture[] GetCertainMaterialTextures(Material _mat)
	{
		List<Texture> results = new List<Texture>();

		Shader shader = _mat.shader;
		for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); ++i)
		{
			if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv)
			{
				string propertyName = ShaderUtil.GetPropertyName(shader, i);
				Texture tex = _mat.GetTexture(propertyName);
				//string texPath = AssetDatabase.GetAssetPath(tex.GetInstanceID());
				//results.Add(texPath);
				results.Add(tex);
			}
		}

		return results.ToArray();
	}
}
#endif

(还缺一个 GameUtility 类,保存文件用,之后再补上吧)

Unity中,可以使用以下代码将多个Mesh合并成一个,并导出为.obj格式的模型文件,同时包含其使用的材质贴图: ```csharp // 获取需要合并的所有Mesh MeshFilter[] meshFilters = gameObject.GetComponentsInChildren<MeshFilter>(); // 创建新的Mesh CombineInstance[] combineInstances = new CombineInstance[meshFilters.Length]; for (int i = 0; i < meshFilters.Length; i++) { combineInstances[i].mesh = meshFilters[i].sharedMesh; combineInstances[i].transform = meshFilters[i].transform.localToWorldMatrix; } Mesh newMesh = new Mesh(); newMesh.CombineMeshes(combineInstances); // 创建新的Material Renderer renderer = gameObject.GetComponent<Renderer>(); Material material = renderer.sharedMaterial; // 导出为.obj格式的模型文件 string path = "Assets/NewModel.obj"; ObjExporter.MeshToFile(newMesh, material, path); // 刷新AssetDatabase AssetDatabase.Refresh(); ``` 在上述代码中,首先获取需要合并的所有Mesh,并将其转换为CombineInstance数组。然后创建新的Mesh,使用CombineMeshes方法将CombineInstance数组合并成一个Mesh。接着获取需要导出的Material,并将其保存为一个新的Material。最后使用ObjExporter类中的MeshToFile方法将新的Mesh及其使用的Material和贴图导出为.obj格式的模型文件,并调用AssetDatabase.Refresh方法刷新AssetDatabase。 以下是修改后的ObjExporter类,支持将Mesh及其使用的Material和贴图导出为.obj格式的模型文件: ```csharp using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; public static class ObjExporter { public static void MeshToFile(Mesh mesh, Material material, string path) { StreamWriter sw = new StreamWriter(path); sw.WriteLine("# Unity Mesh"); sw.WriteLine("mtllib " + Path.GetFileNameWithoutExtension(path) + ".mtl"); sw.WriteLine("g default"); for (int i = 0; i < mesh.vertices.Length; i++) { Vector3 v = mesh.vertices[i]; sw.WriteLine(string.Format("v {0} {1} {2}", -v.x, v.y, v.z)); } for (int i = 0; i < mesh.normals.Length; i++) { Vector3 n = mesh.normals[i]; sw.WriteLine(string.Format("vn {0} {1} {2}", -n.x, n.y, n.z)); } for (int i = 0; i < mesh.uv.Length; i++) { Vector2 uv = mesh.uv[i]; sw.WriteLine(string.Format("vt {0} {1}", uv.x, uv.y)); } for (int i = 0; i < mesh.subMeshCount; i++) { int[] triangles = mesh.GetTriangles(i); for (int j = 0; j < triangles.Length; j += 3) { int i1 = triangles[j] + 1; int i2 = triangles[j + 1] + 1; int i3 = triangles[j + 2] + 1; sw.WriteLine(string.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}", i1, i2, i3)); } } sw.Close(); // 导出Material和贴图 string mtlPath = Path.GetDirectoryName(path) + "/" + Path.GetFileNameWithoutExtension(path) + ".mtl"; StreamWriter mtlSw = new StreamWriter(mtlPath); mtlSw.WriteLine("# Unity Material"); mtlSw.WriteLine("newmtl default"); mtlSw.WriteLine(string.Format("map_Kd {0}", Path.GetFileName(material.mainTexture.name))); mtlSw.Close(); string texPath = Path.GetDirectoryName(path) + "/" + material.mainTexture.name; File.Copy(AssetDatabase.GetAssetPath(material.mainTexture), texPath, true); } } ``` 在上述代码中,MeshToFile方法接受一个Mesh、一个Material和一个文件路径作为参数,将Mesh及其使用的Material和贴图导出为.obj格式的模型文件并保存到指定文件路径下。在导出过程中,先将Material和贴图保存到.mtl和对应的文件中,再将Mesh的顶点、法线、UV等信息以及使用的Material的引用保存到.obj文件中。 需要注意的是,上述代码中的StreamWriter类和Path类需要使用System.IO命名空间,因此需要在代码中添加以下语句: ```csharp using System.IO; ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

avi9111

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值