用odin实现的资源复制编辑器

用odin实现了一个资源复制编辑器,使用要安装odin,功能是把要复制的资源路径一个个添加设置,点copy能把列表里的资源全部复制,支持目录复制到目录,文件复制到目录,文件复制替换。提升效率,让自己有更多的时间研究其他东西或者休息,需要注意的是只有一个目标路径的情况下,不能同时填源文件路径和源文件夹路径,不然不知道要拷贝文件还是文件夹,这个应该很好理解吧。代码如下:

csharp 复制代码
using UnityEditor;
using UnityEngine;
using Sirenix.OdinInspector.Editor;
using Sirenix.OdinInspector;
using System;
using System.IO;
using System.Collecttions.Generic;
public class PathTableListWindow : OdinEditorWindow
{
    [MenuItem("Window/Open Path Table List")]
    private static void OpenWindow()
    {
        // GetExistingOrCreateNewWindow 是一个用于创建或获取已存在窗口的辅助方法
        var window = GetWindow<PathTableListWindow>();
        window.Show();
    }

    // 示例数据,用于在编辑器窗口中显示
    [TableList]
    public List<Item> PathItems = new List<Item>();

    [Button("Copy")]
    private void CopyAssets()
    {
        foreach(var item in PathItems)
        {
			if (Directory.Exists(item.SourcePath))
	        {
	            // 如果源路径是文件夹,则递归复制所有文件和子文件夹
	            CopyDirectory(item.SourcePath, item.TargetPath);
	        }
	        else if (File.Exists(item.SourcePath))
	        {
	            // 如果源路径是文件,则直接复制文件
	            string destDir = Path.GetDirectoryName(item.TargetPath);
	            if (!Directory.Exists(destDir))
	            {
	                Directory.CreateDirectory(destDir);
	            }
	            File.Copy(item.SourcePath, item.TargetPath, true);
	        }
	        if(!string.IsNullOrEmpty(item.SourceFilePath))
	        {
				if(string.IsNullOrEmpty(item.TargetFilePath)
				{
					var destFile = Path.Combine(item.TargetPath,Path.GetFileName(item.TargetFilePath));
					File.Copy(item.SourceFilePath, destFile, true);
				}
				else
				{
					File.Copy(item.SourceFilePath, item.TargetFilePath, true);
				}
			}
		}
    }
	 private void CopyDirectory(string source, string destination)
    {
       	if(File.GetAttributes(source).HasFlag(FileAttributes.Directory))
       	{
			 string targetDest = Path.Combine(destination,Path.GetFileName(source));
	        if(!Directory.Exists(targetDest))
	        {
				// 创建目标目录
	        	Directory.CreateDirectory(targetDest );
			}
			 
		        // 递归复制子目录
		        string[] dirs = Directory.GetDirectories(source);
		        foreach (string dir in dirs)
		        {
		            string destDir = Path.Combine(targetDest, Path.GetFileName(dir));
		            CopyDirectory(dir, destDir);
		        }
		         // 获取源目录下的所有文件
        		string[] files = Directory.GetFiles(source);
        		 foreach (string file in files)
		        {
		            string destFile = Path.Combine(targetDest, Path.GetFileName(file));
		            File.Copy(file, destFile, true);
		        }
		}
		else
		{
			 // 获取源目录下的所有文件
        		string[] files = Directory.GetFiles(source);
        		
        		 foreach (string file in files)
		        {
		            string destFile = Path.Combine(destination, Path.GetFileName(file));
		            File.Copy(file, destFile, true);
		        }
		}
       
        
        

      
       

        
    }
   
    [System.Serializable]
        public class Item
        {
            [TableColumnWidth(60)]
            [FolderPath, PropertyOrder(-1),HorizontalGroup("资源路径列表",0.25f)]
            public string SourcePath;

            [FolderPath, PropertyOrder(-1),HorizontalGroup("资源路径列表",0.25f)]
            public string TargetPath;
            [FilePath, PropertyOrder(-2),HorizontalGroup("资源路径列表",0.25f)]
            public string TargeFiletPath;
            [FilePath, PropertyOrder(-2),HorizontalGroup("资源路径列表",0.25f)]
            public string SourceFilePath;
        }
}

扩展:odin本身的floderpath并不支持项目外的文件夹拖拽,只能点按钮选择路径,为了更加方便的支持拖拽,我新增了一个属性拓展了它的功能,代码如下:

csharp 复制代码
public class DraggableFloderPath:Attribute
{
}
public class DraggableFolderPathAttributeProcessor : OdinAttributeProcessor<DraggableFloderPath>
{
    public override void ProcessSelfAttributes(InspectorProperty property, List<Attribute> attributes)
    {
        base.ProcessSelfAttributes(property,attributes);
        attributes.Add(new FolderPathAttribute());
    }
}
public class DraggableFolderPathDrawer : OdinAttributeDrawer<DraggableFloderPath, string>
{
    protected override void DrawPropertyLayout(GUIContent label)
    {
       
        EditorGUILayout.BeginHorizontal(); 
      
        // 创建输入框和拖拽区域
        Rect dragArea= EditorGUILayout.GetControlRect();
        
        ValueEntry.SmartValue = EditorGUI.TextField(dragArea, label, ValueEntry.SmartValue);

        // 拖拽功能
        if ((Event.current.type == EventType.DragUpdated || Event.current.type == EventType.DragPerform) && dragArea.Contains(Event.current.mousePosition))
        {
            DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
            if (Event.current.type == EventType.DragPerform)
            {
                DragAndDrop.AcceptDrag();
                foreach (var path in DragAndDrop.paths)
                {
                    if(File.GetAttributes(source).HasFlag(FileAttributes.Directory))
                    {
						if (!string.IsNullOrEmpty(path) && Directory.Exists(path))
	                    {
	                        
	                        this.ValueEntry.SmartValue = path;
	                        break;
	                    }
					}
                    else
                    {
						this.ValueEntry.SmartValue = path;
	                    break;
					}
                }
                Event.current.Use();
            }
        }

        // 绘制一个按钮
        if (GUILayout.Button(EditorGUIUtility.IconContent("Folder Icon"),GUILayout.Width(30),GUILayout.Height(20)))
        {
            string selectedPath = EditorUtility.OpenFolderPanel("Select Folder", "", "");
            if (!string.IsNullOrEmpty(selectedPath))
            {
                this.ValueEntry.SmartValue = selectedPath;
            }
        }

        EditorGUILayout.EndHorizontal(); 
    }
}
//然后就可以直接使用了
[System.Serializable]
        public class Item
        {
            [TableColumnWidth(60)]
            [DraggableFloderPath, PropertyOrder(-1),HorizontalGroup("资源路径列表",0.25f)]
            public string SourcePath;

