def METHOD_NAME(self, b_material, n_geom):
    """Export the material UV controller data."""
    # get fcurves - a bit more elaborate here so we can zip with the NiUVData later
    # nb. these are actually specific to the texture slot in blender
    # here we don't care and just take the first fcurve that matches
    fcurves = []
    for dp, ind in (("offset", 0), ("offset", 1), ("scale", 0), ("scale", 1)):
        for fcu in b_material.animation_data.action.fcurves:
            if dp in fcu.data_path and fcu.array_index == ind:
                fcurves.append(fcu)
                break
        else:
            fcurves.append(None)
    # continue if at least one fcurve exists
    if not any(fcurves):
        return
    # get the uv curves and translate them into nif data
    n_uv_data = NifClasses.NiUVData(NifData.data)
    for fcu, n_uv_group in zip(fcurves, n_uv_data.uv_groups):
        if fcu:
            NifLog.debug(f"Exporting {fcu} as NiUVData")
            n_uv_group.num_keys = len(fcu.keyframe_points)
            n_uv_group.interpolation = NifClasses.KeyType.LINEAR_KEY
            n_uv_group.reset_field("keys")
            for b_point, n_key in zip(fcu.keyframe_points, n_uv_group.keys):
                # add each point of the curve
                b_frame, b_value = b_point.co
                if "offset" in fcu.data_path:
                    # offsets are negated in blender
                    b_value = -b_value
                n_key.arg = n_uv_group.interpolation
                n_key.time = b_frame / self.fps
                n_key.value = b_value
    # if uv data is present then add the controller so it is exported
    if fcurves[0].keyframe_points:
        n_uv_ctrl = NifClasses.NiUVController(NifData.data)
        self.set_flags_and_timing(n_uv_ctrl, fcurves)
        n_uv_ctrl.data = n_uv_data
        # attach block to geometry
        n_geom.add_controller(n_uv_ctrl)