Skip to content

Instantly share code, notes, and snippets.

@JohannesMP
Last active January 6, 2024 07:22
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save JohannesMP/e4d8b7464e05f7d782eb66b3764b5049 to your computer and use it in GitHub Desktop.
Save JohannesMP/e4d8b7464e05f7d782eb66b3764b5049 to your computer and use it in GitHub Desktop.
Using the Unity FBX SDK to save a single Mesh as an FBX. Uses Unity FBX SDK from: https://assetstore.unity.com/packages/essentials/101408
using System.IO;
using UnityEngine;
using UnityEditor;
using Unity.FbxSdk;
using FbxExporters.Editor;
// Place in 'Editor' folder
public static class ExtractMeshToFBX
{
// true: fbx file is easy-to-debug ascii, false: fbx file is binary.
static bool saveFbxAsAscii = false;
// The preferred axis system for the exported fbx file
static FbxAxisSystem fbxAxisSystem = FbxAxisSystem.Max;
// The preferred units of the exported fbx file
static FbxSystemUnit fbxUnit = FbxSystemUnit.m;
static string fbxFileTitle = "TITLE HERE";
static string fbxFileSubject = "SUBJECT HERE";
static string fbxFileComment = "COMMENT HERE";
static string fbxFileKeywords = "KEYWORDS HERE";
static string fbxFileAuthor = "AUTHOR HERE";
static string fbxFileRevision = "1.0";
static string fbxFileApplication = "Unity FBX SDK";
[MenuItem("Assets/Extract to FBX", validate = true)]
public static bool MenuExtractToFBXValidate()
{
if (Selection.activeObject == null)
return false;
return Selection.activeObject.GetType() == typeof(Mesh);
}
[MenuItem("Assets/Extract to FBX")]
public static void MenuExtractToFBX()
{
// We assume validation worked and this is always defined.
Mesh mesh = Selection.activeObject as Mesh;
// Set up paths
string meshFilePath = AssetDatabase.GetAssetPath(mesh);
string meshDirectory = Path.GetDirectoryName(meshFilePath);
string filename = Path.GetFileNameWithoutExtension(meshFilePath) + ".fbx";
string filePath = Path.Combine(meshDirectory, filename);
ExtractToFBX(mesh, filePath);
}
public static void ExtractToFBX(Mesh mesh, string filePath)
{
// Make a temporary copy of the mesh to modify it
Mesh tempMesh = Object.Instantiate(mesh);
tempMesh.name = mesh.name;
// If meters, divide by 100 since default is cm. Assume centered at origin.
if (fbxUnit == FbxSystemUnit.m)
{
Vector3[] vertices = tempMesh.vertices;
for (int i = 0; i < vertices.Length; ++i)
vertices[i] /= 100.0f;
tempMesh.vertices = vertices;
}
// You could handle other SystemUnits here
// FBX Manager
FbxManager manager = FbxManager.Create();
manager.SetIOSettings(FbxIOSettings.Create(manager, Globals.IOSROOT));
// FBX Exporter
FbxExporter fbxExporter = FbxExporter.Create(manager, "Exporter");
// Binary
int fileFormat = -1;
// Ascii
if (saveFbxAsAscii)
fileFormat = manager.GetIOPluginRegistry().FindWriterIDByDescription("FBX ascii (*.fbx)");
fbxExporter.Initialize(filePath, fileFormat, manager.GetIOSettings());
fbxExporter.SetFileExportVersion("FBX201400");
// FBX Scene
FbxScene fbxScene = FbxScene.Create(manager, "Scene");
FbxDocumentInfo sceneInfo = FbxDocumentInfo.Create(manager, "SceneInfo");
// Set up scene info
sceneInfo.mTitle = fbxFileTitle;
sceneInfo.mSubject = fbxFileSubject;
sceneInfo.mComment = fbxFileComment;
sceneInfo.mAuthor = fbxFileAuthor;
sceneInfo.mRevision = fbxFileRevision;
sceneInfo.mKeywords = fbxFileKeywords;
sceneInfo.Original_ApplicationName.Set(fbxFileApplication);
sceneInfo.LastSaved_ApplicationName.Set(fbxFileApplication);
fbxScene.SetSceneInfo(sceneInfo);
// Set up Global settings
FbxGlobalSettings globalSettings = fbxScene.GetGlobalSettings();
globalSettings.SetSystemUnit(fbxUnit);
globalSettings.SetAxisSystem(fbxAxisSystem);
FbxNode modelNode = FbxNode.Create(fbxScene, tempMesh.name);
// Add mesh to a node in the scene
using (ModelExporter modelExporter = new ModelExporter())
{
if (!modelExporter.ExportMesh(tempMesh, modelNode))
Debug.LogError("Problem Exporting Mesh");
}
// add the model to the scene
fbxScene.GetRootNode().AddChild(modelNode);
// Finally actually save the scene
bool sceneSuccess = fbxExporter.Export(fbxScene);
AssetDatabase.Refresh();
// clean up temporary model
if (Application.isPlaying)
Object.Destroy(tempMesh);
else
Object.DestroyImmediate(tempMesh);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment