Tuesday, July 14, 2015

Blender editor script for Unity

We've been doing a lot of Unity development recently, and one of the things we find really awkward about it is its Blender support.  Unity's preferred axis doesn't match Blender's, in particular.  We've been using an editor script to help this, which I figured I'd post below.  It does the following things:

- Defaults to not importing materials.  It seems to cause a mess more than anything so we create these by hand.  This is easy to disable if you don't like that.
- Swaps the Y and Z axes so that up in Blender is also up in Unity, and fixes the right/left thing with the X axis.
- Adjusts coordinates so that the Blender object's origin ends up 0,0,0 in the imported mesh.
- Lets you ignore a mesh by putting _ at the start of its name.  For example, an object in the Blender file named "_reference" would not be imported.

We've been using this for static models and it's generally behaved well.  To use, copy/paste the below into a file called BlenderTweaks.cs, and put it in your Assets/Script/Editor folder.



using UnityEngine;
using UnityEditor;
using System.Collections.Generic;


public class BlenderTweaks : AssetPostprocessor
{
public override int GetPostprocessOrder()
{
return base.GetPostprocessOrder() + 10;
}

void OnPreprocessModel()
{
// Don't import materials.
ModelImporter modelImporter = assetImporter as ModelImporter;
modelImporter.importMaterials = false;
}

private void OnPostprocessModel( GameObject gameObj )
{
// Debug.Log( "OnPostprocessModel: " + gameObj.transform.name );

MeshFilter[] meshFilters = gameObj.GetComponentsInChildren();

for( int i=0; i
{
Mesh mesh = meshFilters[i].sharedMesh;

if( mesh.name[0] == '_' )
{
Debug.Log( "Ignoring mesh: " + mesh.name );

Component.DestroyImmediate( meshFilters[i].gameObject );
Component.DestroyImmediate( meshFilters[i] );
Component.DestroyImmediate( mesh );
}
else
{
RotateMesh( mesh );

meshFilters[i].transform.localPosition = Vector3.zero;
}
}

}

private void RotateMesh( Mesh mesh )
{
//switch all vertex z values with y values
Vector3[] vertices = mesh.vertices;

for( int i=0; i < vertices.Length; i++)
{
vertices[i].Set( -vertices[i].x, vertices[i].z, vertices[i].y );
}
mesh.vertices = vertices;

//recalculate other relevant mesh data
mesh.RecalculateNormals();
mesh.RecalculateBounds();
}
}

No comments:

Post a Comment