Action nodes work better now
This commit is contained in:
@@ -3,6 +3,90 @@ import bpy
|
||||
ACTION_PROPS = ["name", "action", "action_text", "height", "radius", "tags"]
|
||||
FURNITURE_PROPS = ["name", "furniture_tags"]
|
||||
|
||||
test_tracking = {"lib_name": None}
|
||||
|
||||
class TEST_OT_LinkAndPlay(bpy.types.Operator):
|
||||
bl_idname = "test.link_and_play"
|
||||
bl_label = "Link and Play Sitting"
|
||||
|
||||
filepath: bpy.props.StringProperty()
|
||||
rig_name: bpy.props.StringProperty()
|
||||
action_name: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
target = context.active_object
|
||||
path = bpy.path.abspath(self.filepath)
|
||||
mesh_name = "Body"
|
||||
with bpy.data.libraries.load(path, link=True) as (data_from, data_to):
|
||||
# We request all three components
|
||||
data_to.objects = [n for n in [self.rig_name, mesh_name] if n in data_from.objects]
|
||||
data_to.actions = [self.action_name] if self.action_name in data_from.actions else []
|
||||
|
||||
# 2. Add to scene and create Override
|
||||
rig_obj = None
|
||||
for obj in data_to.objects:
|
||||
bpy.context.collection.objects.link(obj)
|
||||
obj.matrix_world = target.matrix_world
|
||||
if obj.type == 'ARMATURE':
|
||||
rig_obj = obj
|
||||
if obj.library:
|
||||
test_tracking["lib_name"] = obj.library.name
|
||||
|
||||
|
||||
if rig_obj:
|
||||
if not rig_obj.animation_data:
|
||||
rig_obj.animation_data_create()
|
||||
if data_to.actions:
|
||||
rig_obj.animation_data.action = data_to.actions[0]
|
||||
bpy.ops.screen.animation_play()
|
||||
return {'FINISHED'}
|
||||
|
||||
class TEST_OT_Cleanup(bpy.types.Operator):
|
||||
bl_idname = "test.cleanup"
|
||||
bl_label = "Stop & Cleanup"
|
||||
|
||||
def execute(self, context):
|
||||
if context.screen.is_animation_playing:
|
||||
bpy.ops.screen.animation_cancel(restore_frame=True)
|
||||
|
||||
lib_name = test_tracking.get("lib_name")
|
||||
if lib_name and lib_name in bpy.data.libraries:
|
||||
lib = bpy.data.libraries[lib_name]
|
||||
bpy.data.batch_remove(ids=(lib,))
|
||||
test_tracking["lib_name"] = None
|
||||
|
||||
# Deep purge orphans (meshes, armatures, etc)
|
||||
bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True)
|
||||
return {'FINISHED'}
|
||||
|
||||
class TEST_PT_ObjectPanel(bpy.types.Panel):
|
||||
"""Only appears in Object Properties when a 'position-' Empty is selected"""
|
||||
bl_label = "Character Placement Test"
|
||||
bl_idname = "TEST_PT_object_panel"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "object"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
obj = context.active_object
|
||||
return obj and obj.type == 'EMPTY' and obj.name.startswith("position-")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.label(text="Test Controls:", icon='OUTLINER_OB_EMPTY')
|
||||
|
||||
# Link button with preset arguments
|
||||
row = layout.row(align=True)
|
||||
op = row.operator("test.link_and_play", text="Link & Sit", icon='PLAY')
|
||||
op.filepath = "//../../edited-normal-male.blend" # SET YOUR FILEPATH
|
||||
op.rig_name = "male" # SET YOUR RIG NAME
|
||||
op.action_name = "sitting-chair" # SET YOUR ACTION NAME
|
||||
|
||||
# Cleanup button
|
||||
layout.operator("test.cleanup", text="Stop & Clear", icon='TRASH')
|
||||
|
||||
|
||||
class OBJECT_OT_CreateActionProps(bpy.types.Operator):
|
||||
"""Initializes custom properties on the selected action- empty"""
|
||||
bl_idname = "object.create_action_props"
|
||||
@@ -246,8 +330,6 @@ class OBJECT_PT_FurnitureEmptyPanel(bpy.types.Panel):
|
||||
op_use = layout.operator("object.create_child_action_node", icon='EMPTY_DATA', text="Add Sit Action Node")
|
||||
op_use.target_val = "sit"
|
||||
|
||||
classes = (TEST_PT_CharacterPanel, TEST_OT_LinkAndPlay, TEST_OT_Cleanup)
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(OBJECT_OT_CreateActionProps)
|
||||
bpy.utils.register_class(OBJECT_OT_CreateFurnitureProps)
|
||||
@@ -256,19 +338,12 @@ def register():
|
||||
bpy.utils.register_class(OBJECT_OT_DestroyChildByProp)
|
||||
bpy.utils.register_class(OBJECT_PT_FurnitureEmptyPanel)
|
||||
bpy.utils.register_class(OBJECT_OT_CreateChildActionNode)
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
bpy.types.Scene.test_filepath = bpy.props.StringProperty(name="File Path", subtype='FILE_PATH', default="//char.blend")
|
||||
bpy.types.Scene.test_obj_name = bpy.props.StringProperty(name="Rig Name", default="Character_Rig")
|
||||
bpy.types.Scene.test_action_name = bpy.props.StringProperty(name="Action", default="sitting")
|
||||
bpy.utils.register_class(TEST_OT_LinkAndPlay)
|
||||
bpy.utils.register_class(TEST_OT_Cleanup)
|
||||
bpy.utils.register_class(TEST_PT_ObjectPanel)
|
||||
|
||||
|
||||
def unregister():
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
del bpy.types.Scene.test_filepath
|
||||
del bpy.types.Scene.test_obj_name
|
||||
del bpy.types.Scene.test_action_name
|
||||
bpy.utils.register_class(OBJECT_OT_CreateActionProps)
|
||||
bpy.utils.register_class(OBJECT_OT_CreateFurnitureProps)
|
||||
bpy.utils.unregister_class(OBJECT_PT_ActionEmptyPanel)
|
||||
@@ -276,6 +351,9 @@ def unregister():
|
||||
bpy.utils.unregister_class(OBJECT_OT_DestroyChildByProp)
|
||||
bpy.utils.unregister_class(OBJECT_PT_FurnitureEmptyPanel)
|
||||
bpy.utils.unregister_class(OBJECT_OT_CreateChildActionNode)
|
||||
bpy.utils.unregister_class(TEST_OT_LinkAndPlay)
|
||||
bpy.utils.unregister_class(TEST_OT_Cleanup)
|
||||
bpy.utils.unregister_class(TEST_PT_ObjectPanel)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
@@ -84,6 +84,20 @@ def export_root_objects_to_gltf(output_dir):
|
||||
action["name"] = child["name"]
|
||||
else:
|
||||
action["name"] = desc["name"] + "_" + str(len(desc["actions"]))
|
||||
if "tags" in child:
|
||||
atags = child["tags"]
|
||||
if "," in atags:
|
||||
atags = [m.strip() for m in atags.split(",")]
|
||||
action["tags"] = atags
|
||||
else:
|
||||
action["tags"] = [atags]
|
||||
else:
|
||||
action["tags"] = []
|
||||
for k, v in child.items():
|
||||
if k.startswith("goap_prereq_"):
|
||||
action[k] = v
|
||||
elif k.startswith("goap_effect_"):
|
||||
action[k] = v
|
||||
action["furniture"] = {}
|
||||
action["furniture"]["name"] = desc["name"]
|
||||
action["furniture"]["tags"] = desc["tags"]
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user