B2U 2.0 for Blender 2.8x Released with Price Drop!

Hi!
Will check about it. Can be a bug in our code. Thanks for report! :wink:

Is the new version released?

Sorry the Delay in post it here but since last week B2U 2.0 is released! I was trying to make a short video about this release but the video will need to wait for a bit more.

With the 2.0 version we also make a permanent price drop to $14,99. We think that it’s a fair price and will help many other users to purchase it for their projects.

This is the release log of the 2.0 version:

  • New core to Support to Blender 2.8x
    • New importer system to Support Unity 2019.3
    • Support to Build-In, HDRP and URP Shaders.
    • Now Based on Eevee for Blender’s Previews
    • Unified material setup at the Principled in Eevee
    • Transparency Settings are now based on Eevee Settings for Build-in Pipeline
    • Fixed many bugs and new UI improvements

If you find any bugs or doubts contact us in blendermarket or by e-mail (if purchased in Unity Asset store)

4 Likes

Thanks for the wonderful update! :partying_face: i’ll be putting B2U2 through the hard testing. I did want to second Sasa42’s idea of exporting prefabs and linked duplicates. I’d love to build out a level with Blenders advanced instances and snapping tools and have, position, rotation, scale and instance carry over into Unity.

Is there a process for this? :thinking:

This is exactly what B2U does if you have instances in blender. That means duplicate linked objects (that share the same mesh data) instead of unique objects. :wink:

2 Likes

Hi!
Just wonna make sure before I buy the plugin: Can it convert any shader made in blender into unity shader?

No. It only map a subset of nodes connected to the principled as base and set those values/colors/textures/ to unity native shaders (you chose the destination shader that will be used in unity)

Hi, in Blender Market there is only the unity package to download. Where can I find the addon for Blender?
Blender Market - B2U

Hi.
Install the unitypackage in your unity project. The blender exporter is inside it.

1 Like

Thank you. That worked. :+1:

A couple of critical bugs I’ve noticed in 2.0.1 so far:

  1. The Unity importer script is hard-coded to only work for locales that use “,” as a decimal separator, so does not function correctly in locales that use a “.” (North America, UK, etc). Specifically objects without a scale in Blender are imported with a scale of (10, 10, 10), as “1.0” gets interpreted as “10”.
  2. The importer script also looks for the B2U name prefix anywhere in a models name. As the prefix defaults to “_”, B2U tries to process any model that contains an underscore anywhere in its name (and a LOT of models do!), resulting in script errors as there is no further checking of whether the corresponding B2U files actually exist.

Fixes:

  1. Replace every occurrence of:
float.Parse(something.Replace(".", ","))

with:

float.Parse(something, CultureInfo.InvariantCulture);
  1. In OnPreprocessModel() replace:
if (assetPath.Contains(B2U_Importer.prefixPrefab))

with:

if (Path.GetFileName(assetPath).StartsWith(B2U_Importer.prefixPrefab))

and in OnPostprocessModel(GameObject obj) replace:

if (obj.name.Contains(B2U_Importer.prefixPrefab))

with:

if (obj.name.StartsWith(B2U_Importer.prefixPrefab))

I also wrapped the code in both areas in checks that the files actually exist before trying to load them:

if (File.Exists(prefab_path)) { ... }

Having said that, v2.0 is working much better than v1.x did once these fixes are applied.

2 Likes

Thanks Nutter. Will take a look on it

We just released a new round of bug fix for B2U 2.0 with initial support to Empty Objects in Scene and Collection Export.

  • Fix bugs with Location and Units (Fixed by Nutter)
  • Fix Prefab names with suffix identifier appearing other than in start (Fixed by Nutter)
  • Automatically fix material names if needed (Remove spaces and some other invalid characters)
  • Added Support to Empty Objects in Scene and Collection Export.
1 Like

For me, only works once, i export sucessfully a model, but to the next try, my model got bad scale and don’t export the material so my model is white.

But the first time exports good.

Hi there,
I think I have found at least three more bugs/issues. I provide the solution that works for me.

1st: Array- and Mirrior-Modifier are not well applied (it seams to be the wrong axis)

I fixed it for me by exchanging the dublicateObject() method in the exporter:

def duplicateObject(sceneCollection, name, copyobj):
    # Create new mesh
    depsgraph = bpy.context.evaluated_depsgraph_get()
    object_eval = copyobj.evaluated_get(depsgraph)
    
    mesh_eval = bpy.data.meshes.new_from_object(object_eval)
    
    # Create new object associated with the mesh
    ob_new = bpy.data.objects.new(name, mesh_eval)
 
    ob_new.scale = copyobj.scale
    ob_new.location = (0,0,0) # Fix bug of the Unity
    ob_new.rotation_euler = copyobj.rotation_euler
 
    # Link new object to the given scene and select it
    #scene.collection.objects.link(ob_new)
    sceneCollection.objects.link(ob_new)
    ob_new.select_set(True)

    return ob_new

2nd: An object in a collection with disabled attribute “Export Object” ends up in a crash of the importer at line 737 (NullReferenceException). This is caused by an empty structure from the exporter (ln 733 and following).

a) I made the importer more robust by adding the line

if (objTemp != null) continue;

in line 736

