示例#1
0
        /// <summary>
        /// アセットを複製します。
        /// </summary>
        /// <remarks>
        /// 複製先にすでにアセットが存在していれば上書きし、metaファイルは複製しません。
        /// </remarks>
        /// <param name="source"></param>
        /// <param name="duplicatedPath">「Assets/」から始まりファイル名で終わる複製先のパス。</param>
        private static T DuplicateAsset <T>(T source, string destinationPath) where T : Object
        {
            if (source is AnimatorController controller)
            {
                return(Duplicator.DuplicateAnimatorControllerAsset(controller, destinationPath) as T);
            }

            var sourceUnityPath = UnityPath.FromAsset(source);
            var destination     = AssetDatabase.LoadMainAssetAtPath(destinationPath);
            var copied          = false;

            if (destination)
            {
                if (AssetDatabase.IsNativeAsset(source) || !sourceUnityPath.IsUnderAssetsFolder)
                {
                    EditorUtility.CopySerialized(source, destination);
                }
                else
                {
                    var sourceFullPath      = sourceUnityPath.FullPath;
                    var destinationFullPath = destinationPath.AssetPathToFullPath();
                    if (File.GetLastWriteTime(sourceFullPath) != File.GetLastWriteTime(destinationFullPath))
                    {
                        File.Copy(sourceFullPath, destinationFullPath, overwrite: true);
                        AssetDatabase.ImportAsset(destinationPath);
                        copied = true;
                    }
                }
            }
            else
            {
                if (AssetDatabase.IsSubAsset(source) || !sourceUnityPath.IsUnderAssetsFolder)
                {
                    AssetDatabase.CreateAsset(Duplicator.DuplicateAssetInstance(source), destinationPath);
                }
                else
                {
                    AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(source), destinationPath);
                }
            }

            var destinationAsset = AssetDatabase.LoadAssetAtPath <T>(destinationPath);

            if (copied)
            {
                EditorUtility.SetDirty(destinationAsset);
                AssetDatabase.SaveAssets();
            }
            return(destinationAsset);
        }
示例#2
0
        /// <summary>
        /// ルートとなるプレハブを複製します。
        /// </summary>
        /// <param name="sourceAvatar">プレハブ、またはHierarchy上のオブジェクト。</param>
        /// <param name="destinationPath">「Assets/」から始まり「.prefab」で終わる複製先のパス。</param>
        /// <returns></returns>
        private static GameObject DuplicatePrefab(
            GameObject sourceAvatar,
            string destinationPath
            )
        {
            // プレハブ
            GameObject sourceInstance    = Object.Instantiate(sourceAvatar);
            GameObject destinationPrefab = PrefabUtility
                                           .SaveAsPrefabAssetAndConnect(sourceInstance, destinationPath, InteractionMode.AutomatedAction);

            Object.DestroyImmediate(sourceInstance);

            // Avatar
            var animator          = destinationPrefab.GetComponent <Animator>();
            var destinationAvatar = AssetDatabase.LoadAssetAtPath <Avatar>(destinationPath);

            if (destinationAvatar)
            {
                EditorUtility.CopySerialized(animator.avatar, destinationAvatar);
                animator.avatar = destinationAvatar;
            }
            else
            {
                animator.avatar = (Avatar)Duplicator.DuplicateAssetInstance(animator.avatar);
                AssetDatabase.AddObjectToAsset(animator.avatar, destinationPrefab);
            }

            // AvatarDescription (最終的に削除するので、アセットは複製しない)
            var humanoidDescription = destinationPrefab.GetComponent <VRMHumanoidDescription>();

            humanoidDescription.Avatar = animator.avatar;
            var description = humanoidDescription.Description;

            if (description == null)
            {
                // VRMInitializerで生成されたモデル
                description = PrefabUtility.GetOutermostPrefabInstanceRoot(sourceAvatar) // GetDescriptionはFBX等以外では機能しない
                              .GetComponent <VRMHumanoidDescription>().GetDescription(out var _);
            }
            humanoidDescription.Description = description;

            return(destinationPrefab);
        }
示例#3
0
        /// <summary>
        /// アセットを複製します。
        /// </summary>
        /// <remarks>
        /// 複製先にすでにアセットが存在していれば上書きし、metaファイルは複製しません。
        /// </remarks>
        /// <param name="source"></param>
        /// <param name="duplicatedPath">「Assets/」から始まりファイル名で終わる複製先のパス。</param>
        private static void DuplicateAsset(UnityEngine.Object source, string destinationPath)
        {
            var sourceUnityPath = UnityPath.FromAsset(source);

            UnityEngine.Object destination = AssetDatabase.LoadMainAssetAtPath(destinationPath);
            if (destination)
            {
                if (AssetDatabase.IsNativeAsset(source) && !(source is AnimatorController) ||
                    !sourceUnityPath.IsUnderAssetsFolder)
                {
                    EditorUtility.CopySerialized(source, destination);
                }
                else
                {
                    var sourceFullPath      = sourceUnityPath.FullPath;
                    var destinationFullPath = destinationPath.AssetPathToFullPath();
                    if (File.GetLastWriteTime(sourceFullPath) != File.GetLastWriteTime(destinationFullPath))
                    {
                        File.Copy(
                            sourceFileName: sourceFullPath,
                            destFileName: destinationFullPath,
                            overwrite: true
                            );
                        AssetDatabase.ImportAsset(destinationPath);
                    }
                }
            }
            else
            {
                if (AssetDatabase.IsSubAsset(source) || !sourceUnityPath.IsUnderAssetsFolder)
                {
                    AssetDatabase.CreateAsset(Duplicator.DuplicateAssetInstance(source), destinationPath);
                }
                else
                {
                    AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(source), destinationPath);
                }
            }
        }
示例#4
0
        /// <summary>
        /// ルートとなるプレハブを複製します。
        /// </summary>
        /// <param name="sourceAvatar">プレハブ、またはHierarchy上のオブジェクト。</param>
        /// <param name="destinationPath">「Assets/」から始まり「.prefab」で終わる複製先のパス。</param>
        /// <returns></returns>
        private static GameObject DuplicatePrefab(
            GameObject sourceAvatar,
            string destinationPath
            )
        {
            // プレハブ
            GameObject sourceInstance    = UnityEngine.Object.Instantiate(sourceAvatar);
            GameObject destinationPrefab = PrefabUtility
                                           .SaveAsPrefabAssetAndConnect(sourceInstance, destinationPath, InteractionMode.AutomatedAction);

            UnityEngine.Object.DestroyImmediate(sourceInstance);

            // Avatar
            var animator          = destinationPrefab.GetComponent <Animator>();
            var destinationAvatar = AssetDatabase.LoadAssetAtPath <Avatar>(destinationPath);

            if (destinationAvatar)
            {
                EditorUtility.CopySerialized(animator.avatar, destinationAvatar);
                animator.avatar = destinationAvatar;
            }
            else
            {
                animator.avatar = Duplicator.DuplicateAssetInstance(animator.avatar) as Avatar;
                AssetDatabase.AddObjectToAsset(animator.avatar, destinationPrefab);
            }

            // AvatarDescription (最終的に削除するので、アセットは複製しない)
            var humanoidDescription = destinationPrefab.GetComponent <VRMHumanoidDescription>();

            humanoidDescription.Avatar = animator.avatar;
            humanoidDescription.Description
                = Duplicator.DuplicateAssetInstance(humanoidDescription.Description) as AvatarDescription;

            return(destinationPrefab);
        }