[ADDON ] UE Tools

That’s it! Thanks for update!:slight_smile:

Looks interesting. Will have a look at it when i work with the next time (:

I guys I just update the Addon, now is version v1.2 and include the tools for the animations, I update the first post with a video and also you can check the documentation :wink:

Greetings!

Hi again :wink:

Manuel Odendahl did a patch to have the “add hero rig” functionality work on mac, I had a problem with the file paths (basically using “/” instead of “”) and only worked on windows. I update the addon on the server

Greetings!

2.74 is out and have some changes for the fbx export so i update the addon to meet the new API. Also I made a couple changes

  • In this update I remove the check box for export with or without smoothing shading,The new version export take into the account the normals of the faces by default , so is fine , if you have flat shading in some faces and smooth in others , will export correctly. ( if you need select face or edge when export for smoothing , let me kno
  • The new version also have an option for bake the animation in all bones, this is good because avoid a big problem with the locations of the bones, I show this problem on the animation tools video some days ago and how I deal with that but we don’t need to do anymore.
  • Also I made a change on the workflow for export animations and characters. I remove the pop ups asking for rotate 180º because I found I don’t need anymore. I append the Hero (so facing -y) and I just press export character and the same for the animations. I do some test with the hero and with MakeHuman rigs and work fine. If you find you need rotate 180º the character for some reason let me know , the code is on the addon , just commented, so ignored.

Also yesterday I made a video for show to someone here on the forum how create the animation and use the animation on the default character provided on the templates , so if you are interested take a look, just a couple minutes:

https://.com/watch?v=YJtXegvXZKE

The download is updated on the main page of the addon but also I post a direct link here

Greetings!

Playing with 2.74 right now, thanks for updating the addon, I will test asap.

Realy cool , thank

Thanks for this great gift to all users ^^

Hello Louis!
When you try to export, there is a problem:

version 2.74
I would be grateful for your help!

Ohai, that looks really cool!

I think I’ll dig into the code and refactor some things, so be warned :stuck_out_tongue:

Hi Agilardo](https://forums.unrealengine.com/member.php?34706-Agilardo) , What are the steeps you do before get this error , I can’t replicate. Maybe you can give me some clue.

I add this simple meshes and press the export button with the same settings you have “export tools” , “static” etc…

Try to re-download and reinstall, Maybe help, really I not remember if I did some change just after the release, so do it just to be safe :wink:

Greetings! I wait for more info

I am sure if this tools is able to export a full scene. I mean, I have a file with thirty different objects that are cloned to create a full building. The final buildings has 300 objects using that initial 30 ones. There are a big number of array and mirror modifiers, and also objects cloned in random positions.

For what I see this tool helps exporting evey object to FBX instead of having to go one by one. It is useful to export that 30 objects I have in my file. But how I export that 300 objects that comprises the full building I am modeling? Is this tool of any help with this? In Unity it is possible to import a file, and it takes care of arrays, mirrors, and other cloned objects, so everything is imported in the correct posistion, rotation and scale.

Is this tool useful for this? If not, are there any tool for doing this? Or is this thing only possible if using 3DSmax or Maya with Unreal?

Hi, For cases like that, well I not recommend have a building made it by 300 pieces unless you want the building to use as the whole level, if is for decorate the environment normally are less pieces.

Unfortunately UE4 only can import FBX. The FBX have a problem, the origin point of the object must be the center of the scene before export if no , will place the origin point in bad position (with the addon I can cheat that). The problem here is, if you have arbitrary positions in for each of this 300 objects and you want export this objects with the pivot point in correct place. You need something on UE4 side , to reposition this objects (I’m working on a tool for that) because on the FBX are not included the “world position” for the objects.

If you want export the whole building, you have options, 1, export as if was 1 single mesh (in case you can) or 2 center the building to the scene select all pieces and export to FBX (if you use the addon , uncheck “pivot to center”). This last will export all piece, in 1 file), but with the pivot point of each piece at the center of the scene.

Normally in UE4 , the workflow is , build the level inside UE4 as a prototype with blocking shapes, then made the modular pieces on , using the blocking sizes etc… , and then replace the bloking shapes for the modular pieces inside UE4.

For maya I only see a plugin for UE4 that can do what you want

I hope that help , greetings!

Great Tool thank you very much. Is there a feature to auto rename, with “Auto Creation” Button generated deform bones form a Makehuman sekeleton, so that the deform bone names fit to the unreal skeleton?I would like to re-target the default unreal animations in Unreal to my new character…

Hi GameChanger23](https://forums.unrealengine.com/member.php?26024-GameChanger23) , Thanks for you suggestion, I will study but really I don’t know if will work … first, with Make Human you can export the character with different skeletons , and some have more bones, some less …also on nightly builds there is a skeleton UE4 compatible (I must take a closer look). In other hands I think the best workflow in case you want to use the “default” animations is start by skin you character to the hero rig skeleton event if you want add some more bones to that skeleton.

But yea I will think about, some ideas come to my mind like recognize if is human skeleton and if it is rename the needed bones, I don’t know, for made the tool more generic and usable in more cases ( no idea is something like that will work). Also come to my mind the name of the tool in case some day exist “HeroTize” :stuck_out_tongue:

Greetings!

Will this create the correct Pivots for the individual objects? If so, you are my Hero! Any rough timeline for it?

aWinter](https://forums.unrealengine.com/member.php?34702-aWinter) Yes , will create the correct pivots for individual objects. I have some ideas , and some tests about that. Basically what I want to do is, in write a external file with all the positions for the objects, and then in UE4 create a blueprint where add all the meshes as components and create a blueprint function library for rebuild the scene by reading the external file (1 step). Apart of finish a couple projects I need learn some more c++ for that so really no idea about the timeline. But maybe some one can do it before me. The 2 step will be a UE4 plugin for update in real time the positions, rotations etc of the objects in the scene…something like the plugin for maya. I really don’t know if I can accomplish this 2 step, my programing skills are limited, but I will try it , so at least I will learn something more.

GameChanger23](https://forums.unrealengine.com/member.php?26024-GameChanger23) I play a little bit with you idea and well no lucky for now :(, so I’ll leave it for now. When I finish this couple projects I have I will return to the addon and I will see if i can do something.

I’ll explain what I did, I create a little rough script for rename some Make Human bones ( I use the MH default skeleton, bunch of bones, the skeleton you can see on the video).
By renaming the bones only, the retarget not work so I try to export only the bones with the same name of the “default” skeleton, also not work and I had some issue with missing weights (expected) when I import. BTW, I also try export the MH character in T pose, not with the pose by default (arms down)

So I suppose I must do some more things, maybe the roll of the bones, Maybe I must add more bones to the skeleton , like the Ik bones on the default hero skeleton on the templates (the bones that seems not do anything and are little bit mess when you import to ) no idea maybe both or maybe any of that.

This is the script if you want to try, open the scirpt on and before do the “auto-create” for auto search the deform bones, run the script. Alternatively delete the bone gorup “DeformBones” and run the script:



import bpy

def CheckExistingBone(str):
    
    Bonelist = bpy.context.object.data.bones
    
    for bone in Bonelist:
        if bone.name == str:
            bone.name = str+"H"
      
Bonelist = bpy.context.object.data.bones
HeroTizedBones = ]

