├── LICENSE ├── README.md └── io_export_animationseparator.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 GutterLab 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BlenderToXenkoAnimationSeparator 2 | A blender 2.8 script that exports actions as separate fbx files for use in Xenko. 3 | 4 | ## Usage 5 | Install the addon and push f3 (windows default) to open the search. Type in Split Animation Export and select it. It will export all actions that are saved using a fake user (have the little F next to them) as individual fbx files in the same folder as your .blend file. The naming scheme is blendfilename_action.fbx. Import to xenko. Every fbx contains a single action, the mesh, and the skeleton. -------------------------------------------------------------------------------- /io_export_animationseparator.py: -------------------------------------------------------------------------------- 1 | bl_info = { 2 | "name": "Fbx Animation Splitter for Xenko", 3 | "category": "Import-Export", 4 | "version": (0,0,2), 5 | "blender": (2,80,0), 6 | "location": "File > Import-Export", 7 | "description": "Split Animation Export", 8 | "category": "Import-Export" 9 | } 10 | 11 | import bpy 12 | import os 13 | 14 | 15 | 16 | def main(context): 17 | startStates = [] 18 | blend_file_path = bpy.data.filepath 19 | directory = os.path.dirname(blend_file_path) 20 | 21 | # target_file = os.path.join(directory, os.path.splitext(context.blend_data.filepath)[0] + '.fbx') 22 | # bpy.ops.export_scene.fbx(filepath = target_file, check_existing = True, object_types = {'MESH'}) 23 | #record original state 24 | for i in range(0, len(bpy.data.actions)): 25 | print(str(i) + " " + str(bpy.data.actions[i]) + " " + str(bpy.data.actions[i].use_fake_user)) 26 | startStates.append(bpy.data.actions[i].use_fake_user) 27 | bpy.data.actions[i].use_fake_user = False 28 | 29 | for i in range(0, len(bpy.data.actions)): 30 | if bpy.data.actions[i].name == 'ArmatureAction': 31 | print('skipping') 32 | 33 | elif startStates[i]: 34 | bpy.data.actions[i].use_fake_user = True 35 | #export here 36 | 37 | context.object.animation_data.action = bpy.data.actions[i] 38 | context.scene.frame_end = bpy.data.actions[i].frame_range[1] 39 | 40 | target_file = os.path.join(directory, os.path.splitext(context.blend_data.filepath)[0] + '_' + bpy.data.actions[i].name + '.fbx') 41 | print(str(bpy.data.actions[i].name)) 42 | bpy.ops.export_scene.fbx(filepath = target_file, check_existing = False, object_types = {'ARMATURE', 'MESH'}, bake_anim_use_nla_strips=False, bake_anim_use_all_actions=False, bake_anim_force_startend_keying=False) 43 | bpy.data.actions[i].use_fake_user = False 44 | 45 | #revert to what it was 46 | for i in range(0, len(bpy.data.actions)): 47 | bpy.data.actions[i].use_fake_user = startStates[i] 48 | 49 | class SplitAnimations(bpy.types.Operator): 50 | """Split and Export Animations""" 51 | bl_idname = "object.splitanimations" 52 | bl_label = "Split and Export Animations" 53 | 54 | def execute(self, context): 55 | main(context) 56 | return {'FINISHED'} 57 | 58 | def menu_func(self, context): 59 | self.layout.operator(operator.SplitAnimations.bl_idname, text="SplitAnimations") 60 | 61 | def register(): 62 | bpy.utils.register_class(SplitAnimations) 63 | 64 | def unregister(): 65 | bpy.utils.register_class(SplitAnimations) 66 | 67 | if __name__ == "__main__": 68 | register() 69 | --------------------------------------------------------------------------------