回答:
unity3D导出obj的方法如下:
从TerrAIn菜单下选择Export To Obj... ,在分辨率窗口,选择要四边形还是三角形网格结构。同样也可以选择要导出地形的分辨率,有高中低等等.点击Export,选择要保存的位置和文件名.Obj文件将被导出.要注意如果选择大面积的Full地形导出,最终的Obj文件将非常大,而且也要导出时间较长。
下面为ExportTerrAIn.js脚本
import System.IO;
import System.Text;
enum SaveFormat {Triangles, Quads}
enum SaveResolution {Full, Half, Quarter, Eighth, Sixteenth}
class ExportTerrAIn extends EditorWindow {
var saveFormat = SaveFormat.Triangles;
var saveResolution = SaveResolution.Half;
static var terrAIn : TerrAInData;
static var terrAInPos : Vector3;
var tCount : int;
var counter : int;
var totalCount : int;
@MenuItem ("TerrAIn/Export To Obj...")
static function Init () {
terrAIn = null;
var terrAInObject : TerrAIn = Selection.activeObject as TerrAIn;
if (!terrAInObject) {
terrAInObject = TerrAIn.activeTerrAIn;
}
if (terrAInObject) {
terrAIn = terrAInObject.terrAInData;
terrAInPos = terrAInObject.transForm.position;
}
EditorWindow.GetWindow(ExportTerrAIn).Show();
}
function OnGUI () {
if (!terrAIn) {
GUILayout.Label("No terrAIn found");
if (GUILayout.Button("Cancel")) {
EditorWindow.GetWindow(ExportTerrAIn).Close();
}
return;
}
saveFormat = EditorGUILayout.EnumPopup("Export Format", saveFormat);
saveResolution = EditorGUILayout.EnumPopup("Resolution", saveResolution);
if (GUILayout.Button("Export")) {
Export();
}
}
function Export () {
var fileName = EditorUtility.SaveFilePanel("Export .obj file", "", "TerrAIn", "obj");
var w = terrAIn.heightmapWIDth;
var h = terrAIn.heightmapHeight;
var meshScale = terrAIn.size;
var tRes = Mathf.Pow(2, parseInt(saveResolution));
meshScale = Vector3(meshScale.x/(w-1)*tRes, meshScale.y, meshScale.z/(h-1)*tRes);
var uvScale = Vector2(1.0/(w-1), 1.0/(h-1));
var tData = terrAIn.GetHeights(0, 0, w, h);
w = (w-1) / tRes + 1;
h = (h-1) / tRes + 1;
var tVertices = new Vector3[w * h];
var tUV = new Vector2[w * h];
if (saveFormat == SaveFormat.Triangles) {
var tPolys = new int[(w-1) * (h-1) * 6];
}
else {
tPolys = new int[(w-1) * (h-1) * 4];
}
// BUIld vertices and UVs
For (y = 0; y < h; y++) {
For (x = 0; x < w; x++) {
tVertices[y*w + x] = Vector3.Scale(meshScale, Vector3(x, tData[x*tRes,y*tRes], y)) + terrAInPos;
tUV[y*w + x] = Vector2.Scale(Vector2(x*tRes, y*tRes), uvScale);
}
}
var index = 0;
if (saveFormat == SaveFormat.Triangles) {
// BUIld triangle indices: 3 indices into vertex array For each triangle
For (y = 0; y < h-1; y++) {
For (x = 0; x < w-1; x++) {
// For each grID cell output two triangles
tPolys[index++] = (y * w) + x;
tPolys[index++] = ((y+1) * w) + x;
tPolys[index++] = (y * w) + x + 1;
tPolys[index++] = ((y+1) * w) + x;
tPolys[index++] = ((y+1) * w) + x + 1;
tPolys[index++] = (y * w) + x + 1;
}
}
}
else {
// BUIld quad indices: 4 indices into vertex array For each quad
For (y = 0; y < h-1; y++) {
For (x = 0; x < w-1; x++) {
// For each grID cell output one quad
tPolys[index++] = (y * w) + x;
tPolys[index++] = ((y+1) * w) + x;
tPolys[index++] = ((y+1) * w) + x + 1;
tPolys[index++] = (y * w) + x + 1;
}
}
}
// Export to .obj
try {
var SW = new StreamWriter(fileName);
SW.WriteLine("# Unity terrAIn OBJ File");
// Write vertices
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
counter = tCount = 0;
totalCount = (tVertices.Length*2 + (saveFormat == SaveFormat.Triangles? tPolys.Length/3 : tPolys.Length/4)) / 1000;
For (i = 0; i < tVertices.Length; i++) {
UpdateProgress();
var sb = StringBUIlder("v ", 20);
// StringBUIlder stuff is done this way becAuse it's faster than using the "{0} {1} {2}"etc. Format
// Which is important when you're exporting hUGe terrAIns.
sb.Append(tVertices[i].x.ToString()).Append(" ").
Append(tVertices[i].y.ToString()).Append(" ").
Append(tVertices[i].z.ToString());
SW.WriteLine(sb);
}
// Write UVs
For (i = 0; i < tUV.Length; i++) {
UpdateProgress();
sb = StringBUIlder("vt ", 22);
sb.Append(tUV[i].x.ToString()).Append(" ").
Append(tUV[i].y.ToString());
SW.WriteLine(sb);
}
if (saveFormat == SaveFormat.Triangles) {
// Write triangles
For (i = 0; i < tPolys.Length; i += 3) {
UpdateProgress();
sb = StringBUIlder("f ", 43);
sb.Append(tPolys[i]+1).Append("/").Append(tPolys[i]+1).Append(" ").
Append(tPolys[i+1]+1).Append("/").Append(tPolys[i+1]+1).Append(" ").
Append(tPolys[i+2]+1).Append("/").Append(tPolys[i+2]+1);
SW.WriteLine(sb);
}
}
else {
// Write quads
For (i = 0; i < tPolys.Length; i += 4) {
UpdateProgress();
sb = StringBUIlder("f ", 57);
sb.Append(tPolys[i]+1).Append("/").Append(tPolys[i]+1).Append(" ").
Append(tPolys[i+1]+1).Append("/").Append(tPolys[i+1]+1).Append(" ").
Append(tPolys[i+2]+1).Append("/").Append(tPolys[i+2]+1).Append(" ").
Append(tPolys[i+3]+1).Append("/").Append(tPolys[i+3]+1);
SW.WriteLine(sb);
}
}
}
catch (err) {
DebUG.Log("Error saving file: " + err.Message);
}
SW.Close();
terrAIn = null;
EditorUtility.ClearProgressBar();
EditorWindow.GetWindow(ExportTerrAIn).Close();
}
function UpdateProgress () {
if (counter++ == 1000) {
counter = 0;
EditorUtility.DisplayProgressBar("Saving...", "", Mathf.InverseLerp(0, totalCount, ++tCount));
}
}