for bone in Bonelist:
    if bone.name == "DEF-head":
        CheckExistingBone("head")
        bone.name = "head"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
    
    elif bone.name == "DEF-neck":
        CheckExistingBone("neck_01")
        bone.name = "neck_01"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
    
    elif bone.name == "DEF-hips":
        CheckExistingBone("pelvis")
        bone.name = "pelvis"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-spine":
        CheckExistingBone("spine_01")
        bone.name = "spine_01"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-chest":
        CheckExistingBone("spine_02")
        bone.name = "spine_02"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-chest-1":
        CheckExistingBone("spine_03")
        bone.name = "spine_03"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-thigh.R":
        CheckExistingBone("thigh.R")
        bone.name = "thigh_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-thigh.L":
        CheckExistingBone("thigh.L")
        bone.name = "thigh_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)    
    
    elif bone.name == "DEF-shin.01.R":
        CheckExistingBone("calf_r")
        bone.name = "calf_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-shin.01.L":
        CheckExistingBone("calf_l")
        bone.name = "calf_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-foot.R":
        CheckExistingBone("foot.R")
        bone.name = "foot_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-foot.L":
        CheckExistingBone("foot.L")
        bone.name = "foot_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-toe.R":
        CheckExistingBone("ball_r")
        bone.name = "ball_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-toe.L":
        CheckExistingBone("ball_l")
        bone.name = "ball_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-clavicle.R":
        CheckExistingBone("clavicle.R")
        bone.name = "clavicle_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-clavicle.L":        
        CheckExistingBone("clavicle.L")
        bone.name = "clavicle_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-upper_arm.R":
        CheckExistingBone("upperarm_l")
        bone.name = "upperarm_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-upper_arm.L":
        CheckExistingBone("upperarm_r")
        bone.name = "upperarm_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-forearm.01.R":
        CheckExistingBone("lowerarm_r")
        
        bone.name = "lowerarm_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-forearm.01.L":
        
        CheckExistingBone("lowerarm.L")
        bone.name = "lowerarm_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-hand.R":
        
        CheckExistingBone("hand.R")
        bone.name = "hand_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-hand.L":
        CheckExistingBone("hand.L")
        
        bone.name = "hand_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    #Fingers R
        
    elif bone.name == "DEF-thumb.01.R":
        CheckExistingBone("thumb.01.R")
       
        bone.name = "thumb_01_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-thumb.02.R":
        CheckExistingBone("thumb.02.R")
       
        bone.name = "thumb_02_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-thumb.03.R":
        CheckExistingBone("thumb.03.R")
        
        bone.name = "thumb_03_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_index.01.R":
        
        bone.name = "index_01_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
    
    elif bone.name == "DEF-f_index.02.R":
       
        bone.name = "index_02_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_index.03.R":
        
        bone.name = "index_03_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_middle.01.R":
        
        bone.name = "middle_01_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_middle.02.R":
        
        bone.name = "middle_02_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_middle.03.R":
       
        bone.name = "middle_03_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_ring.01.R":
      
        bone.name = "ring_01_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_ring.02.R":
       
        bone.name = "ring_02_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_ring.03.R":
        
        bone.name = "ring_03_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_pinky.01.R":
        
        bone.name = "pinky_01_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_pinky.02.R":
       
        bone.name = "pinky_02_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_pinky.03.R":
       
        bone.name = "pinky_03_r"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    #Fingers L
    
    elif bone.name == "DEF-thumb.01.L":
        CheckExistingBone("thumb.01.L")
        
        bone.name = "thumb_01_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-thumb.02.L":
        CheckExistingBone("thumb.02.L")
        bone.name = "thumb_02_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-thumb.03.L":
        CheckExistingBone("thumb.03.L")
        
        bone.name = "thumb_03_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_index.01.L":
        
        bone.name = "index_01_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
    
    elif bone.name == "DEF-f_index.02.L":
        
        bone.name = "index_02_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_index.03.L":
        
        bone.name = "index_03_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_middle.01.L":
        
        bone.name = "middle_01_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_middle.02.L":
        
        bone.name = "middle_02_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_middle.03.L":
        
        bone.name = "middle_03_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_ring.01.L":
        
        bone.name = "ring_01_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_ring.02.L":
        
        bone.name = "ring_02_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_ring.03.L":
       
        bone.name = "ring_03_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_pinky.01.L":
       
        bone.name = "pinky_01_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_pinky.02.L":
        
        bone.name = "pinky_02_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
        
    elif bone.name == "DEF-f_pinky.03.L":
        
        bone.name = "pinky_03_l"
        if bone.name not in HeroTizedBones:
            HeroTizedBones.append(bone.name)
  

