用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区域可以支持拖拽,拷贝不同项目的文件更加方便。

相关推荐
楚灵魈23 分钟前
[Linux]从零开始的网站搭建教程
linux·运维·服务器
小小不董25 分钟前
《Linux从小白到高手》理论篇:深入理解Linux的网络管理
linux·运维·服务器·数据库·php·dba
豆豆43 分钟前
为什么用PageAdmin CMS建设网站?
服务器·开发语言·前端·php·软件构建
DY009J1 小时前
深度探索Kali Linux的精髓与实践应用
linux·运维·服务器
什么鬼昵称2 小时前
Pikachu- Over Permission-垂直越权
运维·服务器
码农小白2 小时前
linux驱动:(22)中断节点和中断函数
linux·运维·服务器
4647的码农历程2 小时前
Linux网络编程 -- 网络基础
linux·运维·网络
醉颜凉3 小时前
银河麒麟桌面操作系统V10 SP1:取消安装应用的安全授权认证
运维·安全·操作系统·国产化·麒麟·kylin os·安全授权认证
2401_857610033 小时前
SpringBoot实现:校园资料分享平台开发指南
服务器·spring boot·php
C++忠实粉丝3 小时前
Linux环境基础开发工具使用(2)
linux·运维·服务器