Skip to content

connect_animation_to_sequence

ConnectAlembicAnimation

Bases: ConnectFbxAnimation

Add Animation Sequence to Level Sequence when the skeletal Mesh already binds into the Sequence. Applied only for animation and layout product type. This is done in hacky way which replace the loaded fbx skeletal mesh with the alembic one in the current update. It will be removed after support the alembic export of rig product type.

Source code in client/ayon_unreal/plugins/inventory/connect_animation_to_sequence.py
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
class ConnectAlembicAnimation(ConnectFbxAnimation):
    """Add Animation Sequence to Level Sequence when the skeletal Mesh
    already binds into the Sequence. Applied only for animation and
    layout product type.
    This is done in hacky way which replace the loaded fbx skeletal mesh with the alembic one
    in the current update. It will be removed after support the alembic export of rig product
    type.
    """

    label = "Connect Alembic Animation to Level Sequence"
    icon = "arrow-up"
    color = "red"
    order = 1

    def import_animation_sequence(self, asset_content, sequence, frameStart, frameEnd):
        update_skeletal_mesh(asset_content, sequence)
        import_animation_sequence(asset_content, sequence, frameStart, frameEnd)

ConnectFbxAnimation

Bases: InventoryAction

Add Animation Sequence to Level Sequence when the skeletal Mesh already binds into the Sequence. Applied only for animation and layout product type

Source code in client/ayon_unreal/plugins/inventory/connect_animation_to_sequence.py
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
class ConnectFbxAnimation(InventoryAction):
    """Add Animation Sequence to Level Sequence when the skeletal Mesh
    already binds into the Sequence. Applied only for animation and
    layout product type
    """

    label = "Connect Fbx Animation to Level Sequence"
    icon = "arrow-up"
    color = "red"
    order = 1

    def process(self, containers):
        allowed_families = ["animation", "layout", "camera"]
        sequence = None
        for container in containers:
            container_dir = container.get("namespace")
            if container.get("family") not in allowed_families:
                unreal.log_warning(
                    f"Container {container_dir} is not supported."
                )
                continue
        sequence = self.get_layout_asset(containers)
        if not sequence:
            raise RuntimeError(
                "No level sequence found in layout asset directory. "
                "Please select the layout container."
            )
        self.import_animation(containers, sequence)
        self.import_camera(containers, sequence)
        self.save_layout_asset(containers)

    def get_layout_asset(self, containers, asset_name="LevelSequence"):
        ar = unreal.AssetRegistryHelpers.get_asset_registry()
        layout_path = next((
            container.get("namespace") for container in containers
            if container.get("family") == "layout"), None)
        if not layout_path:
            return None
        asset_content = unreal.EditorAssetLibrary.list_assets(
            layout_path, recursive=False, include_folder=False
        )
        for asset in asset_content:
            data = ar.get_asset_by_object_path(asset)
            if data.asset_class_path.asset_name == asset_name:
                return data.get_asset()

    def import_animation(self, containers, sequence):
        has_animation_product = [
            container for container in containers
            if container.get("family") == "animation"]
        if not has_animation_product:
            return
        anim_path = next((
            container.get("namespace") for container in containers
            if container.get("family") == "animation"), None)
        start_frame, end_frame = get_frame_range_from_folder_attributes()
        # use the clipIn/Out value for the frameStart and frameEnd
        frameStart = next((
            int(container.get("frameStart", start_frame)) for container in containers
            if container.get("family") == "animation"), None)
        frameEnd = next((
            int(container.get("frameEnd", end_frame)) for container in containers
            if container.get("family") == "animation"), None)
        if anim_path:
            asset_content = unreal.EditorAssetLibrary.list_assets(
                anim_path, recursive=False, include_folder=False
            )
            self.import_animation_sequence(
                asset_content, sequence, frameStart, frameEnd)

    def import_camera(self, containers, sequence):
        has_camera_product = [
            container for container in containers
            if container.get("family") == "camera"]
        if not has_camera_product:
            return
        parent_id = next((
            container.get("parent") for container in containers
            if container.get("family") == "camera"), None)
        version_id = next((
            container.get("representation") for container in containers
            if container.get("family") == "camera"), None)
        namespace = next((
            container.get("namespace") for container in containers
            if container.get("family") == "camera"), None)
        start_frame, end_frame = get_frame_range_from_folder_attributes()
        # use the clipIn/Out value for the frameStart and frameEnd
        frameStart = next((
            int(container.get("frameStart", start_frame)) for container in containers
            if container.get("family") == "camera"), None)
        frameEnd = next((
            int(container.get("frameEnd", end_frame)) for container in containers
            if container.get("family") == "camera"), None)
        layout_world = self.get_layout_asset(containers, asset_name="World")
        import_camera_to_level_sequence(
            sequence, parent_id, version_id,
            namespace, layout_world, frameStart,
            frameEnd)

    def import_animation_sequence(self, asset_content, sequence, frameStart, frameEnd):
        import_animation_sequence(asset_content, sequence, frameStart, frameEnd)

    def save_layout_asset(self, containers):
        layout_path = next((
            container.get("namespace") for container in containers
            if container.get("family") == "layout"), None)
        asset_content = unreal.EditorAssetLibrary.list_assets(
            layout_path, recursive=False, include_folder=False
        )
        for asset in asset_content:
            unreal.EditorAssetLibrary.save_asset(asset)