1. We're looking for feedback on Unity Starter Kits! Let us know what you’d like.
    Dismiss Notice
  2. Unity 2017.2 beta is now available for download.
    Dismiss Notice
  3. Unity 2017.1 is now released.
    Dismiss Notice
  4. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  5. Reddit AMA with Adam Myhill on Cinemachine, Thurs July 27 - 10AM PT. More info.
    Dismiss Notice
  6. Check out all the fixes for 5.6 on the patch releases page.
    Dismiss Notice
  7. Help us improve the editor usability and artist workflows. Join our discussion to provide your feedback.
    Dismiss Notice

Blender > Unity Rotation Fix

Discussion in 'External Tools' started by Mirgar, May 11, 2013.

  1. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    Hi all!
    Lately I've been trying to tackle Blender's python and here are early fruits of my experiments. This addon fixes rotation of objects such as meshes or armatures to match Unity's coordinate system.

    To install this addon unpack it to your Blender addon folder, e.g. "C:\Program Files\Blender Foundation\Blender\2.67\scripts\addons" or use install from file button in user preferences under addons tab.

    After installing, addon is in Object category and after enabling it, can be accessed from Tool Shelf under "Unity Tools" panel.

    Note that complete rotation fix on X and Z axis will swap object so it will face +Y axis instead -Y, if you export through fbx remember to set Forward Z and Up Y as export axis when you use full rotation fix.

    Hope it will prove useful for someone.
    Cheers!
     

    Attached Files:

    Last edited: Aug 22, 2013
  2. Cylon_Toast

    Cylon_Toast

    Joined:
    Aug 18, 2012
    Posts:
    8
    Bravo! I applaud anyone who offers their hard work for free to help deveopers with their work flow. I can't wait to see what further developments and tools you create!
     
  3. Benoit3d

    Benoit3d

    Joined:
    May 15, 2013
    Posts:
    7
    Mirgar thank you for sharing the addon. I will test it at my next export.
     
  4. Jimww

    Jimww

    Joined:
    May 14, 2013
    Posts:
    63
    Works great! Thanks :p
     
  5. Xian55

    Xian55

    Joined:
    Jul 6, 2012
    Posts:
    12
    Hello, which is the minimum Blender version is requirement?
    only from 2.67 ?

    Becasue i tried with the Blender 2.63 version. Im just try to apply the plugin with a simple Cube which a default model in blender, and i get these error messages:

     
    Last edited: Jun 19, 2013
  6. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    Hi, I updated attachments, now all 2.6.x version should be able to work with this add-on.
     
  7. Xian55

    Xian55

    Joined:
    Jul 6, 2012
    Posts:
    12
    It works on Blender 2.63 , thank you for your efforts!
     
  8. Gatto_matto

    Gatto_matto

    Joined:
    Feb 15, 2011
    Posts:
    58
    Hey, excellent work. Very simple, but very usefull! It works well on 2.67. Thank you.
     
  9. Tiles

    Tiles

    Joined:
    Feb 5, 2010
    Posts:
    2,465
    Thanks :)
     
  10. Redrum

    Redrum

    Joined:
    Mar 21, 2013
    Posts:
    2
    Thanks.

    I've been messing with it for a while and it works if my object in blender is facing the negative Y axis.
    Is this the intended behavior or am I doing something wrong?
     
  11. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    Basically, models exported from Blender to Unity are flipped by 90 points on X axis, so if model is flipped by -90 points before export and rotation is applied then rotations cancel themselves and models are as they should be. This however means, that after you rotate your model, in Blender it will appear 'laying' on its back, so to make it look unchanged and workable it has to be rotated by 90 points on X axis, but without applying rotation, making its local Z axis face global -Y axis. This add-on automates this process.
     
  12. rimau79

    rimau79

    Joined:
    Jul 10, 2013
    Posts:
    1
    Beautifull little thing. Thank you :)
     
  13. Venni

    Venni

    Joined:
    Jul 15, 2013
    Posts:
    131
    I just wanted to give my thanks to the creator of this addon :D It really makes things a lot faster and works great!
     
  14. Neterea Studios

    Neterea Studios

    Joined:
    May 7, 2013
    Posts:
    23
    Do you need an extra Z axis rotation of 180 to match X Axis orientation?

    $Axis.png
     
  15. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    This rotation is not needed, my add-on should produce only rotation of 90 on X axis and no other rotation should be needed to export correctly. Can you tell me which version of blender and exporter you use? And possibly send me blend file on which you found this problem?
     
  16. Neterea Studios

    Neterea Studios

    Joined:
    May 7, 2013
    Posts:
    23
    Sorry, I explained myself in a bad way.

    Your script only performed the 90 rotation on X axis. I made that extra 180 Z rotation by hand (Rotate 180 in edit mode, and rotate again 180 in object mode, same trick that the script does with X).

    If I don't make that rotation objects end up facing Z positive. When I edit objects in Blender, like that plane, that are facing Y-negative in order to make them facing Z-negative in Unity I need to perform that rotation. In this way I'm changing only the Z-Y axis and not the object orientation according to X Axis.

    My question was more on the way if you also make that rotation when editing in blender (not only you, other people who use your script). I can guess that you only perform the X rotation, but why not the 180 Z rotation?

    It's the only way I found to then reset the rotations in Unity (X: 0, Y: 0, Z:0) and end with my object facing the same directions in the scene. I also noticed that Unity tries to preserve some rotations, so I also need to reset them by hand.

    When I started to do the rotation compensation trick in Blender I also started to rotate around Z. So now that I found a script to automate this I was wondering if other people is rotating around Z.

    I don't know how animations will be affected by this, only used it on "static" models for now.
     
    Last edited: Aug 18, 2013
  17. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    No, I do not need any extra rotations for models exported from Blender. If you use fbx exporter check if your export axies match Forward -Z and Up Y, if they are not then this may cause your problem.
     
    Last edited: Aug 19, 2013
  18. Neterea Studios

    Neterea Studios

    Joined:
    May 7, 2013
    Posts:
    23
    Yes, I make that different.

    I simple place the .blend in the Unity assets structure and Unity performs the import, but I think -Z Forward and Y Up are the defaults, so no difference should result from this process.

    I think that just compensating around X axis your model will end up rotated from your original facing direction.

    I will try to generate another set of screenshots to state better my question.
     
  19. Neterea Studios

    Neterea Studios

    Joined:
    May 7, 2013
    Posts:
    23
    Ok,

    Lets see if I can state my question this time. Again, your script is working perfect. I'm only asking why an extra 180 rotation around Z is not applied.

    I modeled a "small arrow" and a "big arrow" to represent "Up" in an object and "facing" direction. "big arrow" is facing direction, "small arrow" is up.

    In the example, both objects are reseted to 0 rotation on all axis when imported to Unity.

    If I only apply the X correction we can see in the first example that the "Up" direction is preserved. Z-Up in blender is converted to Y-Up in Unity, and this is OK. But facing X positive in Blender now becomes facing X negative in Unity. If you are only interested in the "Up" correction this is fine. And in past projects I was only concerned about this.

    In the second example, after the script applies the X correction I apply an extra Z correction. In this way, my object is also facing X positive (same as when editing) when imported to Unity.

    My question was about this X facing problem. If you are also concerned about this issue, if it's good to give a thought and introduce this extra Z rotation in the script. Again, I don't know if this affects animations (I only tried it with not-animated objects). Just wondering if people also used to do this correction in blender or once the objects is in Unity ("Up" corrected) you don't care the object is flipped around Z axis.

    I hope this clarifies my past posts.

    $Axis2.png
     
  20. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    Ok, now I understand what the problem is. In Blender +X axis is left-sided where in Unity is right-sided. While rotating on Z axis will fix this, it will introduce new problem. From what I seen most people work with -Y axis as forward, should you apply Z rotation forward will switch to +Y and it will probably screw most peoples workflow.

    Personally it doesn't bother me, however, in my free time I will think about good way to update add-on to address this issue.
     
  21. stry

    stry

    Joined:
    Feb 8, 2009
    Posts:
    1
    This sort of bugged me a bit, so I just modified your script like so:
    Code (csharp):
    1.     def FixRotationForUnity3D(self):
    2.         bpy.ops.object.transform_apply(rotation = True)
    3.  
    4.         bpy.ops.transform.rotate(value = -1.5708, axis = (1, 0, 0), constraint_axis = (True, False, False), constraint_orientation = 'GLOBAL')
    5.         bpy.ops.transform.rotate(value = -3.1416, axis = (0, 0, 1), constraint_axis = (False, False, True), constraint_orientation = 'GLOBAL')
    6.  
    7.         bpy.ops.object.transform_apply(rotation = True)
    8.  
    9.         bpy.ops.transform.rotate(value = 1.5708, axis = (1, 0, 0), constraint_axis = (True, False, False), constraint_orientation = 'GLOBAL')
    10.         bpy.ops.transform.rotate(value = 3.1416, axis = (0, 1, 0), constraint_axis = (False, True, False), constraint_orientation = 'GLOBAL')
    So now when I export from Blender, using Forward: Z Forward, and Up: Y Up; the orientation is identical in Unity.
     
  22. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    Updated add-on, now functionality is accessed through panel in tool shelf and both simple X axis rotation and full fix is accessible from there.
     
  23. cCoding

    cCoding

    Joined:
    Jul 3, 2012
    Posts:
    118
    Sorry for updating a 2 week old post.

    Just wanted to say thanks for making this. This blender addon works perfectly! Blender just started refusing to work with unity after the last update. I appreciate the work you put into this. I do have a small suggestion. Is it possible to make this work with a keystroke? Maybe something like Shift+U+F or allow us to just make it custom.
     
  24. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    In my workflow I don't use rotation fix often enough to make shortcut and I'm not sure if setting shortcut by default is good idea but you can manually add keystroke shortcut for operators in user preferences under input tab, find 3D View and in it Object mode. There are all shortcuts for object mode in Blender and you can add more. At end of list there should be Add New button, click it, type in left field object.unity_rotation_fix_x for simple fix or object.unity_rotation_fix_xz for full fix and choose key shortcut. However if you right-click on rotation fix button in tool shelf you should find Add Shortcut menu entry, it will let you very easily choose shortcut for button without going through manual configuration.
     
  25. Kyron

    Kyron

    Joined:
    Mar 12, 2013
    Posts:
    1
    Thanks a bunch pal! I was going crazy with the difference between axis. I think I tried every combination possible with the ftx exporter, trying to fix this.

    This is exactly what we need. Simple tools that let us focus on the job at hand.
     
  26. Smaples

    Smaples

    Joined:
    Oct 29, 2013
    Posts:
    12
    First of all many thanks for those kind of tools and work. But unfortunately I can not get my expected results. So when I try to export only a bone with the fbx exporter and import this into unity then the bone has every time other rotation settings as the amature in local system. This happens with or without this fix. Can somebody please explain me step by step how to export from blender so that the mesh, its amature and its bone have the same orientation/rotation in local coordination-system.
     
  27. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    My addon only works with objects, not sub-objects, so bones are unaffected. Unfortunately I do not see any way to fix bone rotation, those are more complicated. Unless Blender devs changes coordinate system to match Unity (which is unlikely) I don't think it will be possible to completely fix this problem. If I find workaround I will update addon.
     
  28. Smaples

    Smaples

    Joined:
    Oct 29, 2013
    Posts:
    12
    Hey, thanks four your reply and work. I reported this problem in a blender forum to fix the fbx exporter, too. But generelly I think Unity should provide an import so it is possible to use .blend files out of the box without the detour over fbx (I read If you attach a .blend to unity... it will use the internal fbx exporter of Blender).
     
  29. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    255
    I use the stock FBX exporter, and have no problem with the coordinate conversion, for both dumb meshes and mesh/armature models. The only caveat is that the mesh/armature models appear to be laying on their face in the Project view preview icons, but appear upright and work properly when dropped into the Hierarchy. This is true whether I give a .blend file to Unity, or I export manually with Blender's FBX exporter.

    However, I can't access my Unity / Blender machines from this office so I'll take screenshots of the FBX exporter settings this afternoon.
     
  30. Smaples

    Smaples

    Joined:
    Oct 29, 2013
    Posts:
    12
    Some screenshots would be greate. But bear in mind to set the unity system to "local" to see the rotation conversion of the bones. But maybe its an version conflict. So I tired Blender 2.69 and 2.65. Which Blender and Unity Version are you using?

    Yesterdy, I opened another post becuase I think my problem differs from the normal rotation hack of this thread. I think its better to post the sceenshots there.
    http://forum.unity3d.com/threads/20...t-wrong-bone-rotation-relative-to-its-amature
     
  31. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    In most cases mesh rotation doesn't impose much problems. It is problematic in situations when you want to use mesh as particle emitter, have specific needs for object or just want to have working preview.

    If you look at inspector of object with mesh renderer you will notice it has rotation on x axis and if you reset this rotation it will lay on its face, as I wrote previously my addon counters this rotation.
     
  32. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    255
    I've posted to that thread as well, because I think it's fundamental to understand how Blender and Unity's coordinate systems differ.
     
  33. Smaples

    Smaples

    Joined:
    Oct 29, 2013
    Posts:
    12
  34. Holographic

    Holographic

    Joined:
    Dec 28, 2013
    Posts:
    11
    Hey guys. I did my animations etc then used the latest version of the add on to export to fbx and I'm getting this message. Couple of things.. the original scale i set it to is gone - everything scaled up once flipped. Also the fbx file is only 1 kb.. there's nothing in it. anyone got any help here as i saved the file after flipping so might be a days work down the swanny! Cheers

    $fbx export.jpg
     
  35. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    Well, I tested addon on latest official build and couldn't reproduce error. Looking at error contents, it doesn't seem like it has anything to do with rotation fixer. Are you sure your Blender installation isn't corrupted or something?
     
  36. Holographic

    Holographic

    Joined:
    Dec 28, 2013
    Posts:
    11
    Sorry forgot about this one..up to my eyeballs. I was using an old rig from a much earlier version of blender.. must have been the reason it went all pear shaped. I'll test it on the new rig i have... if ya dont hear from me we all good ;)
     
  37. Holographic

    Holographic

    Joined:
    Dec 28, 2013
    Posts:
    11
    Actually whats the difference between the simple rotation fix and full rotation fix? also nothing actually happens when i hit the button. Is this proper cause on the other old rig I used the objects rotated forward 90
     
  38. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    I probably should rename those. Difference is whatever you use +Y or -Y as forward axis in your blender workflow. Use simple rotation fix if your models face -Y, otherwise use full rotation fix.

    Addon automatically transforms object so it appears to not change, otherwise you would have to rotate it back to place manually. If you switch coordinates from global to local then you will notice that after applying fix Z axis points forward of model instead of up, just like in Unity.
     
    Last edited: Jan 3, 2014
  39. Holographic

    Holographic

    Joined:
    Dec 28, 2013
    Posts:
    11
    Brill that seems to work with everything. And no need to set z forward etc as it was originally facing -Y right?
     
  40. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    Yes, if you model with -Y as forward then apply simple rotation fix and you don't have to change fbx export options.
     
  41. basilbits

    basilbits

    Joined:
    Jan 3, 2014
    Posts:
    110
    keep up the good work
     
  42. cocodrilo555

    cocodrilo555

    Joined:
    Feb 15, 2014
    Posts:
    2
    Hi, first thanks for this script and also i may add some bug-fix,

    i was getting some 90.0001213151581º numbers after the full rotation and i wonder ... mhhhh, then read the script and incremented the decimals on the pi and pi/2 numbers, TA-DA!! now it works more precisely. :D


    Code (csharp):
    1.  
    2. import bpy
    3.  
    4. bl_info = {
    5.  "name": "Unity Tools",
    6.  "author": "Karol \"Mirgar\" Głażewski",
    7.  "version": (1, 0, 2),
    8.  "blender": (2, 6, 5),
    9.  "location": "3D View > Tool Shelf > Unity Tools",
    10.  "description": "Tools to ease workflow with Unity Engine",
    11.  "warning": "",
    12.  "wiki_url": "",
    13.  "tracker_url": "",
    14.  "category": "Object"}
    15.  
    16. # fixes rotation on X axis, +X is -X in Unity compared to Blender
    17. class UnityRotationFixerX(bpy.types.Operator):
    18.  
    19.     bl_description = "Fixes rotation of object so it will not \"lay on its face\" in Unity, +X axis is -X compared to Unity"
    20.     bl_label = "Simple rotation fix"
    21.     bl_idname = "object.unity_rotation_fix_x"
    22.     bl_options = {'REGISTER', 'UNDO'}
    23.  
    24.  
    25.     def FixRotationForUnity3D(self):
    26.         bpy.ops.object.transform_apply(rotation = True)
    27.         bpy.ops.transform.rotate(value = -1.5707963267948966192313216916398, axis = (1, 0, 0), constraint_axis = (True, False, False), constraint_orientation = 'GLOBAL')
    28.  
    29.         bpy.ops.object.transform_apply(rotation = True)
    30.         bpy.ops.transform.rotate(value = 1.5707963267948966192313216916398, axis = (1, 0, 0), constraint_axis = (True, False, False), constraint_orientation = 'GLOBAL')
    31.  
    32.     @classmethod
    33.     def poll(cls, context):
    34.         return context.mode == 'OBJECT' and context.area.type == 'VIEW_3D'
    35.  
    36.     def execute(self, context):
    37.         self.FixRotationForUnity3D()
    38.         return {'FINISHED'}
    39.  
    40. # fixes rotation on X and Z axis, front is now +Y
    41. class UnityRotationFixerXZ(bpy.types.Operator):
    42.  
    43.     bl_description = "Fixes rotation of object, +Y is now front"
    44.     bl_label = "Full rotation fix"
    45.     bl_idname = "object.unity_rotation_fix_xz"
    46.     bl_options = {'REGISTER', 'UNDO'}
    47.  
    48.     def FixRotationForUnity3D(self):
    49.         bpy.ops.object.transform_apply(rotation = True)
    50.  
    51.         bpy.ops.transform.rotate(value = -1.5707963267948966192313216916398, axis = (1, 0, 0), constraint_axis = (True, False, False), constraint_orientation = 'GLOBAL')
    52.         bpy.ops.transform.rotate(value = -3.1415926535897932384626433832795, axis = (0, 1, 0), constraint_axis = (False, True, False), constraint_orientation = 'GLOBAL')
    53.  
    54.         bpy.ops.object.transform_apply(rotation = True)
    55.  
    56.         bpy.ops.transform.rotate(value = 1.5707963267948966192313216916398, axis = (1, 0, 0), constraint_axis = (True, False, False), constraint_orientation = 'GLOBAL')
    57.         bpy.ops.transform.rotate(value = 3.1415926535897932384626433832795, axis = (0, 0, 1), constraint_axis = (False, False, True), constraint_orientation = 'GLOBAL')
    58.     @classmethod
    59.     def poll(cls, context):
    60.         return context.mode == 'OBJECT' and context.area.type == 'VIEW_3D'
    61.  
    62.     def execute(self, context):
    63.         self.FixRotationForUnity3D()
    64.         return {'FINISHED'}
    65.  
    66. class UnityPanel(bpy.types.Panel):
    67.  
    68.     bl_idname = "OBJECT_PT_unity_tools"
    69.     bl_label = "Unity Tools"
    70.     bl_space_type = 'VIEW_3D'
    71.     bl_region_type = 'TOOLS'
    72.     bl_context = "objectmode"
    73.     bl_options = {'DEFAULT_CLOSED'}
    74.  
    75.     def draw(self, context):
    76.  
    77.         layout = self.layout
    78.  
    79.         col = layout.column(align=True)
    80.         col.label(text="Rotation:")
    81.         col.operator("object.unity_rotation_fix_x")
    82.         col.operator("object.unity_rotation_fix_xz")
    83.  
    84. #registers    
    85.  
    86. def register():
    87.     bpy.utils.register_class(UnityRotationFixerX)
    88.     bpy.utils.register_class(UnityRotationFixerXZ)
    89.     bpy.utils.register_class(UnityPanel)
    90.  
    91. def unregister():
    92.     bpy.utils.unregister_class(UnityRotationFixerX)
    93.     bpy.utils.unregister_class(UnityRotationFixerXZ)
    94.     bpy.utils.unregister_class(UnityPanel)
    95.  
    96. if __name__ == "__main__":
    97.     register()
    98.  
    99.  
     
  43. Holographic

    Holographic

    Joined:
    Dec 28, 2013
    Posts:
    11
    Oh dear. I'm having some issues here. I have to change my model..bring in a new object and attached it to the character.. say new head. Do I have to apply simple rotation fix to this model too? Originally unity was ok with everthing, but with the changes the head and legs are offset and the humoid rigging is not recognising part of the upper leg (without hitting the rotation fix).. dabbling with it now but be great to know the workaround
     
  44. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    Could you post step by step description what you do and where is the problem?

    Normally you apply rotation fix before skinning, however if your model looks and works in way you're satisfied you may not need to apply rotation fix to it.
     
  45. Holographic

    Holographic

    Joined:
    Dec 28, 2013
    Posts:
    11
    Heya Mirgar. Not getting notices for this thread. keep forgetting. In the main image is the new import where the model is pear shaped. Yu can see in the assets the original file that works perfect. So this is what has happened when I broguht in athe model with adjustments
     

    Attached Files:

  46. Jago

    Jago

    Joined:
    Aug 28, 2009
    Posts:
    30
  47. Mirgar

    Mirgar

    Joined:
    Aug 6, 2012
    Posts:
    18
    @Jago
    I tested this exporter in development builds and it doesn't support blendshapes, is little buggy with modifiers and animations seem to not work correctly. Over time it will probably get better than current exporter, for now it is usable only for most basic stuff.
     
  48. Jago

    Jago

    Joined:
    Aug 28, 2009
    Posts:
    30
    Thanks Mirgar.
     
  49. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    228
    A while ago I found this gem online, I did not read this entire thread, but thought I would share so the efforts could be combined.

    http://blenderartists.org/forum/sho...y-rotation&s=1c8571ae930f8bd9bb4c8aeee22fccf6

    I hope they add a fix like to the import in Unity 5, as having to patch this file each update is annoying.
    I will be e-mailing support with this file as well, perhaps they will get one of their 3D import devs to give it a proper look.


    Code (CSharp):
    1.  
    2. ##########################################################
    3. # Custom Blender -> Unity Pipeline
    4. # http://www.mimimi-productions.com, 2014
    5. # Version: 1.9
    6. # Only for Blender 2.58 and newer
    7. #
    8. # Thanks to kastoria, jonim8or and Freezy for their support!
    9. # Special thanks to Sebastian hagish Dorda for implementing the sort methods.
    10. # http://www.blenderartists.org
    11. ##########################################################
    12. # Fixes the -90 degree (x-axis) problem for Unity.
    13. # Artists and coders simply work as they should.
    14. # -> No more custom rotation-fixes in Unity or Blender.
    15. ##########################################################
    16. # HISTORY
    17. # 1.9, CLEANUP -- removed support for old Blender versions, only support 2.58 and newer
    18. # 1.8, FIX -- applies transforms in order (parents prior childs)
    19. # 1.7, FIX -- shows hidden objects prior importing
    20. # 1.6b, FIX -- Apply mirror modifiers before rotating anything else
    21. # 1.6a, FIX -- deselect all objects, otherwise deleting wrong objects when using UNITY_EXPORT flag
    22. # 1.6, FEATURE -- support UNITY_EXPORT flag --> set via MiBlender-Tools or e.g.: bpy.data.objects['enemy_small']['UNITY_EXPORT'] = False
    23. # 1.6, FIX -- now import empties
    24. # 1.5, FIX -- make all objects single user, otherwise instances can't be imported
    25. # 1.4, FIX -- show all layers, necessary for rotation fix
    26. # 1.3, FIX -- location constraints are now deactivated (due to rotation prior to export)
    27. # 1.2, FIX -- apply rotation worked only on selection! (thx jonim8or)
    28. # 1.1, FIX -- object mode doesn't need to be set in file anymore
    29. ##########################################################
    30. # TO DO
    31. # ISSUE -- do not use empties as parents (rotation can't be applied to them!)
    32. # ISSUE -- transform animations are missing because we are not exporting the default take --> thus only bone-animations are working?!
    33. # ISSUE -- LIMIT_LOCATION animation constraint is forbidden! Will be muted and not work in engine (anim might look different compared to Blender)
    34. # 2.0, FEATURE -- support UNITY_EXPORT_DEFAULT_TAKE --> can export no-bone-animations to Unity
    35. ##########################################################
    36.  
    37. import bpy
    38.  
    39. try: import io_scene_fbx.export_fbx
    40. except:
    41.     print('error: io_scene_fbx.export_fbx not found.')
    42.     # This might need to be bpy.Quit()
    43.     raise
    44.  
    45. import os
    46. import math
    47. from mathutils import Matrix
    48. from functools import cmp_to_key
    49.  
    50. # SORTING HELPERS (sort list of objects, parents prior to children)
    51. # root object -> 0, first child -> 1, ...
    52. def myDepth(o):
    53.     if o == None:
    54.         return 0
    55.     if o.parent == None:
    56.         return 0
    57.     else:
    58.         return 1 + myDepth(o.parent)
    59.  
    60. # compare: parent prior child
    61. def myDepthCompare(a,b):
    62.     da = myDepth(a)
    63.     db = myDepth(b)
    64.     if da < db:
    65.         return -1
    66.     elif da > db:
    67.         return 1
    68.     else:
    69.         return 0
    70.  
    71. # Operator HELPER
    72. class FakeOp:
    73.     def report(self, tp, msg):
    74.         print("%s: %s" % (tp, msg))
    75.  
    76. # Find the Blender output file
    77. outfile = os.getenv("UNITY_BLENDER_EXPORTER_OUTPUT_FILE")
    78.  
    79. # Rotation matrix of -90 around the X-axis
    80. matPatch = Matrix.Rotation(-math.pi / 2.0, 4, 'X')
    81.  
    82. # do the conversion
    83. print("Starting blender to FBX conversion " + outfile)
    84.  
    85. # deselect everything to close edit / pose mode etc.
    86. bpy.context.scene.objects.active = None
    87.  
    88. # activate all 20 layers
    89. for i in range(0, 20):
    90.     bpy.data.scenes[0].layers[i] = True;
    91.  
    92. # show all root objects
    93. for obj in bpy.data.objects:
    94.     obj.hide = False;
    95.  
    96. # make single user (otherwise import fails on instances!) --> no instance anymore
    97. bpy.ops.object.make_single_user(type='ALL', object=True, obdata=True)
    98.  
    99. # prepare rotation-sensitive data
    100. # a) deactivate animation constraints
    101. # b) apply mirror modifiers
    102. for obj in bpy.data.objects:
    103.     # only posed objects
    104.     if obj.pose is not None:
    105.         # check constraints for all bones
    106.         for pBone in obj.pose.bones:
    107.             for constraint in pBone.constraints:
    108.                 # for now only deactivate limit_location
    109.                 if constraint.type == 'LIMIT_LOCATION':
    110.                     constraint.mute = True
    111.     # need to activate current object to apply modifiers
    112.     bpy.context.scene.objects.active = obj
    113.     for modifier in obj.modifiers:
    114.         # if you want to delete only UV_project modifiers
    115.         if modifier.type == 'MIRROR':
    116.             bpy.ops.object.modifier_apply(apply_as='DATA', modifier=modifier.name)
    117.  
    118. # deselect again, deterministic behaviour!
    119. bpy.context.scene.objects.active = None
    120.  
    121. # Iterate the objects in the file, only root level and rotate them
    122. for obj in bpy.data.objects:
    123.     if obj.parent != None:
    124.         continue
    125.     obj.matrix_world = matPatch * obj.matrix_world
    126.  
    127. # deselect everything to make behaviour deterministic -- instead of "export selected" we use the UNITY_EXPORT flag
    128. for obj in bpy.data.objects:
    129.     obj.select = False;
    130.  
    131. # apply all(!) transforms
    132. # parent prior child
    133. for obj in sorted(bpy.data.objects, key=cmp_to_key(myDepthCompare)):
    134.     obj.select = True;
    135.     if(obj.get('UNITY_NOFIX', False)) == True:
    136.         print("Skipping UNITY_NOFIX item")# do nothing
    137.     # delete objects with UNITY_EXPORT flag
    138.     # if flag not saved, then assume True
    139.     elif obj.get('UNITY_EXPORT', True) == False:
    140.         bpy.ops.object.delete()
    141.     # apply transform if not deleted
    142.     else:
    143.         bpy.ops.object.transform_apply(rotation=True)
    144.     # deselect again
    145.     obj.select = False;
    146.  
    147. #export_default_take = bpy.context.object['UNITY_EXPORT_DEFAULT_TAKE'];
    148.  
    149. # custom args
    150. kwargs = dict(    # we dont need the rotation in the exporter anymore
    151.                 # global_matrix=Matrix.Rotation(-math.pi / 2.0, 4, 'X'),
    152.                 use_selection=False,
    153.                 # we need 'EMPTY' for placeholder-transforms and helpers -- but artists can choose to not export them via UNITY_EXPORT flag
    154.                 object_types={'ARMATURE', 'MESH', 'EMPTY'},
    155.                 use_mesh_modifiers=True,
    156.                 use_anim=True,
    157.                 use_anim_optimize=False,
    158.                 use_anim_action_all=True,
    159.                 batch_mode='OFF',
    160.                 # TODO: used only for animated objects without bones -- artists have to define this manually
    161.                 use_default_take=False,
    162.                 )
    163.                
    164. # export!
    165. io_scene_fbx.export_fbx.save(FakeOp(), bpy.context, filepath=outfile, **kwargs)
    166.  
    167. print("Finished blender to FBX conversion " + outfile)
    168.  
     
  50. randomperson42

    randomperson42

    Joined:
    Jun 29, 2013
    Posts:
    975
    This is really helpful, thanks.