Last active
January 31, 2025 18:28
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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