Search Unity

Blender Linked Duplicates workflow

Discussion in 'Asset Importing & Exporting' started by Jessy, Sep 20, 2009.

  1. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    What I need to do is get a level, created in Blender, into Unity. The Blender scene contains a bunch of objects; some animated, some not. In Blender, I have made use of "Linked Duplicates", which allows me to use the same mesh and bone data for multiple objects.

    However, when I import the level into Unity, it's clear that a new mesh is created for each instance of an object. It's not so easy to tell what is going on with bones, but considering the names of the game objects in the hierarchy where bones should be are appended with numbers, I assume those are getting real copies also.

    I want to reuse data. What's the workflow solution, then?
     
  2. GusM

    GusM

    Joined:
    Aug 27, 2005
    Posts:
    585
    I would use a parent object (maybe a null is enough) for transforming the instances in Blender, then in Unity make a prefab with the file, deleting the unnecesary models but keeping the parent GO. Finally, still inside Unity,duplicate again the original model and parent the new copies to the nulls again, reseting the transforms. Save changes to the prefab, and you should get the result you are looking for in Unity and still get it updated when you change something at the blend file.
     
  3. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Parenting armatures in Blender results in duplication of everything that is parented, in Unity. Fortunately, It seems that creating a prefab of a Blender scene with an object that is parented to an armature works nicely. (This does mean, however, that I can't use the Armature modifier.) I can then rotate that prefab 90 degrees on X, and insert it in the completed scene, using an armature in the scene as a parent for the prefab, and then it is placed correctly.

    I'm sorry, but I am having extreme trouble understanding this sentence. Could you clarify?


    Edit...
    Okay, I've given it some more though, and as far as I can tell, it looks like what you're saying will let me update the prefab that gets instanced. That's useful, but what I really want is to be able to make changes to the whole level, and not have to reassign the prefabs every time. Because that's exactly what happens in Blender, I think it's stupid that it doesn't carry over via FBX export. But I guess I have to find some way to deal with that shortcoming.
     
  4. GusM

    GusM

    Joined:
    Aug 27, 2005
    Posts:
    585
    I asume there is no way to get Blender instancing inside Unity directly, so I propose a workaround: import the file as it is now, then inside Unity use one copy of the full file to build one prefab including just one single animated model, deleting all the rest. And then add in a second copy of the full file and create a new prefab with it. Last, delete all the copies of the animated model from the last prefab and replace them with instances of the first prefab you built. It involves some work, but you will get the result I think you were looking for: a big prefab including several copies of the same animated model, all with the same data.

    I sugested to use a null as the parent for each instance of the animated models, in Blender, as helping targets for replacing them in Unity later with the prefab.

    I hope it is not too confusing...

    Edit: Just saw your last edit: I think with the method I described you should get both prefabs updated after your changes in Blender. Give it a try and let me know if it works as expected.
     
  5. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    I have now learned from trying several methods, that if you make a prefab that contains data imported from an FBX, the reference to the original FBX data is lost. That really, really sucks, and I don't yet know how I'm going to deal with that.
     
  6. GusM

    GusM

    Joined:
    Aug 27, 2005
    Posts:
    585
    Using the blend files does neither allow to use Blender instanced animated models. I gave it a try and I see the animation distorted in the moved instances. best method I have found in your situation is to only include the original animated mesh and skeleton in your blend file, without the instances, and then in Unity build a prefab of it, duplicating and re-arranging the copies there. No problem if you do this way, you will keep the model and animations editable and automatically updated too. Attached is a simple example, import the package in Unity, put a copy of the prefab at the scene and then open up the blender file and make some change in the mesh. You will see the prefab updated just fine.
     

    Attached Files:

  7. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Unity is not much of a 3D editor. I can't accept that workflow.

    If the mesh data is edited, that translates to Unity. But object-level transformations do not.

    I really do appreciate your help. I don't mean to be negative, but this is very bad workflow. I am currently trying to put together an editor script that we can all use to make life merrier.
     
  8. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Ok, here's a .unitypackage which I hope is worthy of going in your Standard Packages folder. :-D


    I realized that I could do better than just transferring linked duplicates to Unity. What I've come up with so far allows you to take an FBX file, and automatically replace any objects in it you choose with prefabs. So not only does instancing of meshes and armatures transfer over automatically, but you can also add whatever components you like, to the prefabs, in Unity, then edit the transforms of the prefabs in Blender (this is best done by using linked duplicates, made from linked objects), and have the Unity hierarchy automatically update based on those transforms.


    Here's how you do it:

    The package contains two scripts. EditorFBX_Sync goes into a folder called Editor in the Project pane. You don't need to worry about that one at all.

    You attach the FBX_Sync script to any GameObject in the hierarchy that you want to sync with an FBX file. You then drag any FBX file from the Project pane onto the FBX variable slot, and you drag any of the prefabs that you want to sync (also from the Project Pane), onto the Prefabs slots. (You set Size to be the total number of prefabs you want to sync.)

    (It should be noted that you can drag any child object shown in the Project Pane onto the FBX slot. However, the sync will still happen for the full FBX file itself. That's just the way Unity does things - try dragging the child into the Hierarchy, and you'll have the whole file imported. I'll figure out over time if it's worth trying to override this behavior.)


    Here's what happens:

    When selecting an FBX file in the Project pane, and choosing the FBX To Hierarchy Using Prefabs command from the Assets menu, if the the imported file is the one you set as FBX for any of the FBX_Sync scripts you attached, those game objects with FBX_Sync attached will then be updated so that their child hierarchy matches the FBX file of their FBX variable slot.

    However, for every object whose name contains the name of one of the Prefabs, the prefab will be added to the hierarchy instead, and it will take on the transform properties of the matching object. All the other items that do not correspond to the prefabs will be added to the Hierarchy as-is.


    Currently, the prefabs themselves do not automatically sync, but I will come up with a solution for that as I learn more about how components are put together when Blender files are imported into Unity.

    Also, I would prefer that saving the .blend, or importing/reimporting an FBX file, would make this process happen automatically. However, until I can figure out a way around this problem, or the bug I logged about it gets addressed, then the menu item is the best idea I have.

    I'm obviously totally new with this workflow, but considering the short time it took me to come up with this (most of the time I spent was trying to find workarounds to bugs), how little code it is, and how useful/essential this is, I have a hard time believing that this kind of thing hasn't been built into in Unity itself yet. Is there some reason for that that I'm missing? Is there a similar solution floating around on the forum or wiki that I haven't stumbled across yet:?:

    It's not great to have to worry about naming conventions, but I think that's a lot better than the alternative of time-consuming, repetitive manual labor. If someone has a better idea than relying on naming, please let me know. I plan to add this to the wiki in a more robust form, after I implement whatever I need to, to get the prefabs to sync automatically.
     

    Attached Files:

  9. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Here is an updated version. I've added two features:

    1. FBX_Sync now has an array of strings, called "Omit From Scene". Any Game Objects in the FBX file that include any of these strings will not be imported into the Hierarchy/Scene. This is especially useful in order to get rid of stuff that doesn't translate over to Unity, such as lights that you only want to use for modeling. With Blender, typing in "Lamp" and "Camera" will do the trick. :)

    Children of omitted objects, regardless of name, will also be omitted. The alternative is to create an empty Game Object in the hierarchy where the omitted object was. I think I like it as is. Please give me feedback on this.

    2. If you parent the objects that you want to use as prefabs, to other prefab objects, in Blender, then the hierarchy will be updated appropriately. (In the previous version, only the highest-level prefab would have remained.) This requires the included script named "FBX_SyncPrefab" to be somewhere in the project, outside of the Editor folder.

    This seems to work perfectly for objects without an armature, based on my limited testing. However, the FBX exporting process "gets weird" if armatures are parented to other armatures (at least with Blender). I'll see what I can do about that down the road. Ideally, somebody would just make a better FBX exporter. I'm not particularly interested in doing that, and don't have the know-how for it at the moment. I'd probably prefer to pay somebody to do this, when I can afford it. If you are willing to take on the project, please let me know. I keep a running list of "people to hire when I'm rich". :D

    Seriously. I do.


    Edit...

    3. FBX_Sync now has an array of strings, called "Exclude". This allows you to be able to name objects more similarly to prefabs and omissions, and not have them replaced.

    e.g. I just had a mesh called "Teeth", and the floor it was on was called "TeethFloor". Even though Teeth is a prefab, I can stop TeethFloor from getting replaced with the Teeth prefab, by typing "TeethFloor" into one of the Exclude slots.
     

    Attached Files:

    zosichd likes this.