IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity复制粘贴功能 -> 正文阅读

[游戏开发]Unity复制粘贴功能

?https://github.com/4000white/UnityCopyPaste

同一项目内,复制粘贴资源,不用打开文件夹操作,或者Dublicate再移动。可以批量复制。

复制文件夹时,文件夹内的资源引用了本文件夹内的其它资源,复制出来的资源的依赖会替换新复制出来的资源

using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using UnityEngine;
using System;
using Object = UnityEngine.Object;

namespace UnityEditor
{
    public class AssetCopyer
    {
        //复制粘贴一个文件夹时,如果有资源引用了文件夹里的其它资源,新复制出来的资源的引用会替换新文件夹里对应的文件,而不是继续引用旧文件夹里的资源
        //执行这种操作的资源的后缀
        private static List<string> includeList = new List<string> { ".prefab", ".mat", ".anim", ".controller" };

        private const string META = ".meta";
#if UNITY_EDITOR_OSX
        private const string DS_STORE = ".DS_Store";
        private static List<string> ignoreList = new List<string> { META, DS_STORE };
#else
        private static List<string> ignoreList = new List<string> {META};
#endif
        private static List<string> copyPaths = new List<string>();
        [MenuItem("Assets/Copy", false, -10000)]
        static void AssetCopy()
        {
            var objs = Selection.GetFiltered<Object>(SelectionMode.Assets);
            copyPaths.Clear();
            foreach (var obj in objs)
            {
                copyPaths.Add(AssetDatabase.GetAssetPath(obj));
            }
        }
        [MenuItem("Assets/Paste", true)]
        static bool ValidAssetPaste()
        {
            return copyPaths.Count > 0;
        }
        [MenuItem("Assets/Paste", false, -10000)]
        static void AssetPaste()
        {
            var pastePosition = AssetDatabase.GetAssetPath(Selection.activeObject);
            if (Path.HasExtension(pastePosition))
            {
                pastePosition = Path.GetDirectoryName(pastePosition);
            }
            foreach (var copyPath in copyPaths)
            {
                if (!string.IsNullOrEmpty(copyPath))
                {
                    var fileName = Path.GetFileName(copyPath);
                    var pastePath = pastePosition + "/" + fileName;
                    Copy(copyPath, pastePath);
                }
            }
        }