bpy.ops.object.mode_set( mode='POSE' )
 
#Store visible bone layers

Bonelayers = bpy.context.object.data.layers
VisibleBoneLayers=]
for layer in Bonelayers:
   if layer == True:
       VisibleBoneLayers.append(True)
   else:
       VisibleBoneLayers.append(False)
 
 
#Enable All bone layers
for n in range(0,32):
    bpy.context.object.data.layers[n] = True

 
#Deselect All bones
bpy.ops.pose.select_all(action='DESELECT')
 
 
#Reselect the bones   
BonesSelected=]
 
for b in Bonelist:
    if b.name in HeroTizedBones:
        b.select=True
        BonesSelected.append(b.name)
        
     
#Asign The group
    
if  BonesSelected != ]:      
 bpy.ops.pose.group_assign()
 bpy.context.object.pose.bone_groups'Group'].name = "DeformBones" 
else:
 self.report({'ERROR'}, "Any bones have vertex associated")
 
#Restore Visible Layers
 i=0
 for n in range(0,32):
    bpy.context.object.data.layers[n] = VisibleBoneLayers*
    i=i+1
 
bpy.ops.object.mode_set( mode='OBJECT' )



And this is how I rename the bones:

MakeHuman Original bones = Renamed names

DEF-head = head
DEF-neck = neck_01
DEF-hips = pelvis
DEF-spine = spine_01
DEF-chest = spine_02
DEF-chest-1 = spine_03
DEF-thigh.R = thigh_r
DEF-thigh.L = thigh_l
DEF-shin.01.R = calf_r
DEF-shin.01.L = calf_l
DEF-foot.R = foot_r
DEF-foot.L = foot_l
DEF-toe.R = ball_r
DEF-toe.L = ball_l
DEF-clavicle.R = clavicle_r
DEF-clavicle.L = clavicle_l
DEF-upper_arm.R = upperarm_r
DEF-upper_arm.L = upperarm_l
DEF-forearm.01.R = lowerarm_r
DEF-forearm.01.L = lowerarm_l
DEF-hand.R = hand_r
DEF-hand.L = hand_l

