/// <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); }
/// <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); }
/// <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); } } }
/// <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); }