        public static void Copy(string copyPath, string pastePath)
        {
            Debug.Log("copy " + copyPath + " to " + pastePath);
            try
            {
                if (!string.IsNullOrEmpty(copyPath))
                {
                    if (Path.HasExtension(copyPath))
                    {
                        CopyFile(copyPath, pastePath);
                    }
                    else
                    {
                        CopyFolder(copyPath, pastePath);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.Log(e);
            }
        }

        //复制单个文件
        private static void CopyFile(string copyPath, string pastePath)
        {
            if (!Path.HasExtension(copyPath) || !Path.HasExtension(pastePath))
            {
                throw new Exception();
            }
            pastePath = NextAvailableFilename(pastePath);
            File.Copy(copyPath, pastePath);
            AssetDatabase.Refresh();
            AssetDatabase.SaveAssets();
            Selection.activeObject = AssetDatabase.LoadMainAssetAtPath(pastePath);
        }
        //复制文件夹
        private static void CopyFolder(string copyPath, string pastePath)
        {
            if (Path.HasExtension(copyPath) || Path.HasExtension(pastePath))
            {
                throw new Exception();
            }
            pastePath = NextAvailableFilename(pastePath);
            Debug.Log("pastePath " + pastePath);
            RecursivelyCopyFolder(copyPath, pastePath);
            AssetDatabase.Refresh();
            ReplaceReferences(copyPath, pastePath);
            AssetDatabase.Refresh();
            AssetDatabase.SaveAssets();
            Selection.activeObject = AssetDatabase.LoadMainAssetAtPath(pastePath);
        }
        //刚复制出来的新文件夹里的资源还是会有对旧文件夹中资源的引用,通过替换guid的方式,把引用替换成对新文件夹中对应文件的引用
        private static void ReplaceReferences(string oldPath, string newPath)
        {
            var guidMap = new Dictionary<string, string>();
            var fullPath = Path.GetFullPath(oldPath);
            var filePaths = GetAllFiles(fullPath);
            var length = fullPath.Length + 1;
            foreach (var filePath in filePaths)
            {
                string extension = Path.GetExtension(filePath);
                if (!ignoreList.Contains(extension))
                {
                    string assetPath = GetRelativeAssetPath(filePath);
                    string relativePath = filePath.Remove(0, length);
                    string guid = AssetDatabase.AssetPathToGUID(assetPath);
                    string copyPath = newPath + "/" + relativePath;
                    string copyGuid = AssetDatabase.AssetPathToGUID(copyPath);
                    if (copyGuid != null)
                    {
                        guidMap[guid] = copyGuid;
                    }
                }
            }

            fullPath = Path.GetFullPath(newPath);
            filePaths = GetAllFiles(fullPath);
            foreach (var filePath in filePaths)
            {
                string extension = Path.GetExtension(filePath);
                if (includeList.Contains(extension))
                {
                    var assetPath = GetRelativeAssetPath(filePath);
                    string[] deps = AssetDatabase.GetDependencies(assetPath, true);
                    var fileString = File.ReadAllText(filePath);
                    bool bChanged = false;
                    foreach (var v in deps)
                    {
                        var guid = AssetDatabase.AssetPathToGUID(v);
                        if (guidMap.ContainsKey(guid))
                        {
                            if (Regex.IsMatch(fileString, guid))
                            {
                                fileString = Regex.Replace(fileString, guid, guidMap[guid]);
                                bChanged = true;
                                var oldFile = AssetDatabase.GUIDToAssetPath(guid);
                                var newFile = AssetDatabase.GUIDToAssetPath(guidMap[guid]);
                            }
                        }
                    }
                    if (bChanged)
                    {
                        File.WriteAllText(filePath, fileString);
                    }
                }
            }
        }

        private static string GetRelativeAssetPath(string fullPath)
        {
            fullPath = fullPath.Replace("\\", "/");
            int index = fullPath.IndexOf("Assets");
            string relativePath = fullPath.Substring(index);
            return relativePath;
        }

        private static string[] GetAllFiles(string fullPath)
        {
            List<string> files = new List<string>();
            foreach (string file in GetFiles(fullPath))
            {
                files.Add(file);
            }
            return files.ToArray();
        }

        private static IEnumerable<string> GetFiles(string path)
        {
            Queue<string> queue = new Queue<string>();
            queue.Enqueue(path);
            while (queue.Count > 0)
            {
                path = queue.Dequeue();
                try
                {
                    foreach (string subDir in Directory.GetDirectories(path))
                    {
                        queue.Enqueue(subDir);
                    }
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine(ex);
                }
                string[] files = null;
                try
                {
                    files = Directory.GetFiles(path);
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine(ex);
                }
                if (files != null)
                {
                    for (int i = 0; i < files.Length; i++)
                    {
                        yield return files[i];
                    }
                }
            }
        }

        static void RecursivelyCopyFolder(string sourcePath, string destPath)
        {
            if (sourcePath == destPath)
            {
                throw new Exception("sourcePath == destPath");
            }
            if (Directory.Exists(sourcePath))
            {
                if (!Directory.Exists(destPath))
                {
                    try
                    {
                        Directory.CreateDirectory(destPath);
                    }
                    catch (Exception ex)
                    {
                        Debug.LogError(ex);
                    }
                }

                List<string> files = new List<string>(Directory.GetFiles(sourcePath));
                files.ForEach(c =>
                {
#if UNITY_EDITOR_OSX
                    if (!c.EndsWith(META) && !c.EndsWith(DS_STORE))
#else
                    if (!c.EndsWith(META))
#endif
                    {
                        string destFile = Path.Combine(destPath, Path.GetFileName(c));
                        File.Copy(c, destFile, true);
                    }
                });
                List<string> folders = new List<string>(Directory.GetDirectories(sourcePath));
                folders.ForEach(c =>
                {
                    string destDir = Path.Combine(destPath, Path.GetFileName(c));
                    RecursivelyCopyFolder(c, destDir);
                });
            }
            else
            {
                throw new Exception("sourcePath is not exist!");
            }
        }

        private static string numberPattern = " ({0})";
        private static bool FileExist(string filePath, bool isFolder)
        {
            if (isFolder)
            {
                return Directory.Exists(filePath);
            }
            else
            {
                return File.Exists(filePath);
            }
        }
        //获取一个不重复的文件名,如 aa (1).prefab
        public static string NextAvailableFilename(string path)
        {
            bool isFolder = !Path.HasExtension(path);
            if (!FileExist(path, isFolder))
            {
                return path;
            }
            string tmp;
            if (Path.HasExtension(path))
            {
                tmp = path.Insert(path.LastIndexOf(Path.GetExtension(path)), numberPattern);
            }
            else
            {
                tmp = path + numberPattern;
            }
            return GetNextFilename(tmp, isFolder);
        }
        private static string GetNextFilename(string pattern, bool isFolder)
        {
            string tmp = string.Format(pattern, 1);
            if (tmp == pattern)
            {
                throw new ArgumentException("The pattern must include an index place-holder", "pattern");
            }

            if (!FileExist(tmp, isFolder))
            {
                return tmp;
            }

            int min = 1, max = 2;
            while (FileExist(string.Format(pattern, max), isFolder))
            {
                min = max;
                max *= 2;
            }

            while (max != min + 1)
            {
                int pivot = (max + min) / 2;

                if (FileExist(string.Format(pattern, pivot), isFolder))
                    min = pivot;
                else
                    max = pivot;
            }

            return string.Format(pattern, max);
        }
    }
}

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-12-24 18:50:05  更:2021-12-24 18:51:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 20:27:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码