/// <summary> /// すべてのメッシュの全頂点にウェイトが設定された状態にします。 /// </summary> /// <param name="root"></param> /// <param name="notCombineRendererObjectNames"></param> private static void MakeAllVerticesHaveWeights( GameObject root, IEnumerable <string> notCombineRendererObjectNames ) { foreach (var renderer in root.GetComponentsInChildren <SkinnedMeshRenderer>()) { if (notCombineRendererObjectNames.Contains(renderer.name) || renderer.bones.Length > 1 || renderer.bones.Length > 0 && renderer.bones[0] != renderer.transform) { continue; } CombineMeshesAndSubMeshes.MakeVerticesHaveWeight(renderer: renderer); } foreach (var meshRenderer in root.GetComponentsInChildren <MeshRenderer>()) { if (notCombineRendererObjectNames.Contains(meshRenderer.name)) { continue; } var meshFilter = meshRenderer.GetComponent <MeshFilter>(); Material[] materials = meshRenderer.sharedMaterials; var renderer = meshRenderer.gameObject.AddComponent <SkinnedMeshRenderer>(); renderer.sharedMesh = meshFilter.sharedMesh; UnityEngine.Object.DestroyImmediate(meshFilter); renderer.sharedMaterials = materials; CombineMeshesAndSubMeshes.MakeVerticesHaveWeight(renderer: renderer); } }
private void OnWizardCreate() { CombineMeshesAndSubMeshes.Combine( root: this.root, notCombineRendererObjectNames: this.notCombineRendererObjectNames.Except(new[] { "" }), destinationObjectName: this.destinationObjectName ); EditorUtility.DisplayDialog( CombineMeshesAndSubMeshes.Name, "メッシュ、およびマテリアルが同一であるサブメッシュの結合が完了しました。", "OK" ); }
/// <summary> /// メッシュを結合します。 /// </summary> /// <param name="root"></param> /// <param name="notCombineRendererObjectNames">結合しないメッシュレンダラーのオブジェクト名。</param> /// <param name="destinationObjectName">結合したメッシュのオブジェクト名。</param> /// <returns></returns> public static SkinnedMeshRenderer Combine( GameObject root, IEnumerable <string> notCombineRendererObjectNames, string destinationObjectName ) { CombineMeshesAndSubMeshes.MakeAllVerticesHaveWeights( root: root, notCombineRendererObjectNames: notCombineRendererObjectNames ); return(CombineMeshesAndSubMeshes.CombineAllMeshes( root: root, destinationObjectName: destinationObjectName, notCombineRendererObjectNames: notCombineRendererObjectNames )); }
/// <summary> /// プレハブが依存しているメッシュを複製・結合します。 /// </summary> /// <param name="prefabInstance"></param> /// <param name="combineMeshesAndSubMeshes"></param> /// <param name="notCombineRendererObjectNames"></param> private static void DuplicateAndCombineMeshes( GameObject prefabInstance, bool combineMeshesAndSubMeshes, IEnumerable <string> notCombineRendererObjectNames ) { var faceMeshRenderer = combineMeshesAndSubMeshes ? null : Duplicator.GetFaceMeshRenderer(prefabInstance: prefabInstance); var sameNameTransform = prefabInstance.transform.Find(VRChatUtility.AutoBlinkMeshPath); if (sameNameTransform && (combineMeshesAndSubMeshes || faceMeshRenderer.transform != sameNameTransform)) { sameNameTransform.name += "-" + VRChatUtility.AutoBlinkMeshPath; } var prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefabInstance); if (combineMeshesAndSubMeshes) { CombineMeshesAndSubMeshes.Combine( root: prefabInstance, notCombineRendererObjectNames, destinationObjectName: VRChatUtility.AutoBlinkMeshPath ); } else { if (faceMeshRenderer.transform != sameNameTransform) { faceMeshRenderer.transform.parent = prefabInstance.transform; faceMeshRenderer.transform.name = VRChatUtility.AutoBlinkMeshPath; } } PrefabUtility.SaveAsPrefabAssetAndConnect(prefabInstance, prefabPath, InteractionMode.AutomatedAction); var alreadyDuplicatedMeshes = new Dictionary <Mesh, Mesh>(); foreach (var renderer in prefabInstance.GetComponentsInChildren <SkinnedMeshRenderer>()) { if (combineMeshesAndSubMeshes && renderer.name == VRChatUtility.AutoBlinkMeshPath) { continue; } var mesh = renderer.sharedMesh; renderer.sharedMesh = alreadyDuplicatedMeshes.ContainsKey(mesh) ? alreadyDuplicatedMeshes[mesh] : Duplicator.DuplicateAssetToFolder <Mesh>( source: mesh, prefabInstance, fileName: Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(mesh)) == VRChatUtility.AutoBlinkMeshPath + ".asset" ? VRChatUtility.AutoBlinkMeshPath + "-" + VRChatUtility.AutoBlinkMeshPath + ".asset" : "" ); alreadyDuplicatedMeshes[mesh] = renderer.sharedMesh; } foreach (var filter in prefabInstance.GetComponentsInChildren <MeshFilter>()) { Mesh mesh = filter.sharedMesh; filter.sharedMesh = alreadyDuplicatedMeshes.ContainsKey(mesh) ? alreadyDuplicatedMeshes[mesh] : Duplicator.DuplicateAssetToFolder <Mesh>( source: mesh, prefabInstance, fileName: Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(mesh)) == VRChatUtility.AutoBlinkMeshPath + ".asset" ? VRChatUtility.AutoBlinkMeshPath + "-" + VRChatUtility.AutoBlinkMeshPath + ".asset" : "" ); alreadyDuplicatedMeshes[mesh] = filter.sharedMesh; } }