Search Unity

Blender imports to unity: What's with this silly hack?

Discussion in 'General Discussion' started by Nanako, Oct 24, 2014.

  1. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    hi all. i'm having some issues with animated objects importing to blender, and it's taken me a while to figure out why, thanks to this site:

    http://www.edy.es/dev/2014/02/a-better-blender-to-unity-3d-importer/

    I think i'll let him explain the problem, much better than i could

    To put it mildly, this is really really really NOT NICE. And i feel inclined towards using stronger words, but i'm being civil.

    Aside from the fact that this implementation is an utterly lazy hack which, in any situation, causes as many problems as it solves, there is a much bigger issue:

    There is no problem to fix in the first place

    Here's a quick screencap of the blender .fbx dialog:


    Note near the top, there are two options with dropdown boxes. Forward, and Up. These convert the exported file at that time, to translate between different axis systems. It's the clean and correct solution to this problem. Fixing it was always blender's responsibility, not unity's.

    What unity is doing is actually UN-FIXING the issue, by counteracting the fix i've already applied in blender. This is pretty horrible.

    As a result of this, my simple imported cube looks like this:

    I'm not even sure why the Y offset is baked in there, that's from the middle keyframe of an animation. and Y being 180 doesn't look right either, but the X rotation is the main issue

    I point-blank refuse to adapt to this, i will not let unity's hack be the solution to anything. You can't just do that, it's like building a castle on quicksand. The whole point of computing is to build a solid foundation that works perfectly, and then build ontop of that. Anything that's rotten at the core is always going to cause problems later.


    anyways, in the above-mentioned site, there is a solution, he's written a script to fix it that replaces the default importer. I'm not convinced that's the correct solution either though, since it is doing something. In order to use it, i would have to not-use blender's Up/forward export settings, and let that importer handle things entirely.
    Also, using it requires several awkward steps of specifically naming files with instructions in the filename, which i'd consider to be both a messy implementation, and an introduction of pointless extra work into the pipeline

    As far as i can tell, the best solution to this issue would be to literally do nothing. Let me fix my files at authortime when i'm exporting from blender. Those settings are sticky, and blender has an inbuilt Preset option that i can easily setup for working with unity.

    What i'd like to know is, how can i just turn off this behaviour entirely. I've already had to fix the stupid 0.01 scale thing with fbx imports, i need this done too. I want unity to do absolutely nothing but import my files as they are. Let me do the fixing.

    Can anyone give me a barebones editor script that might accomplish this ?
     
  2. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Well i got really mad, did some learning, and attempted to write a fix myself. it seems that zeroing out the rotation in postprocessing doesn't do anything at all, which i find thoroughly confusing.

    i'm now attempting to adapt the importer from that link to just be always-on and not require special instructions.
     
  3. peteorstrike

    peteorstrike

    Unity Technologies

    Joined:
    Oct 4, 2013
    Posts:
    116
    Not an fbx file format expert (I wouldn't understand it even if I could read it) but I always presumed that when you set Forward to Z-Forward and Up to Y-Up (as it should be for Unity) in the Blender exporter (or even when you set 'Y-up' in 3ds Max's exporter, as it suffers from the 'other-handedness' issues as well) then the exporter is simply applying a -90 0 0 rotation to force the 'wrong-for-Unity' axes to point in the 'right-for-Unity' direction when imported.

    Unity is presumably reading whatever the fbx file format stored for the transforms when it imports and things automatically sorta look how you'd expect (but with that weird rotation that the fbx exporter applied) - Unity is probably not changing anything or adding transforms on importing the file itself. I don't know if fbx files store any data on there having been a Y-up tag set or not - presumably it just slaps that rotation correction on, lets the X-axis be automatically flipped and hopes for the best. I can try and find out for sure what the files are actually doing on import when I'm back in the office next week, though.

    It's worth noting that this issue happens even when sending files between Max and Maya, and Autodesk own the fbx format, so it's seemingly something non-trivial to solve. Even with your Z-forward, Y-up overrides your X-axis will have to point the opposite way to how it did back in Blender due to the inherent differences between the two handedness-systems. It's a known annoyance and I'm not sure on the best way to solve it - I often resort to using Maya to freeze the transformations of Max or Blender files before a second, final export to Unity. If Unity or the fbx exporter zeroed out the transforms in the fbx file post-export then you lose the files original orientation (i.e. when you load your blender fbx back into Blender, it will then have the wrong orientation - inverse of the current issue you're having). I'm not a fan of destructively altering transforms on export either, as that creates its own issues on complex rigs and the like.

    Generally the best solutions I've found is to either do a pre-export axis correction (set a +90 0 0 on the transform axis, so that it loads in at 0 0 0 pointing the right way) or to run some kind of asset post processor to fix; hopefully some proper Blender users can chime in with recommendations for that.

    But I do sympathise, as it's annoyed me enough times as well and I'm hopeful we can find some way to elegantly solve this in the future...
     
  4. wbakunis

    wbakunis

    Joined:
    Jan 28, 2014
    Posts:
    50
    Yea, this is such an annoying problem. I personally was able to correct the 90 degree issue by applying the rotation "control + A" and just using the .blend file instead. When you do go to use the .blend file, just click and drag to your scene hierarchy "not the scene screen" itself. The model will then set its' "forward facing direction" to -90. In my case, my truck is forward facing in the x-axis and set itself to -90.

     
  5. 0tacun

    0tacun

    Joined:
    Jun 23, 2013
    Posts:
    245
    randomperson42 and Nanako like this.
  6. steego

    steego

    Joined:
    Jul 15, 2010
    Posts:
    969
    Take a look at this
     
  7. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    the importer script from the link in the OP looks as though it works fine. It literally just reconfigures the mesh by moving the vertices around, to (i think) make everything work as desired. Of course it's kind of long and complex because of that, but importing is something so rarely done (by computing standards) that several seconds extra processing time doesn't seem so bad.

    Btw when i say rare, i mean in comparison to code that runs every frame, or somesuch. importing is something that has a lot more time to complete, and a lot lower expectations from the user in terms of performance. Working Right is most preferable.

    Why not try contacting the author to buy rights to his code, or replicate that sort of solution ?
     
  8. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    This script seems to do literally nothing at all to affect the problem despite adding massive amounts of code. Does it work for you? i've probably set it up wrong...

    I copy all of his code and paste them to replace the three specified lines at the end of the unity importer python script, right? just after else ?

    maybe my problem is that i'm exporting to fbx first and then importing to unity. I just tried importing my .blend directly and it fails:

    That's BS, my blender version is 2.72
    Reverting back to the old script seems to fix that issue though (i kept a backup of course)

    also, the author seems to have vanished months ago, and as far as google can tell, never did post it to polycount.
     
    Last edited: Oct 25, 2014
  9. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Can anyone explain why zeroing out the rotation in postprocessing does nothing? My code DOES work, and it fixes the numbers shown in the model properties, but it doesn't actually change how the object is rotated

    I'm using this editor script:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System;
    4. public class CustomImportSettings : AssetPostprocessor
    5. {
    6.     public const float importScale= 1.0f;
    7.     void OnPreprocessModel()
    8.     {
    9.         ModelImporter importer = assetImporter as ModelImporter;
    10.         importer.globalScale = importScale;
    11.     }
    12.  
    13.     void OnPostprocessModel (GameObject thisThingy)
    14.     {
    15.         thisThingy.transform.rotation = new Quaternion(0, 0, 0, 1);
    16.     }
    17. }
    (I did try temporarily disabling this while testing the script steego linked)
     
  10. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    this isn't a fix at all. the rotation of the animations is still messed up
     
  11. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    This... works. Ugh. I don't like how it's being done, it's kind of destructive to authortime. i don't consider this a solution. But it only adds one easy step to the pipeline and makes my animations work properly too. I can use this as an interim fix until i find a real solution.

    barely adequate, but i'm definitely not done looking for a better way.
     
    drawcode likes this.
  12. Nanity

    Nanity

    Joined:
    Jul 6, 2012
    Posts:
    148
    Thanks Nanako for the discussion, hopefully this will get sorted out someday before 5.0 release.

    Code (Import pipeline):
    1. > Unity asset importing > .fbx exporter settings
    2. > Blender runtime > .blend file > .fbx exporter > .fbx file
    3. > .fbx import
    From my understanding either Unity does not call the exporter properly with the Y-up / X-forward settings or the exporter does mess up the conversion.

    Of course it could be the unity importer, but if Peteorstrike is right, it leaves the coordinates alone. And needless to say it would be the wrong place to fix.

    Edit: Updated blender from 2.68 to 2.72 and it's apparently fixed. I reimported all meshes to be on the safe side.

    Edit 2: Animation keyframes are ignored by the fbx exporter settings, means it messes up all the objects you want to animate. So bug confirmed in latest blender version.
     
    Last edited: Oct 25, 2014
  13. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    okay, i finally got this working, seems i had to replace the .blend importer entirely.... and it's just dumb.

    It mirrors my object, whether i wanted it to or not (i don't, testing with an asymmetrical object) and it simply discards my animation data, which negates any usefulness. What the heck were they thinking?

    utterly worthless. I'm going back to my original idea of modding the script linked in the OP, i'll let everyone know how it goes.
     
  14. randomperson42

    randomperson42

    Joined:
    Jun 29, 2013
    Posts:
    974
  15. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    it's not exactly a bug. Blender completely rewrote the fbx exporter. The new exporter does not yet support shape keys. It is supposed to be in the final 2.72 release. I haven't been watching but if 2.72 has hit official release then it means they must have pushed the feature back for some reason.
     
  16. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    are shape keys important?
    as mentioned in my OP, i'm using 2.72, and it already supports binary FBX export, as shown in the picture.

    Unity is still rotating the assets on import, can we agree on that at least? Anything done in blender is only going to undo what unity is messing up. I don't think this issue is something that should be fixed on the blender end.
    Am i wrong?
     
  17. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    oops I saw the comment about animation key frames and misread it as shape keys. At any rate, I've been using the settings in the fbx exporter to change to y up and -z forward and not had any issues when importing but I haven't tried with animation either.
     
  18. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    Works just fine for me. Usually, I either bake the axis change or nest to compensate for difference, but since the 2.72 with binary/baking, I can do it in the export. I set it to Z Forward, Y Up and check Apply. The exported fbx appears in Unity with the exact axis orientation, and 0 rotation.
    Blender and Export Settings: BlenderExport.jpg

    FBX as it appears in Unity:
    UnityImport.jpg

    Haven't tried it with animations, the exporter says it is experimental for animations, and doesn't support blendshapes. So for those (for now), I do the usual way.
     
    peteorstrike likes this.
  19. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    Also, just wanted to say that the new exporter in 2.72 is fantastic across the board. (minus the blendshapes, and haven't tried the animation). But for static objects, it is a huge leap. Other than the axis baking, you have more control over how normal/edges are handled, the meshes I have been getting are much smaller, even with edge splits. Usually there was a decent amount of setting tweaks and adjustments when bringing stuff in from blender, but except for materials, it it pretty clean on the first pass.
     
  20. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    There is what you are doing wrong, you need to check "Apply Transform", otherwise it is just rotating the mesh and not baking it. That is why it appears to you that Unity is undoing your changes, it is because they were never applied. Try it with the Apply checked, it should do what you are expecting.

    Screen Shot 2014-10-25 at 7.03.46 PM.png
     
    peteorstrike likes this.
  21. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Last edited: Oct 26, 2014
  22. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    Depends on your project needs, but typically as @peteorstrike pointed out. To expand on that:

    Static/Non Animated or Procedurally controlled objects:
    Nothing, not an issue.

    Static/Animated or Procedurally controlled objects:
    1. Bake (R,X,-90,Return,Ctrl+A,R) in Blender then export or,
    2. Nest in empty parent in Unity, animate or control the parent.

    Animated in Blender with more than one element:
    Nothing, the import will work fine. The parent will have a null rotation, and the animation of the children's rotation will be compensated for already.

    Animated in Blender with only one element (not recommended):
    1. Add an empty object in blender, the export will work fine
    2. In Unity, as above, nest in parent and control the parent. (1. is better solution)

    If you animate a single element in Blender, the import will not contain a parent, so you will need to create it yourself. The animation values are relative, so without a parent it will animate relative to the world (0,0,0).


    Not enough information to give a 100% accurate answer, but presumably it is related to the stuff I pointed out above. If you animate a single object, the values will be relative. Generally you will need to parent it. Alternately there some settings in animation import window (root node options) that may be affecting it (or could be changed to correct).

    Though, I would suggest that for simple animations like hovering an rotating, just use Unity's animator, it is much less work and easier to edit.
     
  23. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,203
    Initial 2.72 release notes state that relative shape keys with support for baked animations were added to the exporter.
     
  24. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    Very cool. I just gave it a try with an old model I have that uses shape keys, and it worked perfectly. The internal meshes were 0 instead of -90 and the shapes keys worked just fine.
     
  25. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    odd, this does appear to be working. I guess i didn't check that box because A: I had already used apply rotaiton and scale, which i thought was what it meant, and B: it was marked scary and experimental.

    in any case, what exactly is this doing? Is it applying the opposite of what the unity importer does, so that it works out neutral again ?
     
  26. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    I tried 1. and it did work, for that particular object. However it broke the animation for transferring onto other single element objects, which was my original goal.

    As mentioned on the unity answers page
    The keycard asset from the tutorial already contains an animation that works perfectly, relative to wherever the object is placed, straight out of the box, with no parenting to anything imported or done within unity. It is clearly possible to create an animation asset that can accomplish this without any extra preparation. THAT is what i need to figure out how to do.
     
  27. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    Correct, if you are planning on using it on other objects, 1. will not work unless you replicate the structure and name the child the same as the animation.

    For that you will need to use option 2. A single object with animation attached. Since it is directly animating itself, naming isn't important. But in this case since the animation is controlling the position of the object itself, you will need to nest it in a parent or the animation will be relative to the scene.

    I assume you are referring to the Stealth project. It is indeed parented. The animation is attached to "prop_keycard", and is animating the child gameobject "prop_keycard_001". Because it is animating a named child, you will have to have the same structure and name. You will always need to do extra preparation/planning. That is what they did in the Stealth project.
    Screen Shot 2014-10-26 at 2.28.43 PM.png

    Moreover, if you want create an animation in something in Blender, and export it as an FBX, that animation will remain part of the FBX. (there are ways to export/extract just the animations, but I won't go into that). One way to do what you want is to set up the animation with an empty container and then just drop your chosen model into it. (ideally using generic names). Basically the same way the key card is set up. If you use that as an example, you can swap the keycard_001 with anything you want, just maintain the same name. Or even easier, just remove the renderer and mesh filter from the keycard_001 and drop your object inside that as a child.

    It will give you an empty object on the timeline, but it is a simple way to achieve what you are trying to do. There are other ways to go about it, (extracting the anim, generating separate anim files, or even building the anims in Unity, but the concepts are bit more complex, and involve much more planning and setup. Doing it with a container an and swapping is simple quick an effective.
    Screen Shot 2014-10-26 at 2.48.55 PM.png
    Screen Shot 2014-10-26 at 2.53.44 PM.png
    Screen Shot 2014-10-26 at 2.55.35 PM.png

    If you want to create your own using blender just drop an empty at 0,0,0 and animate the other, this ensures that a nested animation is created on import.
     
    Nanako likes this.
  28. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    If you applied the rotation and scale to the object in the scene, then you wouldn't need to apply them on export. (assuming you were applying the rotation to conform with the Unity axis, -90 x)

    When you use FBX binary and Apply Transform, it actually bakes the rotation into the mesh based on the settings. The unity import options don't change the mesh at all (for rotation), it just sets the default rotation of the objects transform. (you can see that in the inspector by scrolling down on the object to the imported object section.) It is just a convenience that Unity does to adjust for Blender's axis. But as you have noticed, this is problematic if you are trying to use that raw object. Usually you drop it into the scene adjust (null the rotation, reparent, ect), and create new prefab.

    Generally speaking you always have to perform adjustments, modification, cleanup to imported objects. You don't just drop them in and expect to use them. At a minimum you will clean up/apply materials, create/apply animator, set up your logic in the animator and make adjustments to the import settings. How you go about that, and where you actually do those things will depend on your project and pipeline.

    For example, for my personal or prototype/exploration projects, I will maintain two separate Unity projects. One for asset staging/assembly and one that is the game project. All my assets get dumped into the staging project where I clean up, animate rename and basically make them all nice and clean. I'll pack them all up into a prefab and then export them as package. I'll then import them into the game project. It keeps my game project nice and clean.

    For our production projects, which have thousands of assets that have to be consistent, we automate as much as possible and use templates and starter files to ensure that everything is as expected. Every model/animation/texture is named, separated and verified by a series of scripts in maya, and then again on packaging server. Large or small, asset management is always a challenge at some level, and preparation and planning is the best way to keep it under control.

    I wish I could tell you there is a quick and easy to understand solution, but really there isn't. It will vary from tool to tool, project to project and based on needs. I would suggest you take notes as you go as to what works and what doesn't to help from repeating mistakes, and just kind of accept that there will always be some challenge. Usually just when you really get it down, something will change. ;)
     
    Nanako likes this.
  29. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Ahh, this has been revealing, thank you.That's what i was missing.

    Although XXX_001 sounds more like a quick hack, and a lack of planning, to me. a real plan would have given it a generic, reuseable name, no?

    actually i really would like you to go into that. Or someone else, perhaps, i know you've spent a ton of time and effort on me already (it is hugely appreciated <3)
    I recently made a related question on that subject: http://answers.unity3d.com/questions/817243/why-cant-i-delete-the-unecessary-parts-of-an-fbx-i.html

    and related, why can't i also rename parts. If i could rename that keycard child for instance, to whatever my animation is targeting, then i could make my anim work. i'd rather do that, than make my animation target a stupidly specific name to make it function

    Can you see any problems that might come from generic names? like if i were to name every animated objkect i crate from now til the end of time, as "AnimObject" and put it inside a parent which holds the scripts/components/functionality/etc, would that cause any issues? like objects animating each other. or does everything only animate itself and its own children ?



    i'm a strong believer in doing things right, or not at all. This is too hacky and dirty for me.


    Anything worth doing in life is rarely simple, and never easy.

    RE: building the animations in unity. My understanding was that this system was deprecated and using it was a bad idea. is it still okay to do that if i'm using mecanim to actually play those animations? Because that really would be a good solution.
     
    Last edited: Oct 27, 2014
  30. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    Everyone works different. If it was only intended for that single use, might as well be specific.

    There are several approaches, typically scripted in the 3d app. I use maya for that, though I am sure it can be done in Blender, I haven't delved into it. Going that route is also a lot of setup and works best when you have a rock solid pipeline, and really need to have custom modifications to your asset flow. It also becomes inflexible, not a problem if your asset pipeline is established, but a real pain if you need to make changes and have to re-run all your assets. Alternately, you can "record" an readonly anim track, grabbing the keys and exporting it, but that isn't always perfect.

    And frankly, at this point I wouldn't bother. Unity 5 is going to allow you convert imported tracks into editable ones, so you will be able to save or at least copy and paste into a new anim.

    The term for that is "retargeting". As above, this is something that will be coming to U5 at some point. I did a write up on how to structure 2d animations to allow for a type of retargeting here: http://forum.unity3d.com/threads/2d-puppet-rigging-tips-tricks.245564/ Conceptually you can sort of do the same with 3d. But really it is just a workaround.

    However, that said, you can rename items in your animation. (as long as it is not one from an FBX), just ensure in your project>editor prefs you have asset serialization set to "Force Text". You can then open the .anim file in a text editor and do a find and replace. Not very elegant, but useful in a pinch.

    Yea, they are not linked or anything, it just looks for names in it self and children, so not a problem. I actually do exactly that fairly often. I have common UI or stage assets that are doing exactly the same thing, I have generic anim asset, with names like "assetContainer" or "rotationPoint". If you have repeated animations, it makes since to do do this so you dont have a bunch of asset that do the same thing. (I work primarily mobile, so I try to save space anywhere I can).

    Absolutely, only the legacy animation component that is used to play them is depricated, (replaced by mechanim). The actual animations and animation editor are core, and getting even better. Also you can control virtually anything inside of Unity with them, they are very powerful. And you can modify them right in the editor. Unless it something like an animated character, I usually handle all my animation right in Unity. I am a big fan of it. In addition to the example in the link about puppet rigs, here is another example of a prototype I did, it uses only the internal animation tools : http://forum.unity3d.com/threads/grid-game-best-way-to-start.258715/
     
    Nanako likes this.