DEF-thumb.01.R = thumb_01_r
DEF-thumb.02.R= thumb_02_r
DEF-thumb.03.R = thumb_03_r
DEF-f_index.01.R = index_01_r
DEF-f_index.02.R = index_02_r
DEF-f_index.03.R = index_03_r
DEF-f_middle.01.R = middle_01_r
DEF-f_middle.02.R = middle_02_r
DEF-f_middle.03.R = middle_03_r
DEF-f_ring.01.R = ring_01_r
DEF-f_ring.02.R = ring_02_r
DEF-f_ring.03.R = ring_03_r
DEF-f_pinky.01.R = pinky_01_r
DEF-f_pinky.01.R = pinky_02_r
DEF-f_pinky.01.R = pinky_03_r

DEF-thumb.01.L = thumb_01_l
DEF-thumb.02.L= thumb_02_l
DEF-thumb.03.L = thumb_03_l
DEF-f_index.01.L = index_01_l
DEF-f_index.02.L = index_02_l
DEF-f_index.03.L = index_03_l
DEF-f_middle.01.L = middle_01_l
DEF-f_middle.02.L = middle_02_l
DEF-f_middle.03.L = middle_03_l
DEF-f_ring.01.L = ring_01_l
DEF-f_ring.02.L = ring_02_l
DEF-f_ring.03.L = ring_03_l
DEF-f_pinky.01.L = pinky_01_l
DEF-f_pinky.01.L = pinky_02_l
DEF-f_pinky.01.L = pinky_03_l

Results:

&stc=1

&stc=1

Any idea?

And for the rest, what do you think about the “heroTize”, “herotify” whatever feature?
I’m continue thinking that is better skin the character to the hero Rig/skeleton or jsut retarget manually inside UE4 but maybe I’m wrong

Greetings!

I don’t know if you solved this but I have just been trying this addon (seems great so far!) and had this pop-up a couple of times.

In short, just close and reopen . I think it has something to do with the ‘Open UE Tools’ button when you first load up not appearing if you open a different project after working on one with UE Tools. Once clicking ‘Open UE tools’ (which only appears on a restart of ) it seems the project is then configured to use the addon and the error doesn’t reoccur.

That said I have no knowledge scripts / Python so I may be making this up completely xD

Edit: My error codes actually seem to be different, as below. Your error may not be as simply solved. Also, disabling tangent space stopped another whole load of error messages.

BlenderError.png

Hi Doug](https://forums.unrealengine.com/member.php?12577-Doug) , About the firts problem “Bake_anim_use_all_bones” no I not fix it , but with you info I will investigate again and see if I see something, the problem with tangent space maybe is related but I can’t reproduce an error.

About the second error, I try what you say, have a blend file opened, inicialize the addon, Export a simple cube with the “Relative:UE Assets” checked (I should put a error message here because have no sense export to a relative folder if previously you not have the file saved in some place, now this is allowed, maybe is the cause, now is exported to installation folder if the file is not saved), then File-> New, to open a new file and I see on the field for introduce the custom path , by default apear text on it “Custom Export Folder” also for the custom name field (this should not happen). I have an idea of why this happen so I try to fix but meanwhile, If you remove this text this error should not appear.

test.PNG&stc=1

Thanks for you report, If you find any clues related to the first error, please let me know

Greetings!

Amazing work. Does this plugin also make it possible to import and edit, exported UE4 animations?