@Sal1800 In my case, I created a python script that converts an animation into a mesh using shape key to armature bones, and although the animation is displayed correctly in Blender, MSFS constantly returns the error: Animation target ‘weights’ not supported. Animation[8] ‘Flag.004’, channel[3].
Any ideas?
My python script:
import bpy
from mathutils import Vector
def create_clean_armature(obj):
“”“Cria armature limpa sem vertex groups”“”
if not obj.data.shape_keys:
print(“Objeto não possui shape keys!”)
return None
# Cria nova armature
arm_data = bpy.data.armatures.new(f"MSFS_{obj.name}_Arm")
arm_obj = bpy.data.objects.new(f"MSFS_{obj.name}_Arm", arm_data)
bpy.context.collection.objects.link(arm_obj)
# Configurações visuais
arm_obj.show_in_front = True
arm_data.display_type = 'STICK'
arm_obj.location = obj.location.copy()
arm_obj.rotation_euler = obj.rotation_euler.copy()
# Cria estrutura de bones
bpy.context.view_layer.objects.active = arm_obj
arm_obj.select_set(True)
bpy.ops.object.mode_set(mode='EDIT')
# Bone raiz (obrigatório para MSFS)
root_bone = arm_data.edit_bones.new("MSFS_Root")
root_bone.head = Vector((0, 0, 0))
root_bone.tail = Vector((0, 0.1, 0))
# Bone de controle principal
ctrl_bone = arm_data.edit_bones.new("MSFS_Ctrl")
ctrl_bone.head = Vector((0.2, 0, 0))
ctrl_bone.tail = Vector((0.2, 0.1, 0))
ctrl_bone.parent = root_bone
bpy.ops.object.mode_set(mode='OBJECT')
return arm_obj
def transfer_animation_without_weights(obj, arm_obj):
“”“Transfere animação sem usar vertex groups”“”
shape_keys = obj.data.shape_keys.key_blocks[1:] # Exclui Basis
scene = bpy.context.scene
# Configura bone para rotação XYZ
ctrl_bone = arm_obj.pose.bones["MSFS_Ctrl"]
ctrl_bone.rotation_mode = 'XYZ'
# Encontra todos os frames com keyframes
keyframes = set()
if obj.data.shape_keys.animation_data and obj.data.shape_keys.animation_data.action:
for fcurve in obj.data.shape_keys.animation_data.action.fcurves:
if 'key_blocks' in fcurve.data_path:
for kp in fcurve.keyframe_points:
keyframes.add(int(kp.co[0]))
# Cria driver para cada shape key que controla o bone
for sk in shape_keys:
# Cria propriedade customizada na armature
arm_obj[f"SK_{sk.name}"] = 0.0
arm_obj.keyframe_insert(data_path=f'["SK_{sk.name}"]', frame=1)
# Cria driver para o bone
driver = ctrl_bone.driver_add("rotation_euler", 0).driver
driver.type = 'SUM'
# Adiciona variável para cada shape key
var = driver.variables.new()
var.name = sk.name
var.type = 'SINGLE_PROP'
var.targets[0].id = arm_obj
var.targets[0].data_path = f'["SK_{sk.name}"]'
# Configura a expressão para combinar todas as influências
driver.expression = " + ".join([sk.name for sk in shape_keys])
# Transfere a animação para as propriedades customizadas
for frame in sorted(keyframes):
scene.frame_set(frame)
for sk in shape_keys:
arm_obj[f"SK_{sk.name}"] = sk.value
arm_obj.keyframe_insert(data_path=f'["SK_{sk.name}"]', frame=frame)
def clean_all_vertex_groups(obj):
“”“Remove todos os vertex groups”“”
for vg in obj.vertex_groups:
obj.vertex_groups.remove(vg)
def setup_non_deforming_armature(obj, arm_obj):
“”“Configura armature sem deformação física”“”
# Adiciona modificador Armature sem skinning
mod = obj.modifiers.new(name=“MSFS_Armature”, type=‘ARMATURE’)
mod.object = arm_obj
mod.use_vertex_groups = False # Crucial - sem weights!
mod.use_bone_envelopes = False
# Configura parentesco
obj.parent = arm_obj
obj.matrix_parent_inverse = arm_obj.matrix_world.inverted()
# Marca bones como não deformantes
for bone in arm_obj.data.bones:
bone.use_deform = False
def main():
obj = bpy.context.active_object
if not obj or obj.type != ‘MESH’ or not obj.data.shape_keys:
print(“Selecione um objeto de malha com shape keys!”)
return
# 1. Remove vertex groups existentes
clean_all_vertex_groups(obj)
# 2. Cria nova armature limpa
arm_obj = create_clean_armature(obj)
if not arm_obj:
return
# 3. Transfere animação sem weights
transfer_animation_without_weights(obj, arm_obj)
# 4. Configura armature não-deformante
setup_non_deforming_armature(obj, arm_obj)
# 5. Seleciona objetos para exportação
bpy.context.view_layer.objects.active = arm_obj
arm_obj.select_set(True)
obj.select_set(True)
print("Conversão para MSFS concluída com sucesso!")
print("Configurações de exportação:")
print("- [X] Animation")
print("- [ ] Skinning (DESATIVADO)")
print("- [X] Only Selected")
print("Dica: No MSFS SDK, verifique se a animação está marcada como 'Scripted'")
if name == “main”:
main()