public void setMeta(VRMMetaObject meta) { m_texts.UpdateMeta(meta); vrmMeta = meta; }
/// <summary> /// VRChatアバターインスタンスからVRMインスタンスへ変換します。 /// </summary> /// <param name="instance">ヒエラルキー上のGameObject。</param> /// <param name="presetVRChatBindingPairs">各表情への割り当て。</param> /// <param name="swayingParametersConverter"></param> internal static void Convert( string outputPath, GameObject instance, VRMMetaObject meta, IDictionary <ExpressionPreset, VRChatExpressionBinding> presetVRChatBindingPairs, DynamicBoneReplacer.ParametersConverter swayingParametersConverter ) { GameObject clone = null, normalized = null; try { var rootObjectName = instance.name; clone = Object.Instantiate(instance); // 非表示のオブジェクト・コンポーネントを削除 // TODO: アクティブ・非アクティブの切り替えをシェイプキーに変換する VRChatToVRMConverter.RemoveInactiveObjectsAndDisabledComponents(clone); // 表情とシェイプキー名の組み合わせを取得 var presetShapeKeyNameWeightPairsPairs = presetVRChatBindingPairs.ToDictionary( presetVRChatBindingPair => presetVRChatBindingPair.Key, presetVRChatBindingPair => VRChatExpressionsReplacer.ExtractShapeKeyNames(presetVRChatBindingPair.Value) ); // VRM設定1 var temporaryFolder = UnityPath.FromUnityPath(VRChatToVRMConverter.TemporaryFolderPath); temporaryFolder.EnsureFolder(); var temporaryPrefabPath = temporaryFolder.Child(VRChatToVRMConverter.TemporaryPrefabFileName).Value; VRMInitializer.Initialize(temporaryPrefabPath, clone); VRChatToVRMConverter.SetFirstPersonOffset(clone); VRChatToVRMConverter.SetLookAtBoneApplyer(clone); DynamicBoneReplacer.SetSpringBonesAndColliders(clone, swayingParametersConverter); // 正規化 normalized = VRMBoneNormalizer.Execute(clone, forceTPose: true); // 全メッシュ結合 var combinedRenderer = CombineMeshesAndSubMeshes.Combine( normalized, notCombineRendererObjectNames: new List <string>(), destinationObjectName: "vrm-mesh", savingAsAsset: false ); // 使用していないシェイプキーの削除 SkinnedMeshUtility.CleanUpShapeKeys(combinedRenderer.sharedMesh, presetShapeKeyNameWeightPairsPairs .SelectMany(presetShapeKeyNameWeightPairsPair => presetShapeKeyNameWeightPairsPair.Value.Keys) .Distinct()); // シェイプキーの分離 Utilities.MeshUtility.SeparationProcessing(normalized); // マテリアルの設定・アセットとして保存 VRChatToVRMConverter.ReplaceShaders(normalized, temporaryPrefabPath); // GameObject・メッシュなどをアセットとして保存 (アセットとして存在しないと正常にエクスポートできない) normalized.name = rootObjectName; var animator = normalized.GetComponent <Animator>(); animator.avatar = Duplicator.CreateObjectToFolder(animator.avatar, temporaryPrefabPath); meta.name = "Meta"; normalized.GetComponent <VRMMeta>().Meta = Duplicator.CreateObjectToFolder(meta, temporaryPrefabPath); foreach (var renderer in normalized.GetComponentsInChildren <SkinnedMeshRenderer>()) { renderer.sharedMesh.name = renderer.name; renderer.sharedMesh = Duplicator.CreateObjectToFolder(renderer.sharedMesh, temporaryPrefabPath); } // VRM設定2 VRChatToVRMConverter.SetFirstPersonRenderers(normalized); // 表情の設定 VRChatExpressionsReplacer.SetExpressions(normalized, presetShapeKeyNameWeightPairsPairs); var prefab = PrefabUtility .SaveAsPrefabAssetAndConnect(normalized, temporaryPrefabPath, InteractionMode.AutomatedAction); // エクスポート AssetDatabase.SaveAssets(); VRMEditorExporter.Export( outputPath, prefab, meta: null, ScriptableObject.CreateInstance <VRMExportSettings>(), info: null ); } catch (Exception exception) { ErrorDialog.Open(exception); throw; } finally { if (clone != null) { Object.DestroyImmediate(clone); } if (normalized != null) { Object.DestroyImmediate(normalized); } AssetDatabase.DeleteAsset("Assets/VRMConverterTemporary"); } }
/// <summary> /// Unload the old model and load the new model from VRM file. /// </summary> /// <param name="path"></param> private void LoadModel(string path) { if (!File.Exists(path)) { Debug.Log("Model " + path + " is not exits."); return; } GameObject newModelObject = null; try { // Load from a VRM file. var parser = new GlbFileParser(path); var data = parser.Parse(); context = new VRMImporterContext(data); //Debug.Log("Loading model : " + path); RuntimeGltfInstance instance = context.Load(); instance.EnableUpdateWhenOffscreen(); newModelObject = instance.Root; meta = context.ReadMeta(true); instance.ShowMeshes(); } catch (Exception ex) { if (uiController) { uiController.ShowWarning("Model load failed."); } Debug.LogError("Failed loading " + path); Debug.LogError(ex); return; } if (newModelObject) { if (model) { GameObject.Destroy(model.gameObject); } model = newModelObject.AddComponent <HumanPoseTransfer>(); CreateColliders(model.gameObject); var characterController = model.gameObject.AddComponent <VrmCharacterBehaviour>(); SetMotion(motion, model, meta); if (uiController) { uiController.Show(meta); if (characterController) { uiController.enableRandomMotion = characterController.randomMotion; uiController.enableRandomEmotion = characterController.randomEmotion; } } } }