Пример #1
0
        private void OnWizardCreate()
        {
            if (string.IsNullOrEmpty(this.destinationPath))
            {
                string sourcePath = this.GetAssetsPath(vrm: this.avatar.gameObject);
                this.destinationPath = UnityPath.FromUnityPath(sourcePath).Parent
                                       .Child(Path.GetFileNameWithoutExtension(sourcePath) + " (VRChat).prefab").Value;
            }
            else
            {
                UnityPath destinationFolderUnityPath = UnityPath.FromUnityPath(this.destinationPath).Parent;
                while (!destinationFolderUnityPath.IsDirectoryExists)
                {
                    destinationFolderUnityPath = destinationFolderUnityPath.Parent;
                }
                this.destinationPath = destinationFolderUnityPath.Child(Path.GetFileName(this.destinationPath)).Value;
            }

            string destinationPath = EditorUtility.SaveFilePanelInProject(
                "",
                Path.GetFileName(path: this.destinationPath),
                "prefab",
                "",
                Path.GetDirectoryName(path: this.destinationPath)
                );

            if (string.IsNullOrEmpty(destinationPath))
            {
                Wizard.Open(avatar: this.avatar.gameObject);
                return;
            }
            this.destinationPath = destinationPath;

            // プレハブ、およびシーン上のプレハブインスタンスのBlueprint IDを取得
            string prefabBlueprintId = "";
            var    blueprintIds      = new Dictionary <int, string>();
            var    previousPrefab    = AssetDatabase.LoadMainAssetAtPath(this.destinationPath) as GameObject;

            if (previousPrefab)
            {
                var pipelineManager = previousPrefab.GetComponent <PipelineManager>();
                prefabBlueprintId = pipelineManager ? pipelineManager.blueprintId : "";

                GameObject[] previousRootGameObjects = SceneManager.GetActiveScene().GetRootGameObjects();
                blueprintIds = previousRootGameObjects
                               .Where(root => PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(root) == this.destinationPath)
                               .Select(root =>
                {
                    var manager     = root.GetComponent <PipelineManager>();
                    var blueprintId = manager ? manager.blueprintId : "";
                    return(new
                    {
                        index = Array.IndexOf(previousRootGameObjects, root),
                        blueprintId = blueprintId != prefabBlueprintId ? blueprintId : "",
                    });
                }).ToDictionary(
                    keySelector: indexAndBlueprintId => indexAndBlueprintId.index,
                    elementSelector: indexAndBlueprintId => indexAndBlueprintId.blueprintId
                    );
            }

            GameObject prefabInstance = Duplicator.Duplicate(
                sourceAvatar: this.avatar.gameObject,
                destinationPath: this.destinationPath,
                notCombineRendererObjectNames: this.notCombineRendererObjectNames,
                combineMeshesAndSubMeshes: this.combineMeshes
                );

            var messages = new List <Converter.Message>();

            if (this.forQuest)
            {
                messages.AddRange(Wizard.GenerateQuestLimitationsErrorMessages(prefab: prefabInstance));
            }

            this.SaveSettings();

            foreach (VRMSpringBone springBone in this.GetSpringBonesWithComments(prefab: prefabInstance, comments: this.excludedSpringBoneComments)
                     .SelectMany(springBone => springBone))
            {
                UnityEngine.Object.DestroyImmediate(springBone);
            }

            var clips = VRMUtility.GetAllVRMBlendShapeClips(avatar: this.avatar.gameObject);

            messages.AddRange(Converter.Convert(
                                  prefabInstance: prefabInstance,
                                  clips: clips,
                                  swayingObjectsConverterSetting: this.swayingObjects,
                                  takingOverSwayingParameters: this.takeOverSwayingParameters,
                                  swayingParametersConverter: this.swayingParametersConverter,
                                  enableAutoEyeMovement: this.enableEyeMovement,
                                  addedShouldersPositionY: this.shoulderHeights,
                                  moveEyeBoneToFrontForEyeMovement: this.moveEyeBoneToFrontForEyeMovement,
                                  forQuest: this.forQuest,
                                  addedArmaturePositionY: this.armatureHeight,
                                  useAnimatorForBlinks: this.useAnimatorForBlinks,
                                  useShapeKeyNormalsAndTangents: this.useShapeKeyNormalsAndTangents,
                                  vrmBlendShapeForFINGERPOINT: !string.IsNullOrEmpty(this.blendShapeForFingerpoint)
                    ? VRMUtility.GetUserDefinedBlendShapeClip(clips, this.blendShapeForFingerpoint) as VRMBlendShapeClip
                    : null
                                  ));

            // 変換前のプレハブのPipeline ManagerのBlueprint IDを反映
            if (!string.IsNullOrEmpty(prefabBlueprintId))
            {
                prefabInstance.GetComponent <PipelineManager>().blueprintId = prefabBlueprintId;
            }

            if (this.postConverting != null)
            {
                this.postConverting(prefabInstance, prefabInstance.GetComponent <VRMMeta>());
            }

            PrefabUtility.ApplyPrefabInstance(prefabInstance, InteractionMode.AutomatedAction);

            // 変換前のプレハブインスタンスのPipeline ManagerのBlueprint IDを反映
            GameObject[] rootGameObjects = SceneManager.GetActiveScene().GetRootGameObjects();
            foreach (var(avatarIndex, blueprintId) in blueprintIds)
            {
                if (string.IsNullOrEmpty(blueprintId))
                {
                    continue;
                }
                rootGameObjects[avatarIndex].GetComponent <PipelineManager>().blueprintId = blueprintId;
            }

            if (blueprintIds.Count > 0)
            {
                // シーンのルートに、すでに他のプレハブインスタンスが存在していれば、変換用のインスタンスは削除
                UnityEngine.Object.DestroyImmediate(prefabInstance);
            }

            ResultDialog.Open(messages: messages);
        }