unity编辑器拓展五——将场景中物体以Obj格式导入max
来源:互联网 发布:星之海洋 知乎 编辑:程序博客网 时间:2024/05/21 20:24
描述:
1.在unity中建立一个场景,做完后,有很多需求是将一个完整的场景导入到max里面,这样可以准确的去做行走网格 水面 等各种需要与场景配合的模型
下面这段代码就可以实现unity与max互导
代码如下:
using UnityEngine;using UnityEditor;using System.IO;using System.Text;using System.Collections;using System.Collections.Generic;using UnityEditor.SceneManagement;public class SceneExport : EditorWindow{ struct Model { public Mesh mesh; public Material[] materials; public Transform transform; } struct ModelMaterial { public string name; public float cutoff; public string texture; } class MaterialCompare : EqualityComparer<ModelMaterial> { public override bool Equals(ModelMaterial mtlx, ModelMaterial mtly) { return string.Compare(mtlx.name, mtly.name) == 0; } public override int GetHashCode(ModelMaterial mtl) { return mtl.name.GetHashCode(); } } static SceneExport window; [MenuItem("Game-X/Scene Exporter", false, 101)] public static void Open() { if (window == null) { window = EditorWindow.GetWindow<SceneExport>(false, "SceneExport", true); int initWidth = 300; int initHeight = 150; int x = (Screen.currentResolution.width - initWidth) / 2; int y = (Screen.currentResolution.height - initHeight) / 2; window.position = new Rect(x, y, initWidth, initHeight); } } static float unitsScale; static bool exportMaterial; SceneExport() { unitsScale = 100f; exportMaterial = true; } Texture icon; void Awake() { if (EditorPrefs.HasKey("SceneExportMaterial")) exportMaterial = EditorPrefs.GetBool("SceneExportMaterial"); else exportMaterial = true; if (EditorPrefs.HasKey("SceneExportUnitsScale")) unitsScale = EditorPrefs.GetFloat("SceneExportUnitsScale"); else unitsScale = 100f; icon = AssetDatabase.LoadAssetAtPath( "assets/editor/images/sceneExporter.png", typeof(Texture)) as Texture; } void OnDestroy() { icon = null; window = null; EditorPrefs.SetBool("SceneExportMaterial", exportMaterial); EditorPrefs.SetFloat("SceneExportUnitsScale", unitsScale); } void OnGUI() { EditorGUILayout.BeginVertical(); GUILayout.Space(10f); EditorGUILayout.BeginHorizontal(); exportMaterial = EditorGUILayout.Toggle("Material", exportMaterial); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); unitsScale = EditorGUILayout.FloatField("Units Scale", unitsScale); if (icon) { Rect rc = GUILayoutUtility.GetRect(icon.width, icon.height); rc.x += 6f; rc.y += 6f; rc.width = icon.width; rc.height = icon.height; GUI.DrawTexture(rc, icon); } GUILayout.FlexibleSpace(); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Export", GUILayout.Width(90f))) Export(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } static void Export() { Transform[] objectList = Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab); if (objectList.Length <= 0) { EditorUtility.DisplayDialog("Alert", "No Object Selected", "OK"); return; } List<Model> modelList = new List<Model>(); for (int i = 0; i < objectList.Length; ++i) { MeshFilter[] meshList = objectList[i].GetComponentsInChildren<MeshFilter>(); for (int j = 0; j < meshList.Length; ++j) { Model model = new Model(); MeshFilter _meshFilter = meshList[j]; model.mesh = _meshFilter.sharedMesh; Renderer meshrenderer = _meshFilter.GetComponent<Renderer>(); if (meshrenderer) model.materials = meshrenderer.sharedMaterials; model.transform = _meshFilter.transform; modelList.Add(model); } SkinnedMeshRenderer[] skinList = objectList[i].GetComponentsInChildren<SkinnedMeshRenderer>(); for (int j = 0; j < skinList.Length; ++j) { Model model = new Model(); SkinnedMeshRenderer _skinRender = skinList[j]; model.mesh = _skinRender.sharedMesh; model.materials = _skinRender.sharedMaterials; model.transform = _skinRender.transform; modelList.Add(model); } } if (modelList.Count <= 0) { EditorUtility.DisplayDialog("Alert", "No Mesh To Export", "OK"); return; } string modelPath = EditorUtility.SaveFilePanel( "Scene Export Name", EditorPrefs.GetString("sceneExportPath"), Path.GetFileNameWithoutExtension(SceneManager.GetActiveScene().name), "obj"); if (string.IsNullOrEmpty(modelPath)) { EditorUtility.DisplayDialog("Error", "Invalid Export Name", "OK"); return; } string path = Path.GetDirectoryName(modelPath); string name = Path.GetFileNameWithoutExtension(modelPath); EditorPrefs.SetString("sceneExportPath", path); string materialPath = string.Format("{0}/{1}.material", path, name); if (!Directory.Exists(materialPath)) Directory.CreateDirectory(materialPath); float modelPret = exportMaterial ? 0.9f : 1f; float materialPret = 1f - modelPret; HashSet<ModelMaterial> materialSet = new HashSet<ModelMaterial>(new MaterialCompare()); using (StreamWriter writer = new StreamWriter(modelPath)) { writer.WriteLine( string.Format("mtllib ./{0}.material/material.mtl", name)); writer.WriteLine(); int offset = 0; for (int i = 0; i < modelList.Count; ++i) { ExportMesh(writer, modelList[i], materialSet, ref offset); EditorUtility.DisplayProgressBar( "SceneExport", string.Format( "Export Model : {0}", modelList[i].transform.name), modelPret * (float)i / (float)modelList.Count); } writer.Close(); } if (exportMaterial) using (StreamWriter writer = new StreamWriter(string.Format("{0}/material.mtl", materialPath))) { int p = 0; int count = materialSet.Count; foreach (ModelMaterial material in materialSet) { ExportMaterial(writer, material, materialPath); EditorUtility.DisplayProgressBar( "SceneExport", string.Format( "Export Material : {0}", material.name), materialPret * (float)p / (float)count); ++p; } writer.Close(); } EditorUtility.ClearProgressBar(); EditorUtility.RevealInFinder(modelPath); } static void ExportMesh( TextWriter writer, Model model, HashSet<ModelMaterial> materalSet, ref int offset) { int vertexCount = model.mesh.vertexCount; writer.WriteLine( string.Format("g {0}", model.transform.name)); for (int i = 0; i < vertexCount; ++i) { Vector3 v = model.transform.TransformPoint(model.mesh.vertices[i]); v *= unitsScale; writer.WriteLine( string.Format("v {0} {1} {2}", -v.x, v.y, v.z)); } writer.WriteLine(); for (int i = 0; i < vertexCount; ++i) { Vector3 n = model.transform.TransformDirection(model.mesh.normals[i]); writer.WriteLine( string.Format("vn {0} {1} {2}", -n.x, n.y, n.z)); } writer.WriteLine(); for (int i = 0; i < vertexCount; ++i) { Vector2 t = model.mesh.uv[i]; writer.WriteLine( string.Format("vt {0} {1}", t.x, t.y)); } writer.WriteLine(); for (int i = 0; i < model.mesh.subMeshCount; ++i) { Material mtl = model.materials[i]; int[] triangles = model.mesh.GetTriangles(i); if (exportMaterial) { ModelMaterial modelMtl = new ModelMaterial(); modelMtl.name = mtl.name; modelMtl.cutoff = 1f; for (int t = 0; t < 100; ++t) { if (!materalSet.Contains(modelMtl)) break; modelMtl.name = string.Format("{0}_{1:d2}", mtl.name, t); } writer.WriteLine( string.Format("usemtl {0}", modelMtl.name)); writer.WriteLine( string.Format("usemap {0}", modelMtl.name)); if (mtl.mainTexture) modelMtl.texture = AssetDatabase.GetAssetPath(mtl.mainTexture); else modelMtl.texture = null; if (mtl.HasProperty("_Cutoff")) modelMtl.cutoff = mtl.GetFloat("_Cutoff"); materalSet.Add(modelMtl); } for (int j = 0; j < triangles.Length / 3; ++j) writer.WriteLine( string.Format( "f {1}/{1}/{1} {0}/{0}/{0} {2}/{2}/{2}", triangles[j * 3 + 0] + 1 + offset, triangles[j * 3 + 1] + 1 + offset, triangles[j * 3 + 2] + 1 + offset)); } writer.WriteLine(); offset += vertexCount; } static void ExportMaterial(TextWriter writer, ModelMaterial material, string path) { writer.WriteLine("newmtl {0}", material.name); writer.WriteLine("Ka 1.0 1.0 1.0"); writer.WriteLine("Kd 1.0 1.0 1.0"); writer.WriteLine("Ks 0.0 0.0 0.0"); writer.WriteLine("d 1.0"); writer.WriteLine("illum 1"); if (!string.IsNullOrEmpty(material.texture)) { string texture = Path.GetFileName(material.texture); try { File.Copy(material.texture, path + "/" + texture); } catch (System.Exception) { } writer.WriteLine("map_Kd {0}", texture); if (material.cutoff < 1f) writer.WriteLine("map_d {0}", texture); } writer.WriteLine(); }}
阅读全文
0 0
- unity编辑器拓展五——将场景中物体以Obj格式导入max
- 将Unity场景以Wavefront Obj格式导出
- unity编辑器拓展三——一键调整scene中物体坐标中心点
- unity编辑器拓展九——删除场景中丢失的脚本
- 将Unity地形以Wavefront Obj格式导出
- 【unity编辑器拓展】使用脚本添加Prefab到场景中
- unity 场景编辑器中 获取点击的物体
- unity编辑器拓展四——删除场景空Animator组件
- Unity 编辑器拓展 —— svn
- Unity教程之-解析OBJ模型并将其加载到Unity3d场景中
- unity编辑器拓展八——unity里面分离模型
- unity编辑器拓展二——一键调整scene中物件坐标朝向
- Unity学习笔记——Unity基础一:unity界面、场景、游戏物体、组件等基本概念
- unity编辑器拓展七——脚本创建模型
- unity导出obj格式
- unity编辑器拓展
- Unity编辑器拓展<一>
- Unity编辑器拓展<二>
- hdu1059 Dividing(生成函数||背包)
- jdk环境变量配置教程(史上最详细版)
- Java中编码转换:怎样将 GB2312 编码的字符串转换为 ISO-8859-1 编码的字符串?
- jvm垃圾回收
- JDBC:登录与注册
- unity编辑器拓展五——将场景中物体以Obj格式导入max
- iOS的消息转发机制
- JFFS2 文件系统的工作原理
- iOS开发 导航栏渐变 图片下拉放大 导航栏移动 仿QQ 微博 知乎导航栏
- Spring Boot tomcat配置SSL
- 通过SSH安全协议传输文件(SecureCRT, SSH Secure File Transfer Client)
- C++笔记---函数声明(prototype)
- 带格式字符串反转
- el表达式取值有特殊符号解决方法