Skip to content

Instantly share code, notes, and snippets.

@thebeardphantom
Last active September 4, 2023 16:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thebeardphantom/862de8923d4a9e4f32b906c4bbf1c6af to your computer and use it in GitHub Desktop.
Save thebeardphantom/862de8923d4a9e4f32b906c4bbf1c6af to your computer and use it in GitHub Desktop.
Improvements to Unity <-> Blender <-> FBX <-> Blendfile workflows. See readme.txt.

Improvements to Unity <-> Blender <-> FBX <-> Blendfile workflows.

Using .blend files in Unity projects is slow and overall not great practice. Ideally, you could double click a model in a project, edit it in Blender, hit save, then see the results back in Unity. That's what these scripts help with.

You'll need to associate .blend~ files with Blender in your OS for this to fully work.

BlenderSupportFunctions.cs

Add to your Unity projects.

FUNCTIONS
  • Automatically renames any .blend to .blend~ to have the AssetDatabase ignore it.
  • Lets you double click an FBX to open its associated .blend~ in Blender (only works if the .blend~ file association is setup).

auto_fbx_export.py

Add this to your Blender Default Startup File.

FUNCTIONS

  • Automatically exports an FBX file for any .blend~ file on save.
import bpy
import os
def export_fbx():
# We only want the auto FBX export when working with .blend~ files specifically
blend_file_path = bpy.data.filepath
if not blend_file_path.endswith(".blend~"):
return
blend_file_name = os.path.basename(blend_file_path)
blend_file_name_without_extension = os.path.splitext(blend_file_name)[0]
directory = os.path.dirname(blend_file_path)
fbx_file_path = os.path.join(directory, f"{blend_file_name_without_extension}.fbx")
bpy.ops.export_scene.fbx(
filepath=fbx_file_path,
# Export entire scene, not just selected objects
use_selection=False,
global_scale=1.0,
apply_unit_scale=True,
apply_scale_options='FBX_SCALE_ALL',
object_types={'MESH', 'ARMATURE', 'EMPTY', 'OTHER'},
# Apply mesh modifiers during export
use_mesh_modifiers=True,
# Smoothing algorithm for mesh export
mesh_smooth_type='FACE',
bake_space_transform=True,
# Add leaf bones at end of chains
add_leaf_bones=False,
# Primary axis for bones
primary_bone_axis='Y',
# Secondary axis for bones
secondary_bone_axis='X',
# Export only deform bones of armature
use_armature_deform_only=True,
# Export custom properties
use_custom_props=True,
# Path mode for textures and linked files
path_mode='AUTO'
)
print(f'Saved FBX "{fbx_file_path}"')
# Callback function for save event
def on_save_pre(scene):
export_fbx()
# Register the callback
bpy.app.handlers.save_pre.append(on_save_pre)
print("Registered auto_fbx_export.py")
using System;
using System.Diagnostics;
using System.IO;
using Unity.Logging;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;
using Debug = UnityEngine.Debug;
public class BlenderSupportFunctions : AssetPostprocessor
{
#region Methods
[OnOpenAsset]
private static bool OpenFbx(int instanceID)
{
var assetPath = AssetDatabase.GetAssetPath(instanceID);
return assetPath.EndsWith(".fbx") && TryOpenBlendFileForFbx(assetPath);
}
private static bool TryOpenBlendFileForFbx(string assetPath)
{
var name = Path.GetFileNameWithoutExtension(assetPath);
name += ".blend~";
var directoryName = Path.GetDirectoryName(assetPath);
// skip "Assets/"
directoryName = directoryName.Substring(7);
directoryName = $"{Application.dataPath}/{directoryName}";
var finalPath = $"{directoryName}/{name}";
finalPath = finalPath.Replace('\\', '/');
try
{
Process.Start(finalPath);
}
catch (Exception e)
{
Debug.LogError($"Exception thrown while opening blendfile at path: {finalPath}");
Debug.LogException(e);
return false;
}
return true;
}
private void OnPreprocessAsset()
{
if (!assetPath.EndsWith(".blend"))
{
return;
}
var name = Path.GetFileName(assetPath);
name += "~";
var directoryName = Path.GetDirectoryName(assetPath);
var finalPath = $"{directoryName}/{name}";
finalPath = finalPath.Replace('\\', '/');
Log.Info(finalPath);
File.Move(assetPath, finalPath);
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment