Search Unity

Question FBX Exporter: Binary export doesn't work via editor scripting

Discussion in 'Editor & General Support' started by Peter77, May 23, 2021.

  1. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,609
    I use your Unity FBX Exporter 4.0.1 package and I have to export objects via scripting, like:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5.  
    6. class TestCode
    7. {
    8.     [MenuItem("BugReport/Export selected GameObject as FBX")]
    9.     static void DoMenuItem()
    10.     {
    11.         UnityEditor.Formats.Fbx.Exporter.ModelExporter.ExportObject("Assets/MyExport.fbx", Selection.activeGameObject);
    12.         UnityEditor.AssetDatabase.Refresh();
    13.     }
    14. }
    However, the exported FBX file is in ASCII format always. The
    Export Format
    settings under
    Project Settings > Fbx Export
    don't affect the exported format.

    upload_2021-5-23_15-23-53.png

    Right-clicking the object in the Hierarchy and choosing
    Export to FBX...
    actually does export the file in binary. I looked through the FBX Exporter code and you pass an additional
    SettingsObject
    to the
    ExportObjects
    method.

    All of this functionality is internal only. Please make the API public instead, I need to export objects via editor-scripting. The reason why I need to export binary is that the ASCII format is just too big, the mesh export is 150MB, which isn't great for import times in the editor and version control.

    I also submitted a bug-report for you:
    (Case 1338169) 2019.4: FBX Exporter: Export Binary not working
    https://issuetracker.unity3d.com/is...script-and-the-export-format-is-set-to-binary
     
    Last edited: Jun 23, 2021
  2. unity_GhCCjBkYeYN1eQ

    unity_GhCCjBkYeYN1eQ

    Joined:
    Jun 15, 2020
    Posts:
    3
    Same here, did you find a fix?
     
    Miscellaneous likes this.
  3. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,609
    Unity QA was able to reproduce the issue and provided the following workaround, here is their reply:
    PS: I don't use the workaround.
     
  4. LemonLube

    LemonLube

    Joined:
    Jul 5, 2014
    Posts:
    1
    Also ran into this problem and cannot use source code edit workaround. Here's a dumb as hell, reflection workaround!

    Code (CSharp):
    1. private static void ExportBinaryFBX (string filePath, UnityEngine.Object singleObject)
    2.     {
    3.         // Find relevant internal types in Unity.Formats.Fbx.Editor assembly
    4.         Type[] types = AppDomain.CurrentDomain.GetAssemblies().First(x => x.FullName == "Unity.Formats.Fbx.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").GetTypes();
    5.         Type optionsInterfaceType = types.First(x => x.Name == "IExportOptions");
    6.         Type optionsType = types.First(x => x.Name == "ExportOptionsSettingsSerializeBase");
    7.  
    8.         // Instantiate a settings object instance
    9.         MethodInfo optionsProperty = typeof(ModelExporter).GetProperty("DefaultOptions", BindingFlags.Static | BindingFlags.NonPublic).GetGetMethod(true);
    10.         object optionsInstance = optionsProperty.Invoke(null, null);
    11.  
    12.         // Change the export setting from ASCII to binary
    13.         FieldInfo exportFormatField = optionsType.GetField("exportFormat", BindingFlags.Instance | BindingFlags.NonPublic);
    14.         exportFormatField.SetValue(optionsInstance, 1);
    15.  
    16.         // Invoke the ExportObject method with the settings param
    17.         MethodInfo exportObjectMethod = typeof(ModelExporter).GetMethod("ExportObject", BindingFlags.Static | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(string), typeof(UnityEngine.Object), optionsInterfaceType }, null);
    18.         exportObjectMethod.Invoke(null, new object[] { filePath, singleObject, optionsInstance });
    19.     }
     
    caogtaa, EJSainz, sam373 and 3 others like this.
  5. GlobalAdminShiftPixy

    GlobalAdminShiftPixy

    Joined:
    Apr 26, 2021
    Posts:
    2
    So - this is a work-around to the work around if you want to avoid reflection.

    Download the https://github.com/Unity-Technologies/com.unity.formats.fbx and set this up in your packages folder and import the tar.
    Open Packages\com.unity.formats.fbx folder in IDE of choice
    Find and replace all [internal ] with [public ]*do not include [] **Include the space at the end so you don't replace anything prefaced with internal
    Now you can use:

    Code (CSharp):
    1. var exportOptions = new ExportModelSettingsSerialize();
    2. exportOptions.SetPreserveImportSettings(true);
    3. ModelExporter.ExportObject(filename, cube, exportOptions);
    1. var exportOptions = new ExportModelSettingsSerialize();
    2. exportOptions.SetPreserveImportSettings(true);
    3. ModelExporter.ExportObject(filename, cube, exportOptions);
     
  6. GeniusKoala

    GeniusKoala

    Joined:
    Oct 13, 2017
    Posts:
    97
    The export works but the FBX does not keep the position at all and export at (0,0,0) but the rotation is ok. Any idea?

    I want to export a GameObject at the root of the scene in World Absolute position but it always export it Local Pivot even if it is "World Absolute" in Project Settings :

    Code (CSharp):
    1.         FieldInfo exportFormatField = optionsType.GetField("objectPosition", BindingFlags.Instance | BindingFlags.NonPublic);
    2.         exportFormatField.SetValue(optionsInstance, 1);
    I tried added "objectPosition" "objectsPosition" I even tried "include" but only your field "exportFormat" works. How can you the names of the fields? @LemonLube

    I found this line in the package : https://github.com/Unity-Technologi...unity.formats.fbx/Editor/FbxExporter.cs#L3719

    EDIT : I found it !

    Code (CSharp):
    1. Type optionsPositionType = types.First(x => x.Name == "ExportModelSettingsSerialize");
    2. FieldInfo exportPositionField = optionsPositionType.GetField("objectPosition", BindingFlags.Instance | BindingFlags.NonPublic);
    3. exportPositionField.SetValue(optionsInstance, 1);
    Add these lines to the @LemonLube solution!

    I printed all type possible with these lines :

    Code (CSharp):
    1.         foreach(Type type in types)
    2.         {
    3.             Debug.Log("type : " + type);
    4.         }
     
    Last edited: Jun 2, 2022
    LemonLube likes this.
  7. Mhonglim

    Mhonglim

    Joined:
    Aug 8, 2015
    Posts:
    1
    FBX Exporter 5.1.0 pre
    Developer’s Guide | FBX Exporter | 5.1.0-pre.1 (unity3d.com)


    using UnityEngine;
    using UnityEditor;
    using System.IO;
    using UnityEditor.Formats.Fbx.Exporter;

    public class MyFBXExport : MonoBehaviour
    {
    public GameObject[] meshCombiners;

    public void Export()
    {
    ExportModelOptions exportSettings = new ExportModelOptions();
    exportSettings.ExportFormat = ExportFormat.Binary;
    exportSettings.KeepInstances = false;

    for (int i = 0; i < meshCombiners.Length; i++)
    {
    string filePath = Path.Combine(Application.dataPath, "MyExport", meshCombiners.gameObject.name + ".fbx");
    ModelExporter.ExportObject(filePath, meshCombiners.gameObject, exportSettings);
    }
    }
    }
     
  8. aavenel-ls

    aavenel-ls

    Joined:
    Jul 3, 2020
    Posts:
    4