EdyJ / blender-to-unity-fbx-exporter

FBX exporter addon for Blender compatible with Unity's coordinate and scaling system.
MIT License
947 stars 98 forks source link

Improvement(?) #25

Closed Kai764 closed 2 years ago

Kai764 commented 2 years ago

Thank you very much for this addon, it really makes with importing Blender models into Unity a lot easier!

While all the individual object's positions and rotations are correct, it seems like I still need to rotate the whole model by 180° on the Y-axis in Unity to make it face in the right direction.

So I tried making a fix for it (the comments in the code should hopefully be self explanatory, although I am not 100% sure about why some of my code segments seem to be required for it to work correctly). Maybe there is a better way, but this seems to work in all scenarios I tested (including more than one child object).

This is the code starting from line 130. I have also attached the full file below (although as .txt, as .py files are not supported for uploading in this case):

# Reset parent's inverse so we can work with local transform directly
        reset_parent_inverse(ob)

        # Create a copy of the local matrix and set a X-90/Z-180 matrix
        mat_original = ob.matrix_local.copy()       

        rot_x = mathutils.Matrix.Rotation(math.radians(-90.0), 4, 'X')
        rot_z = mathutils.Matrix.Rotation(math.radians(-180.0), 4, 'Z')

        ob.matrix_local = rot_x @ rot_z 

        # Apply the rotation to the object
        apply_rotation(ob)

        if (ob.parent):
            # Reapply the previous local transform with an X+90 and Y+180 rotation
            ob.matrix_local = mat_original @ mathutils.Matrix.Rotation(math.radians(90.0), 4, 'X') @ mathutils.Matrix.Rotation(math.radians(180.0), 4, 'Y')
        else:
            # Reapply the previous local transform with only an X+90 rotation
            ob.matrix_local = mat_original @ mathutils.Matrix.Rotation(math.radians(90.0), 4, 'X')

            # Correct position by inverting X and Y values
            loc_or = ob.location        
            ob.location = (-loc_or.x, -loc_or.y, loc_or.z)

            # Correct rotation by inverting Y value
            rot_or = ob.rotation_euler
            ob.rotation_euler = (rot_or.x, -rot_or.y, rot_or.z)

Hope this helps and of course please let me know if you have any suggestions or if there might be a better way!

blender-to-unity-fbx-exporter.txt

EdyJ commented 2 years ago

Thank you for your contribution, but this seems a specific scenario applicable to your case only.

In Blender, the "Front" direction is -Y (object facing the negative Y direction). Surely your objects are facing the positive Y direction when all their rotations are 0. This means their natural orientation is facing "Backwards". They conserve this orientation when imported in Unity, so you see that they need an additional rotation of 180 degrees. It's not a fault in the exporter.

The solution is adhering to the Blender convention for the "Front" direction, which is -Y (negative Y). This fbx exporter assumes this convention, so trying to fix any possible corner cases outside it is out of the scope of the add-on.

Kai764 commented 2 years ago

Thank you for your response.

I know this is a bit of a hackery, compared to the simple 90° X-axis fix. But every model I imported with this addon needed to be rotated by 180° to get it facing in the right direction.

But do you mean I am using Blender's coordinate system wrong? This is how my objects face in Blender:

Blender Rotation

So should I actually always have my models facing the opposite direction inside Blender (regardless of whether I want to export them to Unity)? To me, the way I have it currently seems more intuitive, but of course if it's just wrong, I will change my models. Then your original rotation script should work perfectly as well without needing to do any changes of course.

Let me know!

EdyJ commented 2 years ago

Exactly, your model is actually facing backwards in Blender. This is the correct orientation for a cone pointing in the Front direction:

image

When this model is exported to FBX and imported into Unity, the -Y direction will be translated to the +Z direction, which is the Front direction in Unity.

You can verify the Front direction in Blender by pressing Numpad-1, which brings the "Front Orthographic" view. In this view you must be seeing the front of your model, in this case the tip of the cone:

image

Kai764 commented 2 years ago

Thank you for the heads up, I will then change the orientation of my models, which would make all my changes to the script redundant of course. With all the swapped axes compared to Unity, it still seems a bit weird to me that +y means backwards and +x means left, but I guess I have to get used to it...

EdyJ commented 2 years ago

Pretty much every 3D software out here arbitrarily chooses their coordinate system and the meaning of each axis. Here's an (incomplete) example: image image

Kai764 commented 2 years ago

Thank you for this graph, I didn't know the coordinate systems were that arbitrary...

Personally, Z forward, Y up and X right makes the most sense to me, like Unity or DirectX have it. Unreal also seems good enugh to me, just with Y forward and Z up. But for the rest it looks a bit unintuitive to be honest.

I guess you have to make the best out of it, and at least your addon will work without any problems then.