From Unify Community Wiki
Revision as of 00:29, 6 September 2011 by Rogerimp (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search



Author: Roger Braunstein (rogerimp)

This editor script will prevent Unity from modifying the polygon ordering in a model upon import. Lore and evidence suggest that mesh optimizations are applied on import (even when the Mesh Compression import setting is Off).

In most cases this optimization is a good thing, as Unity seems to create triangle strips that would optimize rendering performance. In some cases, this is a bad thing, such as when you are attempting to render an overlapping discontinuous mesh in a single draw call from bottom-to-top (for instance, drawing a character on the same z-plane in a 2D game using the Unlit/Transparent shader). In this case, the optimizations could reorder your polygons and their carefully-created draw order.

The script does this by overriding the optimized mesh at import time, using the original polygon ordering. No additional work is required at run time.


To use this script, place it in the Assets/Editor directory. It will only run on models with an accompanying .csv file containing the original polygon ordering.

For instance, if your model is in Assets/Kimmy.fbx, it will look for an accompanying Assets/Kimmy.csv file.

Details on the format of this CSV file (which is actually tab-separated, not comma) are inline in the code.

Contributions Accepted

If your 3d package can export polygon ordering to some kind of text file, it should be pretty easy to accept a new format in this script. Please change it and let me know (PM me on the forums).

I can provide a python script that reads this information from any FBX, but you'll need to have python and the Autodesk FBX SDK for Python installed. (In theory, we could read this info directly from the FBX in this script, but I'm keeping it simple.)


<csharp> using UnityEditor; using UnityEngine; using System; using System.IO; using System.Linq; using System.Collections.Generic; using Path = System.IO.Path;

public class PolyOrderFixupOnImport : AssetPostprocessor { private readonly char[] CSVDelimiters = new char[]{'\t'};

public void OnPostprocessModel(GameObject go) { string assetPathAbsolute = Path.Combine(Path.Combine(Application.dataPath, ".."), this.assetPath); string assetPathNormalized = new DirectoryInfo(assetPathAbsolute).FullName; string csvPath = Path.ChangeExtension(assetPathNormalized, "csv"); if (!File.Exists(csvPath)) return;

try { Debug.Log(string.Format("Found replacement polygon info for {0}, replacing optimized polys...", go.name));

Mesh mesh = go.GetComponent<MeshFilter>().sharedMesh; mesh.triangles = ReadTriangleListFromCSV(csvPath).ToArray();

Debug.Log("Rewrote triangles successfully."); } catch (NullReferenceException) {} }

//We expect a tab separated values file in the following format: //Polygon A B C D //0 0 12 14 //1 12 1 13 // //and so on. Polygon = just a counter up from 0. //All polygons are expected to be triangles, so D column is left blank (and is optional.) //By the way, the reasoning behind this format is the way Cinema 4D's Structure manager //exports data. Try out Window>Structure Manager, Mode>Polygons, then File>Export ASCII Data. //Feel free to extend this class to include formats supported by other 3d tools. private List<int> ReadTriangleListFromCSV(string filename) { var triangles = new List<int>(); using (StreamReader sr = File.OpenText(filename)) { sr.ReadLine(); //discard first line while (!sr.EndOfStream) { string[] substrings = sr.ReadLine().Split(CSVDelimiters); triangles.AddRange(substrings.Skip(1).Take(3).Select(str => int.Parse(str))); } } return triangles; } } </csharp>

Personal tools