1
\$\begingroup\$

I have a terrain on which I painted on and used many textures on it. Now when I start the game on my phone it lags alot. Is there any way I can convert the terrain to maybe a plane or anything simpler but still keep the textures and paintings on top?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

There are 3 methods for mobile optimized terrain or platform.

1) Predesigned Terrian from 3D modeling tool.

2) Optimized the Terrian in Unity.

3) Export Unity Terrian from Unity to any 3D modeling tool and then Reimport it into Unity.

1) Use any modeling tool and make a platform.You have a good knowledge of 3D Modeling tool.

2) Set these setting on Unity Terrian and you can optimized it.

Image 1 Image 2 Image 3

Set those setting and use texture size of 512x512 and for each terrain use 2-3 texture.

3)Exports a Unity terrain object as a .obj file that can be loaded into various 3D apps.

This approach is used to convert high poly terrain into low poly by exporting it from Unity into a .obj file and then optimize it into any 3D tool.

You must place the script in a folder named Editor in your project's Assets folder for it to work properly. Also, it must be called "ExportTerrain" or it won't run.

Usage To export, first, select a terrain object in your scene. If none is selected, it will use the active terrain (if any). Select Export To Obj... from the Terrain menu, and in the resulting window, select whether you want the object to use triangles or quads when exported, and also select the resolution to use for the exported mesh (full, half, quarter, eighth or sixteenth). Then click Export, choose a file name and location, and the file will be exported. Note that high-res terrains exported at full resolution will result in very large .obj files and may take a while to process.

Find this link also: http://wiki.unity3d.com/index.php?title=TerrainObjExporter

using UnityEngine;
using UnityEditor;
using System;
using System.Collections;
using System.IO;
using System.Text;
 
enum SaveFormat { Triangles, Quads }
enum SaveResolution { Full=0, Half, Quarter, Eighth, Sixteenth }
 
class ExportTerrain : EditorWindow
{
   SaveFormat saveFormat = SaveFormat.Triangles;
   SaveResolution saveResolution = SaveResolution.Half;
 
   static TerrainData terrain;
   static Vector3 terrainPos;
 
   int tCount;
   int counter;
   int totalCount;
   int progressUpdateInterval = 10000;
 
   [MenuItem("Terrain/Export To Obj...")]
   static void Init()
   {
      terrain = null;
      Terrain terrainObject = Selection.activeObject as Terrain;
      if (!terrainObject)
      {
         terrainObject = Terrain.activeTerrain;
      }
      if (terrainObject)
      {
         terrain = terrainObject.terrainData;
         terrainPos = terrainObject.transform.position;
      }
 
      EditorWindow.GetWindow<ExportTerrain>().Show();
   }
 
   void OnGUI()
   {
      if (!terrain)
      {
         GUILayout.Label("No terrain found");
         if (GUILayout.Button("Cancel"))
         {
            EditorWindow.GetWindow<ExportTerrain>().Close();
         }
         return;
      }
      saveFormat = (SaveFormat) EditorGUILayout.EnumPopup("Export Format", saveFormat);
 
      saveResolution = (SaveResolution) EditorGUILayout.EnumPopup("Resolution", saveResolution);
 
      if (GUILayout.Button("Export"))
      {
         Export();
      }
   }
 
   void Export()
   {
      string fileName = EditorUtility.SaveFilePanel("Export .obj file", "", "Terrain", "obj");
      int w = terrain.heightmapWidth;
      int h = terrain.heightmapHeight;
      Vector3 meshScale = terrain.size;
      int tRes = (int)Mathf.Pow(2, (int)saveResolution );
      meshScale = new Vector3(meshScale.x / (w - 1) * tRes, meshScale.y, meshScale.z / (h - 1) * tRes);
      Vector2 uvScale = new Vector2(1.0f / (w - 1), 1.0f / (h - 1));
      float[,] tData = terrain.GetHeights(0, 0, w, h);
 
      w = (w - 1) / tRes + 1;
      h = (h - 1) / tRes + 1;
      Vector3[] tVertices = new Vector3[w * h];
      Vector2[] tUV = new Vector2[w * h];
 
      int[] tPolys;
 
      if (saveFormat == SaveFormat.Triangles)
      {
         tPolys = new int[(w - 1) * (h - 1) * 6];
      }
      else
      {
         tPolys = new int[(w - 1) * (h - 1) * 4];
      }
 
      // Build vertices and UVs
      for (int y = 0; y < h; y++)
      {
         for (int x = 0; x < w; x++)
         {
            tVertices[y * w + x] = Vector3.Scale(meshScale, new Vector3(-y, tData[x * tRes, y * tRes], x)) + terrainPos;
            tUV[y * w + x] = Vector2.Scale( new Vector2(x * tRes, y * tRes), uvScale);
         }
      }
 
      int  index = 0;
      if (saveFormat == SaveFormat.Triangles)
      {
         // Build triangle indices: 3 indices into vertex array for each triangle
         for (int y = 0; y < h - 1; y++)
         {
            for (int 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 (int y = 0; y < h - 1; y++)
         {
            for (int 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
      StreamWriter sw = new StreamWriter(fileName);
      try
      {
 
         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)) / progressUpdateInterval;
         for (int i = 0; i < tVertices.Length; i++)
         {
            UpdateProgress();
            StringBuilder sb = new 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 (int i = 0; i < tUV.Length; i++)
         {
            UpdateProgress();
            StringBuilder sb = new 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 (int i = 0; i < tPolys.Length; i += 3)
            {
               UpdateProgress();
               StringBuilder sb = new 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 (int i = 0; i < tPolys.Length; i += 4)
            {
               UpdateProgress();
               StringBuilder sb = new 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(Exception err)
      {
         Debug.Log("Error saving file: " + err.Message);
      }
      sw.Close();
 
      terrain = null;
      EditorUtility.DisplayProgressBar("Saving file to disc.", "This might take a while...", 1f);
      EditorWindow.GetWindow<ExportTerrain>().Close();      
      EditorUtility.ClearProgressBar();
   }
 
   void UpdateProgress()
   {
      if (counter++ == progressUpdateInterval)
      {
         counter = 0;
         EditorUtility.DisplayProgressBar("Saving...", "", Mathf.InverseLerp(0, totalCount, ++tCount));
      }
   }
}

And then import the terrain in your project but you need to take care of unrapping and texture on it after importing on Unity.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .