文章目录

  • 目的
  • 没那么美观的功能
  • 使用
  • 先打开 SVN log
  • 选中你想导出的 svn url
  • Git 中同样可以 copy submits option url 的方式
  • 到工具面板
  • 选中导出 unitypackage 文件目录
  • 将导出的 unitypackage 拖拽入 程序工程即可
  • 此工具缺点
  • 稍微美观一些的工具(主要使用拖拽)
  • 使用起来比前一个工具方便多了
  • 也可以 CTRL + V 已复制的 svn url
  • 还可以脚本化



目的

主要用途是便于美术工程中,将零零散散的资源一次导出到 unitypackage,再导入到程序工程的一个工具


没那么美观的功能

// jave.lin 2021/04/07

using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

public class FileOptInfo
{
    public bool export;
    public string path;
}

public class CustomExportPackageWindow : EditorWindow
{
    private static string[] lineSpliter = new string[] { "\n" };

    private Vector2 fileOptScrollPos;
    private Vector2 selectFileDependentsScrollPos;
    private Vector2 allExportFilesPos;

    private List<FileOptInfo> fileOptInfoList = new List<FileOptInfo>();

    private FileOptInfo selectFileOpt;
    private FileOptInfo lastFileOpt;

    private string[] lastFileOptDepsList;

    private string ignorePrefixStr = "https://192.168.1.x:xxx/svn/xxx/x/xxx/xxx/";

    private List<FileOptInfo> allExportFileOptList = new List<FileOptInfo>();

    [MenuItem("Tools/CustomExportPackageWindow")]
    public static void _Show()
    {
        var win = EditorWindow.GetWindow<CustomExportPackageWindow>();
        win.Show();
    }
    private void OnGUI()
    {
        EditorGUILayout.BeginVertical();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Ignore Prefix : ", GUILayout.Width(100));
        ignorePrefixStr = EditorGUILayout.TextField(ignorePrefixStr);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        
        // File Opt
        
        fileOptScrollPos = EditorGUILayout.BeginScrollView(fileOptScrollPos, GUILayout.Width(600), GUILayout.Height(300));
        EditorGUILayout.BeginVertical();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("File Opt", GUILayout.Width(100));
        if (GUILayout.Button("Refresh From Clipboard Text"))
        {
            selectFileOpt = null;
            fileOptInfoList.Clear();

            var cbBufStr = GUIUtility.systemCopyBuffer;
            if (!string.IsNullOrEmpty(cbBufStr))
            {
                var lines = cbBufStr.Split(lineSpliter, StringSplitOptions.RemoveEmptyEntries);
                if (lines != null && lines.Length > 0)
                {
                    foreach (var line in lines)
                    {
                        var newLine = line.Replace(ignorePrefixStr, "");
                        fileOptInfoList.Add(new FileOptInfo
                        {
                            export = true,
                            path = newLine,
                        });
                    }
                }
            }
        }
        EditorGUILayout.EndHorizontal();

        if (fileOptInfoList.Count == 0)
        {
            EditorGUILayout.LabelField("[EMPTY]");
        }
        else
        {
            foreach (var opt in fileOptInfoList)
            {
                EditorGUILayout.BeginHorizontal();
                opt.export = EditorGUILayout.Toggle(opt.export, GUILayout.Width(20));
                if (GUILayout.Button("ShowDeps", GUILayout.Width(80)))
                {
                    selectFileOpt = opt;
                }
                EditorGUILayout.TextField(opt.path);
                EditorGUILayout.EndHorizontal();
            }
        }
        
        EditorGUILayout.EndVertical();
        EditorGUILayout.EndScrollView();

        
        // Select File Dependents
        
        selectFileDependentsScrollPos = EditorGUILayout.BeginScrollView(selectFileDependentsScrollPos/*, GUILayout.Width(300), GUILayout.Width(300)*/);
        EditorGUILayout.BeginVertical();
        EditorGUILayout.LabelField("Select File Dependents");

        if (selectFileOpt != null)
        {
            if (lastFileOpt != selectFileOpt)
            {
                lastFileOpt = selectFileOpt;
                lastFileOptDepsList = AssetDatabase.GetDependencies(selectFileOpt.path.Trim());
            }
        }
        
        if (lastFileOptDepsList != null && lastFileOptDepsList.Length > 0)
        {
            foreach (var deps in lastFileOptDepsList)
            {
                EditorGUILayout.TextField(deps);
            }
        }

        EditorGUILayout.EndVertical();
        EditorGUILayout.EndScrollView();

        EditorGUILayout.EndHorizontal();


        
        // All Export Files
        
        allExportFilesPos = EditorGUILayout.BeginScrollView(allExportFilesPos/*, GUILayout.Width(300), GUILayout.Width(300)*/);
        EditorGUILayout.BeginVertical();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("All Export Files");
        if (GUILayout.Button("Refresh", GUILayout.Width(100)))
        {
            HashSet<string> distincSet = new HashSet<string>();
            foreach (var opt in fileOptInfoList)
            {
                if (!opt.export) continue;

                var deps = AssetDatabase.GetDependencies(opt.path.Trim());

                foreach (var dep in deps)
                {
                    if (!distincSet.Contains(dep))
                    {
                        distincSet.Add(dep);
                    }
                }
            }

            var depArr = new string[distincSet.Count];
            distincSet.CopyTo(depArr);

            Array.Sort(depArr);

            allExportFileOptList.Clear();
            foreach (var dep in depArr)
            {
                allExportFileOptList.Add(new FileOptInfo { export = true, path = dep });
            }
        }
        if (GUILayout.Button("Export", GUILayout.Width(100)))
        {
            if (allExportFileOptList.Count > 0)
            {
                var exportCount = 0;
                foreach (var opt in allExportFileOptList)
                {
                    if (opt.export) exportCount++;
                }
                if (exportCount > 0)
                {
                    var title = "Save Export Unity Package";
                    var now = DateTime.Now;
                    var defaultName = $"{now.Year}_{now.Month}_{now.Day}_{now.Hour}_{now.Minute}_{now.Second}_ToPGUnityPackage";
                    var extension = "unitypackage";
                    var savePath = EditorUtility.SaveFilePanel(title, Application.dataPath, defaultName, extension);
                    var dirPath = Path.GetDirectoryName(savePath);
                    if (!string.IsNullOrEmpty(savePath) && Directory.Exists(dirPath))
                    {
                        var exports = new string[exportCount];
                        var idx = 0;
                        foreach (var opt in allExportFileOptList)
                        {
                            if (opt.export)
                            {
                                exports[idx++] = opt.path.Trim();
                            }
                        }
                        AssetDatabase.ExportPackage(exports, savePath, ExportPackageOptions.Default);
                        System.Diagnostics.Process.Start("explorer.exe", dirPath);
                        //System.Diagnostics.Process.Start("explorer.exe", $"{dirPath} /select {savePath}");
                    }
                }
            }
        }
        EditorGUILayout.EndHorizontal();

        if (allExportFileOptList.Count > 0)
        {
            foreach (var opt in allExportFileOptList)
            {
                EditorGUILayout.BeginHorizontal();
                opt.export = EditorGUILayout.Toggle(opt.export, GUILayout.Width(20));
                EditorGUILayout.TextField(opt.path);
                EditorGUILayout.EndHorizontal();
            }
        }

        EditorGUILayout.EndVertical();
        EditorGUILayout.EndScrollView();


        EditorGUILayout.EndVertical();
    }
}

使用


先打开 SVN log

如何将unitypacket导入unity unity导入package_List


选中你想导出的 svn url

如何将unitypacket导入unity unity导入package_custom 导包_02

  • CTRL + C
  • 或是右键 Copy to clipboard/Urls, URLs with revision, Paths relative to root, Filenames,如下图

如何将unitypacket导入unity unity导入package_自定义导包_03


Git 中同样可以 copy submits option url 的方式

Git 的当时没截图,现在就不放上来了


到工具面板

如何将unitypacket导入unity unity导入package_custom 导包_04

1,2,3 步骤

选中导出 unitypackage 文件目录

如何将unitypacket导入unity unity导入package_svn_05

将导出的 unitypackage 拖拽入 程序工程即可

如何将unitypacket导入unity unity导入package_System_06


可以看到,和 unity 自带的 Export Package… 再 Import Package… 时的方式是一致的

但是导入的时候,我们可以高度自由的添加,删除不需要的导出内容

此工具缺点

如果你选中的一些 svn commit 上的记录文件,在后续的 svn update 中有 Remove 的话

那么 copy 到的 svn url 将不会导入、导出


稍微美观一些的工具(主要使用拖拽)

// jave.lin 2021/04/07

using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

public class FileOptInfo
{
	public bool export;
	public string path;
	public UnityEngine.Object obj;
}

public class ClipboardImportInfo
{
	public bool import;
	public string path;
}

public class CustomExportPackageClipboardDialog : EditorWindow
{
    private string ignorePrefixStr = "https://192.168.x.x:xxx/xx/xxx/xxx/xxx/xxx/";
	private string lastIgnorePrefixStr;
	private Vector2 scrollViewPos;

	private string clipboardStr;
	private List<string> srcLines = new List<string>();
	private List<ClipboardImportInfo> filterImportInfoList = new List<ClipboardImportInfo>();
	private List<string> filterLines = new List<string>();

	public static List<string> ShowDialog(EditorWindow parent)
    {
#if UNITY_2019_4_OR_NEWER

		var win = EditorWindow.GetWindow<CustomExportPackageClipboardDialog>();
		var w = parent.position.width * 0.5f;
		var h = parent.position.height * 0.5f;
		var x = parent.position.x + (w) * 0.5f;
		var y = parent.position.y + (h) * 0.5f;
		var rect = new Rect(x, y, w, h);
		//var win = EditorWindow.GetWindowWithRect(
		//	typeof(CustomExportPackageClipboardDialog), 
		//	rect, false, "Filter Clipboard Data")
		//	as CustomExportPackageClipboardDialog; // rect 参数这是没有效果

		win.clipboardStr = GUIUtility.systemCopyBuffer;
		var lines = win.clipboardStr.Split(new string[] { "\n\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
        foreach (var line in lines)
        {
			var tempLine = line.Trim();
			if (string.IsNullOrEmpty(tempLine))
			{
				continue;
			}
			win.srcLines.Add(line);
        }

		win.position = rect; // 上面的 GetWindowWithRect 中的 rect 参数没有效果,只能在 EditorWindow.position 上设置才有效果
		win.titleContent = new GUIContent("过滤剪贴板内容");
		win.ShowModal();
		return win.GetFilterPaths();
#else
		return new List<string>();
#endif
	}

	public List<string> GetFilterPaths()
    {
		filterLines.Clear();
        foreach (var info in filterImportInfoList)
        {
			if (info.import) filterLines.Add(info.path);
        }
		return filterLines;
    }

    private void OnGUI()
    {
		//if (GUILayout.Button("OK"))
		//{
		//	this.Close();
		//	return;
		//}

		EditorGUILayout.BeginHorizontal();
		EditorGUILayout.LabelField("Ignore Prefix : ", GUILayout.Width(100));
		ignorePrefixStr = EditorGUILayout.TextField(ignorePrefixStr);
		EditorGUILayout.EndHorizontal();

		scrollViewPos = EditorGUILayout.BeginScrollView(scrollViewPos);

		if (lastIgnorePrefixStr != ignorePrefixStr)
		{
			lastIgnorePrefixStr = ignorePrefixStr;
			filterLines.Clear();

			foreach (var line in srcLines)
			{
				var newLineContent = line;
				if (!string.IsNullOrEmpty(ignorePrefixStr) && line.StartsWith(ignorePrefixStr))
				{
					newLineContent = line.Substring(ignorePrefixStr.Length);
				}
				newLineContent = newLineContent.Trim();
				if (!string.IsNullOrEmpty(newLineContent))
				{
					filterLines.Add(newLineContent);
				}
			}
			if (filterImportInfoList.Count == 0)
			{
				foreach (var line in filterLines)
				{
					filterImportInfoList.Add(new ClipboardImportInfo { import = true, path = line });
				}
			}
			else
			{
				for (int i = 0; i < filterLines.Count; i++)
				{
					var info = filterImportInfoList[i];
					info.path = filterLines[i];
				}
			}
		}

		EditorGUILayout.BeginVertical();
		foreach (var info in filterImportInfoList)
		{
			EditorGUILayout.BeginHorizontal();
			info.import = EditorGUILayout.Toggle(info.import, GUILayout.Width(12));
			EditorGUILayout.TextField(info.path);
			EditorGUILayout.EndHorizontal();
		}
		EditorGUILayout.EndVertical();

		EditorGUILayout.EndScrollView();
	}
}

public class CustomExportPackageWindow : EditorWindow
{
	public static string[] clipboardAssetPaths;

	private Vector2 dragDropFileScrollViewPos;
	private Vector2 allExportFileScrollViewPos;

	private List<FileOptInfo> fileOptInfoList = new List<FileOptInfo>();
	private List<FileOptInfo> allExportFileOptList = new List<FileOptInfo>();

	private List<string> pushList = new List<string>();

	private Action OnRefreshDepsEvent;

	public string defaultExportPath = null; // "Assets/ExportUnityPackage";
	public bool useDefaultExportPath = false;

	[MenuItem("实用工具/资源工具/自定义的资源导出工具")]
    public static void _Show()
    {
        var win = EditorWindow.GetWindow<CustomExportPackageWindow>();
		win.titleContent = new GUIContent("自定义的资源导出工具");
		win.Init();
        win.Show();
    }

	private void Init()
    {
		OnRefreshDepsEvent = OnRefreshDepsEventCallback;
	}

	private void OnRefreshDepsEventCallback()
    {
		RefreshDeps();
    }

	private void HandlePushList()
    {
		if (pushList.Count > 0)
        {
			var havePushSuccess = false;
            foreach (var path in pushList)
            {
				var tempPath = path.Trim();
				if (string.IsNullOrEmpty(tempPath))
                {
					continue;
                }
				if (AddPath(path))
                {
					havePushSuccess = true;
				}
			}
			pushList.Clear();

			if (havePushSuccess) OnRefreshDepsEvent?.Invoke();
		}
    }

	private void OnGUI()
    {
		///
		/// Handle Push List
		///
		HandlePushList();

		///
		/// Handle Clipboard Data
		///
		HandleClipboardData();

		///
		/// Drag and Drop
		///
		DragDrop();

		EditorGUILayout.BeginHorizontal();
		///
		/// Display Files
		///
		DisplayFileOptList();

		///
		/// Display All Dependencies
		///
		DisplayAllDependencies();
		EditorGUILayout.EndHorizontal();
	}

	private void HandleClipboardData()
    {
		if (Event.current.control && Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.V)
        {
			if (!string.IsNullOrEmpty(GUIUtility.systemCopyBuffer))
			{
				var paths = CustomExportPackageClipboardDialog.ShowDialog(this);
				if (paths != null && paths.Count > 0)
                {
                    foreach (var path in paths)
                    {
						pushList.Add(path);
					}
				}
			}
		}
	}

	public void RefreshDeps()
    {
		HashSet<string> distincSet = new HashSet<string>();
		foreach (var opt in fileOptInfoList)
		{
			if (!opt.export) continue;

			var deps = AssetDatabase.GetDependencies(opt.path.Trim());

			foreach (var dep in deps)
			{
				if (!distincSet.Contains(dep))
				{
					distincSet.Add(dep);
				}
			}
		}

		var depArr = new string[distincSet.Count];
		distincSet.CopyTo(depArr);

		Array.Sort(depArr);

		// Record src export value
		Dictionary<string, bool> srcExportDict = new Dictionary<string, bool>();
        foreach (var opt in allExportFileOptList)
        {
			srcExportDict[opt.path] = opt.export;
        }

		allExportFileOptList.Clear();
		foreach (var dep in depArr)
		{
			// Try recovery src export value
			if (!srcExportDict.TryGetValue(dep, out bool srcExportValue))
            {
				// If not found, default export value EQUALS : true
				srcExportValue = true;
			}
			allExportFileOptList.Add(new FileOptInfo { export = srcExportValue, path = dep });
		}
	}

	private void DisplayFileOptList()
    {
		EditorGUILayout.BeginVertical();

		EditorGUILayout.BeginHorizontal();
		if (GUILayout.Button("Clear"))
		{
			fileOptInfoList.Clear();
			allExportFileOptList.Clear();
		}
		if (GUILayout.Button("Refresh Deps"))
		{
			OnRefreshDepsEvent?.Invoke();
		}
		EditorGUILayout.EndHorizontal();

		EditorGUILayout.LabelField("DragDrop Files:");

		dragDropFileScrollViewPos = EditorGUILayout.BeginScrollView(dragDropFileScrollViewPos/*, GUILayout.Width(300), GUILayout.Width(300)*/);

		var refreshDepsEventFire = false;
		for (int i = 0; i < fileOptInfoList.Count; i++)
		{
			var remove = false;
			var info = fileOptInfoList[i];
			EditorGUILayout.BeginHorizontal();
			bool srcExportValue = info.export;
			info.export = EditorGUILayout.Toggle(info.export, GUILayout.Width(12));
			if (srcExportValue != info.export)
			{
				refreshDepsEventFire = true;
			}
			remove = GUILayout.Button("X", GUILayout.Width(20));
			if (info.obj == null)
			{
				info.obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(info.path);
			}
			EditorGUILayout.ObjectField(info.obj, typeof(UnityEngine.Object), false, GUILayout.Width(40));
			EditorGUILayout.TextField(info.path);
			EditorGUILayout.EndHorizontal();
			if (remove)
			{
				fileOptInfoList.RemoveAt(i);
				--i;
				refreshDepsEventFire = true;
			}
		}
		if (refreshDepsEventFire)
		{
			OnRefreshDepsEvent?.Invoke();
		}
		EditorGUILayout.EndScrollView();
		EditorGUILayout.EndVertical();
    }

	private void DisplayAllDependencies()
	{
		EditorGUILayout.BeginVertical();

		EditorGUILayout.BeginHorizontal();

		EditorGUILayout.LabelField("All Export Files:");

		if (GUILayout.Button("Export", GUILayout.Width(100)))
        {
            Export();
        }
        EditorGUILayout.EndHorizontal();

		allExportFileScrollViewPos = EditorGUILayout.BeginScrollView(allExportFileScrollViewPos/*, GUILayout.Width(300), GUILayout.Width(300)*/);
		foreach (var info in allExportFileOptList)
		{
			EditorGUILayout.BeginHorizontal();
			info.export = EditorGUILayout.Toggle(info.export, GUILayout.Width(12));
			if (info.obj == null)
			{
				info.obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(info.path);
			}
			EditorGUILayout.ObjectField(info.obj, typeof(UnityEngine.Object), false, GUILayout.Width(40));
			EditorGUILayout.TextField(info.path);
			EditorGUILayout.EndHorizontal();
		}
		EditorGUILayout.EndScrollView();
		EditorGUILayout.EndVertical();
	}

	private void RefreshDefaultExportPath()
    {
		if (string.IsNullOrEmpty(defaultExportPath))
		{
			var dir = Path.GetDirectoryName(Application.dataPath).Replace("\\", "/");
			defaultExportPath = Path.Combine(dir, "ExportUnityPackage");
		}
	}

    public void Export()
    {
		RefreshDefaultExportPath();

		if (allExportFileOptList.Count > 0)
        {
            var exportCount = 0;
            foreach (var opt in allExportFileOptList)
            {
                if (opt.export) exportCount++;
            }
            if (exportCount > 0)
            {
                var title = "Save Export Unity Package";
                var now = DateTime.Now;
                var defaultName = $"{now.Year}_{now.Month}_{now.Day}_{now.Hour}_{now.Minute}_{now.Second}_ToPGUnityPackage";
                var extension = "unitypackage";
				string savePath;
				if (useDefaultExportPath)
                {
					savePath = defaultExportPath;
				}
				else
                {
					savePath = EditorUtility.SaveFilePanel(title, Application.dataPath, defaultName, extension);
				}
				if (!string.IsNullOrEmpty(savePath))
                {
                    var dirPath = Path.GetDirectoryName(savePath);
					if (!Directory.Exists(dirPath))
                    {
						Directory.CreateDirectory(dirPath);
					}
                    var exports = new string[exportCount];
                    var idx = 0;
                    foreach (var opt in allExportFileOptList)
                    {
                        if (opt.export)
                        {
                            exports[idx++] = opt.path.Trim();
                        }
                    }
                    AssetDatabase.ExportPackage(exports, savePath, ExportPackageOptions.Default);
                    //System.Diagnostics.Process.Start("explorer.exe", dirPath);

					// 打开并选中对应的文件
                    //Debug.LogError($"dirPath : {dirPath}");
                    var selectPath = savePath.Replace("/", "\\");
                    //Debug.LogError($"select : {selectPath}");
                    System.Diagnostics.Process.Start("explorer.exe", $"/select,{selectPath}");
                }
            }
        }
    }

    private void DragDrop()
	{
		Event evt = Event.current;
		switch (evt.type)
		{
			case EventType.DragUpdated:
			case EventType.DragPerform:

			DragAndDrop.visualMode = DragAndDropVisualMode.Link;

			if (evt.type == EventType.DragPerform)
			{
				 method 1: handle by objs
				//var objList = new List<UnityEngine.Object>();
				//GetObjsOnDragDrops(DragAndDrop.objectReferences, objList);

				//foreach (UnityEngine.Object draggedObj in objList)
				//{
				//	DoDropObj(draggedObj);
				//}

				// method 2 : handle by obj paths
				var projectViewSelectedObjsPaths = new List<string>();
				TransToPath(DragAndDrop.objectReferences, projectViewSelectedObjsPaths);

				var allProjectViewSelectedObjPaths = new List<string>();
				GetAllObjPathsWithPaths(projectViewSelectedObjsPaths, allProjectViewSelectedObjPaths);

				pushList.AddRange(allProjectViewSelectedObjPaths);
			}
			break;
		}
	}

	private void GetObjsOnDragDrops(UnityEngine.Object[] objs, List<UnityEngine.Object> ret)
    {
		foreach (UnityEngine.Object obj in objs)
		{
			var assetPath = AssetDatabase.GetAssetPath(obj);
			if (JudgeIsAFolder(assetPath))
			{
				var objGUIDs = AssetDatabase.FindAssets("t:Object", new string[] { assetPath });
				var newObjs = new UnityEngine.Object[objGUIDs.Length];
                for (int i = 0; i < objGUIDs.Length; i++)
                {
					var objPath = AssetDatabase.GUIDToAssetPath(objGUIDs[i]);
					newObjs[i] = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(objPath);
                }
				GetObjsOnDragDrops(newObjs, ret);
			}
			else
			{
				ret.Add(obj);
			}
		}
	}

	private void DoDropObj(UnityEngine.Object dragObj)
    {
		pushList.Add(AssetDatabase.GetAssetPath(dragObj));
	}

	private void DoDropPath(string path)
    {
		pushList.Add(path);
	}

	private void TransToPath(UnityEngine.Object[] objs, List<string> objPaths)
    {
        foreach (var obj in objs)
        {
			objPaths.Add(AssetDatabase.GetAssetPath(obj));
		}
    }

	private void GetAllObjPathsWithPaths(List<string> paths, List<string> allObjPaths)
    {
        foreach (var path in paths)
        {
			if (JudgeIsAFolder(path))
			{
				var objGUIDs = AssetDatabase.FindAssets("t:Object", new string[] { path });
				var newPaths = new List<string>();
                foreach (var objGUID in objGUIDs)
                {
					var objPath = AssetDatabase.GUIDToAssetPath(objGUID);
					newPaths.Add(objPath);
				}
				GetAllObjPathsWithPaths(newPaths, allObjPaths);
			}
			else
            {
				allObjPaths.Add(path);
			}
		}
	}

	private bool JudgeIsAFolder(string assetPath)
    {
		return Directory.Exists(assetPath);
    }

	private void DoDropFolder(string path)
    {

    }

	public bool AddPath(string path)
    {
		if (string.IsNullOrEmpty(path))
		{
			Debug.LogError($"{nameof(CustomExportPackageWindow)}.DoDrop path is null.");
			return false;
		}
		if (!AssetDatabase.IsValidFolder(Path.GetDirectoryName(path)))
        {
			Debug.LogError($"{nameof(CustomExportPackageWindow)}.DoDrop path is invalidated");
			return false;
		}

		Debug.Log($"Add File : {path}");

		var found = false;
		for (int i = 0; i < fileOptInfoList.Count; i++)
		{
			var info = fileOptInfoList[i];
			if (info.path == path)
			{
				found = true;
				break;
			}
		}
		if (!found)
		{
			fileOptInfoList.Add(new FileOptInfo { export = true, path = path });
		}
		return !found;
	}
}

使用起来比前一个工具方便多了

如何将unitypacket导入unity unity导入package_自定义导包_07

也可以 CTRL + V 已复制的 svn url

如何将unitypacket导入unity unity导入package_自定义导包_08

最后 Export 按钮即可导出


还可以脚本化

var dir = Path.GetDirectoryName(Application.dataPath).Replace("\\", "/");
var now = DateTime.Now;
var defaultFileName = $"{now.Year}_{now.Month}_{now.Day}_{now.Hour}_{now.Minute}_{now.Second}_ToPGUnityPackage";
var exportPath = Path.Combine(dir, $"ExportUnityPackage/{defaultFileName}.unitypackage").Replace("\\", "/");

try
{
    EditorUtility.DisplayProgressBar("提示", "导出资源中", 1.0f);

    var tool = new CustomExportPackageWindow();
    tool.AddPath(scenePath);
    tool.RefreshDeps();
    tool.useDefaultExportPath = true;
    tool.defaultExportPath = exportPath;
    tool.Export();

    GameObject.DestroyImmediate(tool);
}
catch (Exception er)
{
    Debug.Log($"导出资源中报错:{er}");
}
finally
{
    EditorUtility.ClearProgressBar();
}