            [DraggableFloderPath, PropertyOrder(-1),HorizontalGroup("资源路径列表",0.25f)]
            public string TargetPath;
            [DraggableFloderPath, PropertyOrder(-2),HorizontalGroup("资源路径列表",0.25f)]
            public string TargeFiletPath;
            [DraggableFloderPath, PropertyOrder(-2),HorizontalGroup("资源路径列表",0.25f)]
            public string SourceFilePath;
        }

这样生成出来的样式几乎跟floderpath一样,但是text区域可以支持拖拽,拷贝不同项目的文件更加方便。

相关推荐
^乘风破浪^2 分钟前
Centos升级openssh及openssl
linux·运维·centos
满天星83035773 分钟前
【Linux】【进程间通信】管道
linux·运维·服务器
linux修理工4 分钟前
CentOS Stream 9 软件仓库 清华源
linux·运维·centos
naodianbozzz5 分钟前
nginx的https的搭建
运维·nginx·https
liefyuan6 分钟前
【嵌入式Linux】添加sshd (顺便dropbear--scp命令)
linux·运维
Han.miracle10 分钟前
JavaEE--网络编程 传输层 (一) UDP TCP特点
运维·服务器·网络·java-ee·三次握手·四次挥手·超时重传
Gogo81610 分钟前
docker 容器
运维·docker·容器
I · T · LUCKYBOOM12 分钟前
18.通过密钥免密访问目标服务器,脚本运行过程中不需要额外交互
linux·运维·服务器
深圳市恒讯科技15 分钟前
高防服务器支持哪些协议和端口防护?
运维·服务器·网络
软件测试慧姐19 分钟前
精简版-Linux常用命令
linux·运维·服务器