b) I do not let create the empty structure by adding a check if the object is marked as selected.
For this I have to reorder the code a little bit, so I will provide the hole block.
ln 763,764 and 741,742 are moved to the end depending on the new condition if(Obj in ObjectsToExport):

    # -------------- Cria XML dos Collections -------------
    if(bpy.context.scene.B2U_Settings.use_collection):
        for collection in bpy.data.collections:
            path_collection = assetsPath + "/B2U/Editor/Data/Collections/" + collection.name +".b2uc"
            #out_file_collection = open(path_collection,"w")
            #out_file_collection.close()

            collection_root = ET.Element("Collection")

            #ET.SubElement(collection_root ,"Path").text = Models_Local + "/" + collection.name + ".prefab"
            #ET.SubElement(collection_root ,"NoCache").text = str(random.randrange(0,10000)) # Force makes a diferent file so always reimport the group

            for Obj in collection.objects:

                if(Obj in ObjectsToExport):

                    if Obj.type == "EMPTY":
                    
                        loc, rot, sca = Obj.matrix_world.decompose()
                        rot = rot.to_euler()

                        # The scale is always local in Unity
                        sca = Obj.scale

                        Pos =  [ round(elem, 5) for elem in loc]
                        Rot = [ round(elem, 5) for elem in rot ]
                        Sca = [ round(elem, 5) for elem in sca ]

                        vec = mathutils.Euler((Rot[0],Rot[1],Rot[2]),"XYZ")
                        euler_final = vec.to_matrix()
                        euler_final = euler_final.to_euler("XZY")

                        obj = ET.SubElement(collection_root, "Empty")
                        ET.SubElement(obj, "Name").text = str(Obj.name)
                        ET.SubElement(obj, "Position").text = str((Pos[0],Pos[2],Pos[1]))
                        ET.SubElement(obj, "Rotation").text = str((math.degrees(euler_final[0]),math.degrees(euler_final[1]),math.degrees(euler_final[2])))
                        ET.SubElement(obj, "Scale").text = str((Sca[0],Sca[2],Sca[1]))

                        parent = Obj.parent
                        if parent == None:
                            parent_name = "None"
                        else:
                            parent_name = parent.name

                        ET.SubElement(obj, "Parent").text = str(parent_name)

                    # Export Objects
                    if Obj.type == "MESH":

                        loc, rot, sca = Obj.matrix_world.decompose()
                        rot = rot.to_euler()
                        parent = Obj.parent
                        # The scale is always local in Unity
                        sca = Obj.scale

                        Pos =  [ round(elem, 5) for elem in loc]
                        Rot = [ round(elem, 5) for elem in rot ]
                        Sca = [ round(elem, 5) for elem in sca ]
                        Prefab = Obj.data.name

                        vec = mathutils.Euler((Rot[0],Rot[1],Rot[2]),"XYZ")
                        euler_final = vec.to_matrix()
                        euler_final = euler_final.to_euler("XZY")

                        obj = ET.SubElement(collection_root, "Object")

                        ET.SubElement(obj, "Name").text = str(Obj.name)
                        ET.SubElement(obj, "Prefab").text = str(Models_Local + "/" + bpy.context.scene.B2U_Settings.prefixPrefab + Prefab + ".fbx")
                        ET.SubElement(obj, "Position").text = str((Pos[0],Pos[2],Pos[1]))
                        ET.SubElement(obj, "Rotation").text = str((math.degrees(euler_final[0]),math.degrees(euler_final[1]),math.degrees(euler_final[2])))
                        ET.SubElement(obj, "Scale").text = str((Sca[0],Sca[2],Sca[1]))

                        parent = Obj.parent
                        if parent == None:
                            parent_name = "None"
                        else:
                            parent_name = parent.name

                        ET.SubElement(obj, "Parent").text = str(parent_name)
                            
                    out_file_collection = open(path_collection,"w")
                    out_file_collection.close()

                    ET.SubElement(collection_root ,"Path").text = Models_Local + "/" + collection.name + ".prefab"
                    ET.SubElement(collection_root ,"NoCache").text = str(random.randrange(0,10000)) # Force makes a diferent file so always reimport the group

                    indent(collection_root)
                    FileOut = ET.ElementTree(collection_root)
                    FileOut.write(path_collection)

3rd: Bug or feature? I tried to make a transparency material and set in the eevee settings BlendMode to “Alpha Hashed” (which should end in Transparency I assumed). This is not the case. May I just do not understand how to use it. So please help me out. But in the meantime I made the following change:
Adding line

if (value == "HASHED") { mat.SetFloat("_Mode", 3.0f); }

after line 266 in the importer fixed it for me.

I work every with this changes and I hope you will find these hints useful too.

Hi Jesaro17
To export materials after the first export you need to check the “Update Materials”.
About bad scales after the first export can you send a scene to us to check in blendermarket inbox system?

Thanks will check about those. :wink:

Argh, sorry, thats wrong (boolean, if I meet you in the night!). If the statement is written this way (not a block afterwards) it has to be

if (objTemp == null) continue;

because we want to avoid executing the code following this line.
Sorry for that.

1 Like

Hm, unfortunately exported objects have a scale of 100 (instead of 1) when dropped into a Unity scene and the rotation is off. Using Unity 2019.3.10.f1, tried with Blender 2.90 and 2.82.7. So this requires some extra steps from the user to fix it. Using Blender’s own eport to FBX works fine on the other hand. The objects have transformations applied and do not have any parents.
Would be great, if this issue could be fixed. Thanks!

If this is happening there was a problem during the export or import process. Check for errors at the console in blender or unity.