From f90efb549ada8d8d00b04c316d19aac58b105695 Mon Sep 17 00:00:00 2001 From: Yusarina Date: Sun, 3 Aug 2025 15:56:42 +0100 Subject: [PATCH 1/4] Small fix --- core/dictionaries.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/dictionaries.py b/core/dictionaries.py index 3e4be29..95a7fc9 100644 --- a/core/dictionaries.py +++ b/core/dictionaries.py @@ -512,7 +512,7 @@ standard_bones = { # Eyes 'left_eye': 'Eye_L', - 'right_eye': 'Eye_R' + 'right_eye': 'Eye_R', # Breast bones 'breast_1_l': 'Breast1_L', From b39e20e6476492383fee5f0db99b6e96d4029c9a Mon Sep 17 00:00:00 2001 From: Yusarina Date: Sun, 3 Aug 2025 16:33:51 +0100 Subject: [PATCH 2/4] Removed hardcoded bones names --- core/dictionaries.py | 16 +++---- core/vrm_unity_converter.py | 91 +++---------------------------------- 2 files changed, 14 insertions(+), 93 deletions(-) diff --git a/core/dictionaries.py b/core/dictionaries.py index 95a7fc9..7100b34 100644 --- a/core/dictionaries.py +++ b/core/dictionaries.py @@ -285,12 +285,12 @@ bone_names.update({ 'head': bone_names['head'] + ['jbipchead', 'jhead', 'vrmhead', 'lefteye', 'righteye'], # VRM arms - both simplified patterns - 'left_shoulder': bone_names['left_shoulder'] + ['jbipllshoulder', 'jlshoulder', 'jbiplshoulder', 'leftshoulder'], + 'left_shoulder': bone_names['left_shoulder'] + ['jbipllshoulder', 'jlshoulder', 'jbiplshoulder', 'leftshoulder', 'jbipllclavicle'], 'left_arm': bone_names['left_arm'] + ['jbiplupperarm', 'jlupperarm', 'leftupperarm'], 'left_elbow': bone_names['left_elbow'] + ['jbipllforearm', 'jlforearm', 'jbipllowerarm', 'leftlowerarm'], 'left_wrist': bone_names['left_wrist'] + ['jbipllhand', 'jlhand', 'jbiplhand', 'lefthand'], - 'right_shoulder': bone_names['right_shoulder'] + ['jbiprlshoulder', 'jrshoulder', 'jbiprshoulder', 'rightshoulder'], + 'right_shoulder': bone_names['right_shoulder'] + ['jbiprlshoulder', 'jrshoulder', 'jbiprshoulder', 'rightshoulder', 'jbiprrclavicle'], 'right_arm': bone_names['right_arm'] + ['jbiprrupperarm', 'jrupperarm', 'jbiprupperarm', 'rightupperarm'], 'right_elbow': bone_names['right_elbow'] + ['jbiprrforearm', 'jrforearm', 'jbiprforearm', 'jbiprlowerarm', 'rightlowerarm'], 'right_wrist': bone_names['right_wrist'] + ['jbiprrhand', 'jrhand', 'jbiprhand', 'righthand'], @@ -314,12 +314,12 @@ bone_names.update({ 'jaw': ['jaw', 'mandible', 'lowerjaw', 'chin', 'あご', 'ik_あご'], # Breast bones - 'breast_1_l': bone_names['breast_1_l'] + ['jbipcbreast1l', 'jlbreast1'], - 'breast_2_l': bone_names['breast_2_l'] + ['jbipcbreast2l', 'jlbreast2'], - 'breast_3_l': bone_names['breast_3_l'] + ['jbipcbreast3l', 'jlbreast3'], - 'breast_1_r': bone_names['breast_1_r'] + ['jbipcbreast1r', 'jrbreast1'], - 'breast_2_r': bone_names['breast_2_r'] + ['jbipcbreast2r', 'jrbreast2'], - 'breast_3_r': bone_names['breast_3_r'] + ['jbipcbreast3r', 'jrbreast3'], + 'breast_1_l': bone_names['breast_1_l'] + ['jbipcbreast1l', 'jlbreast1', 'jseclbust1'], + 'breast_2_l': bone_names['breast_2_l'] + ['jbipcbreast2l', 'jlbreast2', 'jseclbust2'], + 'breast_3_l': bone_names['breast_3_l'] + ['jbipcbreast3l', 'jlbreast3', 'jseclbust3'], + 'breast_1_r': bone_names['breast_1_r'] + ['jbipcbreast1r', 'jrbreast1', 'jsecrbust1'], + 'breast_2_r': bone_names['breast_2_r'] + ['jbipcbreast2r', 'jrbreast2', 'jsecrbust2'], + 'breast_3_r': bone_names['breast_3_r'] + ['jbipcbreast3r', 'jrbreast3', 'jsecrbust3'], # VRM fingers - Left (including Little finger variations) 'thumb_0_l': bone_names['thumb_0_l'] + ['jbipllthumb0', 'jlthumb0', 'jbipllthumbmetacarpal', 'jlthumbmetacarpal', 'leftthumbmetacarpal'], diff --git a/core/vrm_unity_converter.py b/core/vrm_unity_converter.py index 73e6458..8d6f92e 100644 --- a/core/vrm_unity_converter.py +++ b/core/vrm_unity_converter.py @@ -85,94 +85,15 @@ def find_vrm_bones_in_armature(armature: Object) -> Dict[str, str]: def guess_unity_name_from_vrm(vrm_simplified: str) -> Optional[str]: """ - Attempt to guess Unity bone name from VRM simplified name + Attempt to guess Unity bone name from VRM simplified name using dictionary lookup """ - # Map common VRM patterns to Unity equivalents - pattern_mappings = { - 'jbipcupperchest': 'UpperChest', - 'jbipcchest': 'Chest', - 'jbipcspine': 'Spine', - 'jbipchips': 'Hips', - 'jbipcneck': 'Neck', - 'jbipchead': 'Head', + if vrm_simplified in reverse_bone_lookup: + standard_bone_key = reverse_bone_lookup[vrm_simplified] - # Left arm - 'jbipllclavicle': 'LeftShoulder', - 'jbipllshoulder': 'LeftShoulder', - 'jbiplshoulder': 'LeftShoulder', - 'jbiplupperarm': 'LeftUpperArm', - 'jbipllforearm': 'LeftLowerArm', - 'jbipllowerarm': 'LeftLowerArm', - 'jbipllhand': 'LeftHand', - 'jbiplhand': 'LeftHand', - - # Right arm (both single and double R patterns) - 'jbiprrclavicle': 'RightShoulder', - 'jbiprlshoulder': 'RightShoulder', - 'jbiprshoulder': 'RightShoulder', - 'jbiprupperarm': 'RightUpperArm', - 'jbiprrupperarm': 'RightUpperArm', - 'jbiprforearm': 'RightLowerArm', - 'jbiprrforearm': 'RightLowerArm', - 'jbiprlowerarm': 'RightLowerArm', - 'jbiprhand': 'RightHand', - 'jbiprrhand': 'RightHand', - - # Left leg - 'jbiplupperleg': 'LeftUpperLeg', - 'jbipllowerleg': 'LeftLowerLeg', - 'jbipllfoot': 'LeftFoot', - 'jbiplfoot': 'LeftFoot', - 'jbiplltoe': 'LeftToes', - 'jbipltoebase': 'LeftToes', - - # Right leg (both single and double R patterns) - 'jbiprupperleg': 'RightUpperLeg', - 'jbiprrupperleg': 'RightUpperLeg', - 'jbiprlowerleg': 'RightLowerLeg', - 'jbiprrlowerleg': 'RightLowerLeg', - 'jbiprfoot': 'RightFoot', - 'jbiprrfoot': 'RightFoot', - 'jbiprtoe': 'RightToes', - 'jbiprrtoe': 'RightToes', - 'jbiprtoebase': 'RightToes', - - # Eyes - 'jbipcleye': 'LeftEye', - 'jbipcreye': 'RightEye', - 'jadjlfaceeye': 'LeftEye', - 'jadjrfaceeye': 'RightEye', - - # Fingers - Left - 'jbiplthumb1': 'LeftThumb1', - 'jbiplthumb2': 'LeftThumb2', - 'jbiplthumb3': 'LeftThumb3', - 'jbiplindex1': 'LeftIndex1', - 'jbiplindex2': 'LeftIndex2', - 'jbiplindex3': 'LeftIndex3', - 'jbiplmiddle1': 'LeftMiddle1', - 'jbiplmiddle2': 'LeftMiddle2', - 'jbiplmiddle3': 'LeftMiddle3', - 'jbiplring1': 'LeftRing1', - 'jbiplring2': 'LeftRing2', - 'jbiplring3': 'LeftRing3', - 'jbipllittle1': 'LeftPinky1', - 'jbipllittle2': 'LeftPinky2', - 'jbipllittle3': 'LeftPinky3', - 'jbiprlittle1': 'RightPinky1', - 'jbiprlittle2': 'RightPinky2', - 'jbiprlittle3': 'RightPinky3', - - # Breast bones - 'jseclbust1': 'Breast1_L', - 'jseclbust2': 'Breast2_L', - 'jseclbust3': 'Breast3_L', - 'jsecrbust1': 'Breast1_R', - 'jsecrbust2': 'Breast2_R', - 'jsecrbust3': 'Breast3_R' - } + if standard_bone_key in standard_bones: + return standard_bones[standard_bone_key] - return pattern_mappings.get(vrm_simplified) + return None def is_vrm_collider_object(obj_name: str) -> bool: From d820edfc647fd90cc3230a9ee28509f3cdf7189b Mon Sep 17 00:00:00 2001 From: Yusarina Date: Sun, 3 Aug 2025 20:08:38 +0100 Subject: [PATCH 3/4] Change Chest.Up to UpperChest --- core/dictionaries.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/dictionaries.py b/core/dictionaries.py index 7100b34..198919e 100644 --- a/core/dictionaries.py +++ b/core/dictionaries.py @@ -452,7 +452,7 @@ standard_bones = { 'hips': 'Hips', 'spine': 'Spine', 'chest': 'Chest', - 'upper_chest': 'Chest.Up', + 'upper_chest': 'UpperChest', 'neck': 'Neck', 'head': 'Head', @@ -526,20 +526,20 @@ standard_bones = { bone_hierarchy = [ ('Hips', 'Spine'), ('Spine', 'Chest'), - ('Chest', 'Chest.Up'), - ('Chest.Up', 'Neck'), + ('Chest', 'UpperChest'), + ('UpperChest', 'Neck'), ('Neck', 'Head'), ('Head', 'Eye_L'), ('Head', 'Eye_R'), # Left Arm Chain - ('Chest.Up', 'Shoulder_L'), + ('UpperChest', 'Shoulder_L'), ('Shoulder_L', 'UpperArm_L'), ('UpperArm_L', 'LowerArm_L'), ('LowerArm_L', 'Hand_L'), # Right Arm Chain - ('Chest.Up', 'Shoulder_R'), + ('UpperChest', 'Shoulder_R'), ('Shoulder_R', 'UpperArm_R'), ('UpperArm_R', 'LowerArm_R'), ('LowerArm_R', 'Hand_R'), @@ -616,10 +616,10 @@ acceptable_bone_hierarchy = [ ('Head', 'RightEye'), # Old standard bone hierarchy patterns - ('Chest.Up', 'UpperArm.L'), + ('UpperChest', 'UpperArm.L'), ('UpperArm.L', 'LowerArm.L'), ('LowerArm.L', 'Hand.L'), - ('Chest.Up', 'UpperArm.R'), + ('UpperChest', 'UpperArm.R'), ('UpperArm.R', 'LowerArm.R'), ('LowerArm.R', 'Hand.R'), ('Hips', 'UpperLeg.L'), @@ -632,11 +632,11 @@ acceptable_bone_hierarchy = [ ('Foot.R', 'Toes.R'), # New standard bone hierarchy patterns (with shoulders) - ('Chest.Up', 'Shoulder_L'), + ('UpperChest', 'Shoulder_L'), ('Shoulder_L', 'UpperArm_L'), ('UpperArm_L', 'LowerArm_L'), ('LowerArm_L', 'Hand_L'), - ('Chest.Up', 'Shoulder_R'), + ('UpperChest', 'Shoulder_R'), ('Shoulder_R', 'UpperArm_R'), ('UpperArm_R', 'LowerArm_R'), ('LowerArm_R', 'Hand_R'), From e19dd78557ba715d38a5d207c62acf2aea0fab38 Mon Sep 17 00:00:00 2001 From: Yusarina Date: Sun, 3 Aug 2025 20:19:14 +0100 Subject: [PATCH 4/4] Translations update --- core/vrm_unity_converter.py | 1 + functions/tools/vrm_unity_conversion.py | 14 ++++---- resources/translations/en_US.json | 31 +++++++++++++++- resources/translations/ja_JP.json | 31 +++++++++++++++- resources/translations/ko_KR.json | 31 +++++++++++++++- ui/vrm_unity_panel.py | 48 ++++++++++++------------- 6 files changed, 122 insertions(+), 34 deletions(-) diff --git a/core/vrm_unity_converter.py b/core/vrm_unity_converter.py index 8d6f92e..f3bacdf 100644 --- a/core/vrm_unity_converter.py +++ b/core/vrm_unity_converter.py @@ -4,6 +4,7 @@ from bpy.types import Object, Bone from .common import get_active_armature from .dictionaries import simplify_bonename, standard_bones, bone_hierarchy, reverse_bone_lookup from .logging_setup import logger +from .translations import t def detect_vrm_armature(armature: Object) -> bool: diff --git a/functions/tools/vrm_unity_conversion.py b/functions/tools/vrm_unity_conversion.py index 48f0738..c4faaa6 100644 --- a/functions/tools/vrm_unity_conversion.py +++ b/functions/tools/vrm_unity_conversion.py @@ -10,8 +10,8 @@ from ...core.armature_validation import validate_armature class AvatarToolkit_OT_ConvertVRMToUnity(Operator): """Convert VRM armature bone names to Unity humanoid format""" bl_idname = "avatar_toolkit.convert_vrm_to_unity" - bl_label = "Convert VRM to Unity" - bl_description = "Convert VRM armature bone names to Unity humanoid naming convention" + bl_label = t("VRM.convert_to_unity.label") + bl_description = t("VRM.convert_to_unity.desc") bl_options = {'REGISTER', 'UNDO'} @classmethod @@ -23,7 +23,7 @@ class AvatarToolkit_OT_ConvertVRMToUnity(Operator): armature = get_active_armature(context) if not armature: logger.warning("No active armature found for VRM conversion") - self.report({'ERROR'}, "No active armature selected") + self.report({'ERROR'}, t("VRM.no_armature_selected")) return {'CANCELLED'} logger.info(f"Starting VRM to Unity conversion for armature: {armature.name}") @@ -59,10 +59,10 @@ class AvatarToolkit_OT_ConvertVRMToUnity(Operator): if is_valid: logger.info("Unity hierarchy validation passed") - self.report({'INFO'}, "Unity hierarchy validation passed") + self.report({'INFO'}, t("VRM.validation.hierarchy_passed")) else: logger.warning("Unity hierarchy validation found issues") - self.report({'WARNING'}, "Conversion completed but hierarchy validation found issues:") + self.report({'WARNING'}, t("VRM.validation.hierarchy_issues")) for msg in validation_messages: self.report({'WARNING'}, msg) @@ -70,7 +70,7 @@ class AvatarToolkit_OT_ConvertVRMToUnity(Operator): armature_valid, armature_messages, _ = validate_armature(armature) if armature_valid: logger.info("Full armature validation passed") - self.report({'INFO'}, "Armature passes standard validation") + self.report({'INFO'}, t("VRM.validation.armature_passed")) else: logger.info("Full armature validation found minor issues") # Don't report these as errors since the conversion was successful @@ -83,6 +83,6 @@ class AvatarToolkit_OT_ConvertVRMToUnity(Operator): except Exception as e: logger.error(f"Error during hierarchy validation: {str(e)}") - self.report({'WARNING'}, f"Conversion completed but validation failed: {str(e)}") + self.report({'WARNING'}, t("VRM.validation.failed", error=str(e))) return {'FINISHED'} \ No newline at end of file diff --git a/resources/translations/en_US.json b/resources/translations/en_US.json index 667ac37..712b3f5 100644 --- a/resources/translations/en_US.json +++ b/resources/translations/en_US.json @@ -554,6 +554,35 @@ "Language.ko_KR": "Korean", "Language.changed.title": "Language Changed", "Language.changed.success": "Language changed successfully!", - "Language.changed.restart": "Some UI elements may require restarting Blender" + "Language.changed.restart": "Some UI elements may require restarting Blender", + + "VRM.panel.label": "VRM to Unity", + "VRM.converter.title": "VRM Converter", + "VRM.no_armature_selected": "No armature selected", + "VRM.select_armature_to_convert": "Select an armature to convert", + "VRM.armature_name": "Armature: {name}", + "VRM.armature_detected": "VRM armature detected", + "VRM.no_vrm_bones_detected": "No VRM bones detected", + "VRM.remove_colliders": "Remove Colliders", + "VRM.remove_root_bone": "Remove Root Bone", + "VRM.convert_to_unity_format": "Convert to Unity Format", + "VRM.convert_to_unity.label": "Convert VRM to Unity", + "VRM.convert_to_unity.desc": "Convert VRM armature bone names to Unity humanoid naming convention", + "VRM.conversion_info.title": "Conversion Info:", + "VRM.conversion_info.renames_bones": "• Renames VRM bones to Unity format", + "VRM.conversion_info.removes_colliders": "• Removes collider bones (optional)", + "VRM.conversion_info.removes_root": "• Removes root bone, makes Hips root (optional)", + "VRM.conversion_info.maintains_hierarchy": "• Maintains bone hierarchy", + "VRM.conversion_info.validates_results": "• Validates conversion results", + "VRM.conversion_info.preserves_animations": "• Preserves all animations", + "VRM.detection_failed.title": "VRM Detection Failed:", + "VRM.detection_failed.not_vrm_format": "• Selected armature is not VRM format", + "VRM.detection_failed.bones_start_with": "• VRM bones start with 'J_Bip_C_'", + "VRM.detection_failed.need_five_bones": "• Need at least 5 VRM bones detected", + "VRM.detection_failed.check_bone_names": "• Check armature bone names", + "VRM.validation.hierarchy_passed": "Unity hierarchy validation passed", + "VRM.validation.hierarchy_issues": "Conversion completed but hierarchy validation found issues:", + "VRM.validation.armature_passed": "Armature passes standard validation", + "VRM.validation.failed": "Conversion completed but validation failed: {error}" } } diff --git a/resources/translations/ja_JP.json b/resources/translations/ja_JP.json index 57554c8..6d2e1cd 100644 --- a/resources/translations/ja_JP.json +++ b/resources/translations/ja_JP.json @@ -537,6 +537,35 @@ "Language.ko_KR": "韓国語", "Language.changed.title": "言語が変更されました", "Language.changed.success": "言語が正常に変更されました!", - "Language.changed.restart": "一部のUI要素はBlenderの再起動が必要な場合があります" + "Language.changed.restart": "一部のUI要素はBlenderの再起動が必要な場合があります", + + "VRM.panel.label": "VRMからUnityへ", + "VRM.converter.title": "VRMコンバーター", + "VRM.no_armature_selected": "アーマチュアが選択されていません", + "VRM.select_armature_to_convert": "変換するアーマチュアを選択してください", + "VRM.armature_name": "アーマチュア: {name}", + "VRM.armature_detected": "VRMアーマチュアが検出されました", + "VRM.no_vrm_bones_detected": "VRMボーンが検出されませんでした", + "VRM.remove_colliders": "コライダーを削除", + "VRM.remove_root_bone": "ルートボーンを削除", + "VRM.convert_to_unity_format": "Unity形式に変換", + "VRM.convert_to_unity.label": "VRMをUnityに変換", + "VRM.convert_to_unity.desc": "VRMアーマチュアのボーン名をUnityヒューマノイド命名規則に変換", + "VRM.conversion_info.title": "変換情報:", + "VRM.conversion_info.renames_bones": "• VRMボーンをUnity形式にリネーム", + "VRM.conversion_info.removes_colliders": "• コライダーボーンを削除(オプション)", + "VRM.conversion_info.removes_root": "• ルートボーンを削除し、Hipsをルートにする(オプション)", + "VRM.conversion_info.maintains_hierarchy": "• ボーン階層を維持", + "VRM.conversion_info.validates_results": "• 変換結果を検証", + "VRM.conversion_info.preserves_animations": "• すべてのアニメーションを保持", + "VRM.detection_failed.title": "VRM検出失敗:", + "VRM.detection_failed.not_vrm_format": "• 選択されたアーマチュアはVRM形式ではありません", + "VRM.detection_failed.bones_start_with": "• VRMボーンは'J_Bip_C_'で始まります", + "VRM.detection_failed.need_five_bones": "• 少なくとも5つのVRMボーンが検出される必要があります", + "VRM.detection_failed.check_bone_names": "• アーマチュアのボーン名を確認してください", + "VRM.validation.hierarchy_passed": "Unity階層検証に合格しました", + "VRM.validation.hierarchy_issues": "変換は完了しましたが、階層検証で問題が見つかりました:", + "VRM.validation.armature_passed": "アーマチュアは標準検証に合格しました", + "VRM.validation.failed": "変換は完了しましたが、検証に失敗しました: {error}" } } diff --git a/resources/translations/ko_KR.json b/resources/translations/ko_KR.json index ca19665..5eeecc9 100644 --- a/resources/translations/ko_KR.json +++ b/resources/translations/ko_KR.json @@ -537,6 +537,35 @@ "Language.ko_KR": "한국어", "Language.changed.title": "언어 변경됨", "Language.changed.success": "언어가 성공적으로 변경되었습니다!", - "Language.changed.restart": "일부 UI 요소는 블렌더를 다시 시작해야 할 수 있습니다" + "Language.changed.restart": "일부 UI 요소는 블렌더를 다시 시작해야 할 수 있습니다", + + "VRM.panel.label": "VRM에서 Unity로", + "VRM.converter.title": "VRM 변환기", + "VRM.no_armature_selected": "선택된 아마추어 없음", + "VRM.select_armature_to_convert": "변환할 아마추어를 선택하세요", + "VRM.armature_name": "아마추어: {name}", + "VRM.armature_detected": "VRM 아마추어 감지됨", + "VRM.no_vrm_bones_detected": "VRM 본이 감지되지 않음", + "VRM.remove_colliders": "콜라이더 제거", + "VRM.remove_root_bone": "루트 본 제거", + "VRM.convert_to_unity_format": "Unity 형식으로 변환", + "VRM.convert_to_unity.label": "VRM을 Unity로 변환", + "VRM.convert_to_unity.desc": "VRM 아마추어 본 이름을 Unity 휴머노이드 명명 규칙으로 변환", + "VRM.conversion_info.title": "변환 정보:", + "VRM.conversion_info.renames_bones": "• VRM 본을 Unity 형식으로 이름 변경", + "VRM.conversion_info.removes_colliders": "• 콜라이더 본 제거 (선택사항)", + "VRM.conversion_info.removes_root": "• 루트 본 제거, Hips를 루트로 설정 (선택사항)", + "VRM.conversion_info.maintains_hierarchy": "• 본 계층 구조 유지", + "VRM.conversion_info.validates_results": "• 변환 결과 검증", + "VRM.conversion_info.preserves_animations": "• 모든 애니메이션 보존", + "VRM.detection_failed.title": "VRM 감지 실패:", + "VRM.detection_failed.not_vrm_format": "• 선택된 아마추어가 VRM 형식이 아님", + "VRM.detection_failed.bones_start_with": "• VRM 본은 'J_Bip_C_'로 시작함", + "VRM.detection_failed.need_five_bones": "• 최소 5개의 VRM 본이 감지되어야 함", + "VRM.detection_failed.check_bone_names": "• 아마추어 본 이름을 확인하세요", + "VRM.validation.hierarchy_passed": "Unity 계층 구조 검증 통과", + "VRM.validation.hierarchy_issues": "변환은 완료되었지만 계층 구조 검증에서 문제를 발견했습니다:", + "VRM.validation.armature_passed": "아마추어가 표준 검증을 통과했습니다", + "VRM.validation.failed": "변환은 완료되었지만 검증에 실패했습니다: {error}" } } diff --git a/ui/vrm_unity_panel.py b/ui/vrm_unity_panel.py index edaad43..f1565ab 100644 --- a/ui/vrm_unity_panel.py +++ b/ui/vrm_unity_panel.py @@ -9,7 +9,7 @@ from ..functions.tools.vrm_unity_conversion import AvatarToolkit_OT_ConvertVRMTo class AvatarToolKit_PT_VRMUnityPanel(Panel): """Panel for VRM to Unity conversion tools""" - bl_label = "VRM to Unity" + bl_label = t("VRM.panel.label") bl_idname = "OBJECT_PT_avatar_toolkit_vrm_unity" bl_space_type = 'VIEW_3D' bl_region_type = 'UI' @@ -25,63 +25,63 @@ class AvatarToolKit_PT_VRMUnityPanel(Panel): # VRM Conversion Tools vrm_box: UILayout = layout.box() col: UILayout = vrm_box.column(align=True) - col.label(text="VRM Converter", icon='ARMATURE_DATA') + col.label(text=t("VRM.converter.title"), icon='ARMATURE_DATA') col.separator(factor=0.5) # Check if we have an active armature armature = get_active_armature(context) if not armature: - col.label(text="No armature selected", icon='ERROR') - col.label(text="Select an armature to convert") + col.label(text=t("VRM.no_armature_selected"), icon='ERROR') + col.label(text=t("VRM.select_armature_to_convert")) return # Check if the armature appears to be VRM is_vrm = detect_vrm_armature(armature) if is_vrm: - col.label(text=f"Armature: {armature.name}", icon='CHECKMARK') - col.label(text="VRM armature detected", icon='INFO') + col.label(text=t("VRM.armature_name", name=armature.name), icon='CHECKMARK') + col.label(text=t("VRM.armature_detected"), icon='INFO') col.separator(factor=0.3) toolkit = context.scene.avatar_toolkit - col.prop(toolkit, 'vrm_remove_colliders', text="Remove Colliders") - col.prop(toolkit, 'vrm_remove_root', text="Remove Root Bone") + col.prop(toolkit, 'vrm_remove_colliders', text=t("VRM.remove_colliders")) + col.prop(toolkit, 'vrm_remove_root', text=t("VRM.remove_root_bone")) col.separator(factor=0.2) col.operator( AvatarToolkit_OT_ConvertVRMToUnity.bl_idname, - text="Convert to Unity Format", + text=t("VRM.convert_to_unity_format"), icon='EXPORT' ) info_box = vrm_box.box() info_col = info_box.column(align=True) - info_col.label(text="Conversion Info:", icon='INFO') - info_col.label(text="• Renames VRM bones to Unity format") - info_col.label(text="• Removes collider bones (optional)") - info_col.label(text="• Removes root bone, makes Hips root (optional)") - info_col.label(text="• Maintains bone hierarchy") - info_col.label(text="• Validates conversion results") - info_col.label(text="• Preserves all animations") + info_col.label(text=t("VRM.conversion_info.title"), icon='INFO') + info_col.label(text=t("VRM.conversion_info.renames_bones")) + info_col.label(text=t("VRM.conversion_info.removes_colliders")) + info_col.label(text=t("VRM.conversion_info.removes_root")) + info_col.label(text=t("VRM.conversion_info.maintains_hierarchy")) + info_col.label(text=t("VRM.conversion_info.validates_results")) + info_col.label(text=t("VRM.conversion_info.preserves_animations")) else: - col.label(text=f"Armature: {armature.name}", icon='ERROR') - col.label(text="No VRM bones detected", icon='CANCEL') + col.label(text=t("VRM.armature_name", name=armature.name), icon='ERROR') + col.label(text=t("VRM.no_vrm_bones_detected"), icon='CANCEL') col.separator(factor=0.3) row = col.row() row.enabled = False row.operator( AvatarToolkit_OT_ConvertVRMToUnity.bl_idname, - text="Convert to Unity Format", + text=t("VRM.convert_to_unity_format"), icon='CANCEL' ) help_box = vrm_box.box() help_col = help_box.column(align=True) - help_col.label(text="VRM Detection Failed:", icon='QUESTION') - help_col.label(text="• Selected armature is not VRM format") - help_col.label(text="• VRM bones start with 'J_Bip_C_'") - help_col.label(text="• Need at least 5 VRM bones detected") - help_col.label(text="• Check armature bone names") \ No newline at end of file + help_col.label(text=t("VRM.detection_failed.title"), icon='QUESTION') + help_col.label(text=t("VRM.detection_failed.not_vrm_format")) + help_col.label(text=t("VRM.detection_failed.bones_start_with")) + help_col.label(text=t("VRM.detection_failed.need_five_bones")) + help_col.label(text=t("VRM.detection_failed.check_bone_names")) \ No newline at end of file