首次提交
This commit is contained in:
8
Assets/Scripts/NBC/Asset.meta
Normal file
8
Assets/Scripts/NBC/Asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 841fa3f7e4afc064c82bb2e5d8ae49c4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/NBC/Asset/Editor.meta
Normal file
8
Assets/Scripts/NBC/Asset/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57b93d152d45c8e4db2b93e67f13f4b2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Scripts/NBC/Asset/Editor/Attributes.cs
Normal file
18
Assets/Scripts/NBC/Asset/Editor/Attributes.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义名称
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.All, Inherited = false)]
|
||||
public sealed class DisplayNameAttribute : Attribute
|
||||
{
|
||||
public DisplayNameAttribute(string name)
|
||||
{
|
||||
showName = name;
|
||||
}
|
||||
|
||||
public string showName;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Attributes.cs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Attributes.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9f1086eccfe46c4bfd85634641ac41b
|
||||
timeCreated: 1679490587
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Builder.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Builder.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be385019c3e843a9a751d1facb8c38a9
|
||||
timeCreated: 1673928172
|
||||
99
Assets/Scripts/NBC/Asset/Editor/Builder/BuildContext.cs
Normal file
99
Assets/Scripts/NBC/Asset/Editor/Builder/BuildContext.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public class BuildContext
|
||||
{
|
||||
public List<BuildAsset> Assets = new List<BuildAsset>();
|
||||
public List<BuildBundle> Bundles = new List<BuildBundle>();
|
||||
public List<string> Packages = new List<string>();
|
||||
|
||||
public void Add(GroupConfig groupConfig, List<BuildAsset> assets)
|
||||
{
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
asset.Group = groupConfig;
|
||||
AddOrUpdate(asset);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddOrUpdate(BuildAsset asset)
|
||||
{
|
||||
Assets.Add(asset);
|
||||
}
|
||||
|
||||
public void AddBundle(BuildBundle bundle)
|
||||
{
|
||||
Bundles.Add(bundle);
|
||||
}
|
||||
|
||||
public BuildBundle GetBundle(string name)
|
||||
{
|
||||
return Bundles.FirstOrDefault(bundle => bundle.Name == name);
|
||||
}
|
||||
|
||||
public List<BuildBundle> GenBundles()
|
||||
{
|
||||
Bundles.Clear();
|
||||
|
||||
Dictionary<string, BuildBundle> dictionary = new Dictionary<string, BuildBundle>();
|
||||
foreach (var asset in Assets)
|
||||
{
|
||||
if (!dictionary.TryGetValue(asset.Bundle, out var bundle))
|
||||
{
|
||||
bundle = new BuildBundle
|
||||
{
|
||||
Name = asset.Bundle,
|
||||
Tags = asset.Tags
|
||||
};
|
||||
dictionary[bundle.Name] = bundle;
|
||||
}
|
||||
|
||||
bundle.AddAsset(asset);
|
||||
}
|
||||
|
||||
foreach (var bundle in dictionary.Values)
|
||||
{
|
||||
AddBundle(bundle);
|
||||
}
|
||||
|
||||
return Bundles;
|
||||
}
|
||||
|
||||
public void SaveAssets()
|
||||
{
|
||||
var cache = Caches.Get();
|
||||
cache.ClearAssets();
|
||||
cache.AddOrUpdate(Assets);
|
||||
cache.Save();
|
||||
}
|
||||
|
||||
public void SaveBundles()
|
||||
{
|
||||
var cache = Caches.Get();
|
||||
cache.ClearBundles();
|
||||
cache.AddOrUpdate(Bundles);
|
||||
cache.Save();
|
||||
}
|
||||
|
||||
public List<AssetBundleBuild> GetAssetBundleBuilds()
|
||||
{
|
||||
List<AssetBundleBuild> builds = new List<AssetBundleBuild>();
|
||||
|
||||
for (int i = 0; i < Bundles.Count; i++)
|
||||
{
|
||||
var bundle = Bundles[i];
|
||||
var build = new AssetBundleBuild
|
||||
{
|
||||
assetNames = bundle.GetAssetNames(),
|
||||
assetBundleName = bundle.Name
|
||||
};
|
||||
builds.Add(build);
|
||||
}
|
||||
|
||||
return builds;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 334b2db512674787abcafd936a43c2b0
|
||||
timeCreated: 1678170411
|
||||
138
Assets/Scripts/NBC/Asset/Editor/Builder/Builder.cs
Normal file
138
Assets/Scripts/NBC/Asset/Editor/Builder/Builder.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public class Builder
|
||||
{
|
||||
private static readonly Dictionary<BundleMode, Type> _gatherTypes = new Dictionary<BundleMode, Type>();
|
||||
private static readonly Dictionary<int, Type> _buildTaskTypes = new Dictionary<int, Type>();
|
||||
|
||||
#region 内部方法
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
private static void OnInitialize()
|
||||
{
|
||||
FindGathers();
|
||||
FindTasks();
|
||||
}
|
||||
|
||||
private static void FindGathers()
|
||||
{
|
||||
var types = EditUtil.FindAllSubclass<GatherBase>();
|
||||
foreach (var t in types)
|
||||
{
|
||||
var attributes = t.GetCustomAttributes(typeof(BindAttribute), true);
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
if (attribute is BindAttribute bindAttribute && bindAttribute.BindObject is BundleMode mode)
|
||||
{
|
||||
_gatherTypes[mode] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void FindTasks()
|
||||
{
|
||||
var types = EditUtil.FindAllSubclass<BuildTask>();
|
||||
foreach (var t in types)
|
||||
{
|
||||
var attributes = t.GetCustomAttributes(typeof(IdAttribute), true);
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
if (attribute is IdAttribute idAttribute && idAttribute.Id > 0)
|
||||
{
|
||||
_buildTaskTypes[idAttribute.Id] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Type GetGatherType(BundleMode mode)
|
||||
{
|
||||
return _gatherTypes.TryGetValue(mode, out var t) ? t : null;
|
||||
}
|
||||
|
||||
private static Type GetTaskType(int id)
|
||||
{
|
||||
return _buildTaskTypes.TryGetValue(id, out var t) ? t : null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
internal static BuildAsset[] GatherAsset(PackageConfig packageConfig, GroupConfig groupConfig)
|
||||
{
|
||||
var type = GetGatherType(groupConfig.BundleMode);
|
||||
if (type != null)
|
||||
{
|
||||
if (Activator.CreateInstance(type) is GatherBase instance)
|
||||
{
|
||||
return instance.Run(packageConfig, groupConfig);
|
||||
}
|
||||
}
|
||||
|
||||
return Array.Empty<BuildAsset>();
|
||||
}
|
||||
|
||||
public static void Gather()
|
||||
{
|
||||
RunBuildTasks(TaskId.Gather);
|
||||
}
|
||||
|
||||
|
||||
public static void Build()
|
||||
{
|
||||
RunBuildTasks(
|
||||
TaskId.Gather,
|
||||
TaskId.BuildBundle,
|
||||
TaskId.GenPackageData,
|
||||
TaskId.GenVersionData,
|
||||
TaskId.CopyVersionBundle,
|
||||
TaskId.CopyToStreamingAssets
|
||||
);
|
||||
|
||||
// TaskId.GenVersionData,
|
||||
// TaskId.CopyVersionBundle,
|
||||
// TaskId.CopyToStreamingAssets
|
||||
}
|
||||
|
||||
public static void RunBuildTasks(params int[] ids)
|
||||
{
|
||||
if (ids.Length < 1)
|
||||
{
|
||||
throw new Exception("not set task id!");
|
||||
}
|
||||
|
||||
List<Type> types = ids.Select(GetTaskType).Where(type => type != null).ToList();
|
||||
if (types.Count < 1)
|
||||
{
|
||||
throw new Exception("task id error!");
|
||||
}
|
||||
|
||||
List<BuildTask> buildTasks = new List<BuildTask>();
|
||||
foreach (var type in types)
|
||||
{
|
||||
if (Activator.CreateInstance(type) is BuildTask task)
|
||||
{
|
||||
buildTasks.Add(task);
|
||||
}
|
||||
}
|
||||
|
||||
BuildContext buildContext = new BuildContext();
|
||||
foreach (var task in buildTasks)
|
||||
{
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
task.Run(buildContext);
|
||||
sw.Stop();
|
||||
Debug.Log($"Run {task.GetType().Name} time={sw.ElapsedMilliseconds / 1000f}s");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Builder/Builder.cs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Builder/Builder.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8faa489ad1174a76933f9bc929874b8d
|
||||
timeCreated: 1673928193
|
||||
8
Assets/Scripts/NBC/Asset/Editor/Builder/Gathers.meta
Normal file
8
Assets/Scripts/NBC/Asset/Editor/Builder/Gathers.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5c130f0a9594227a41f366c4fb51c84
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
161
Assets/Scripts/NBC/Asset/Editor/Builder/Gathers/GatherBase.cs
Normal file
161
Assets/Scripts/NBC/Asset/Editor/Builder/Gathers/GatherBase.cs
Normal file
@@ -0,0 +1,161 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public abstract class GatherBase
|
||||
{
|
||||
protected PackageConfig PackageConfig;
|
||||
protected GroupConfig GroupConfig;
|
||||
|
||||
public BuildAsset[] Run(PackageConfig packageConfig, GroupConfig groupConfig)
|
||||
{
|
||||
PackageConfig = packageConfig;
|
||||
GroupConfig = groupConfig;
|
||||
return Execute();
|
||||
}
|
||||
|
||||
protected abstract BuildAsset[] Execute();
|
||||
|
||||
protected string GetBundleName(BuildAsset asset, string bundleName = "")
|
||||
{
|
||||
if (string.IsNullOrEmpty(bundleName))
|
||||
{
|
||||
bundleName = asset.Path;
|
||||
}
|
||||
|
||||
var settings = BuildSettings.Instance;
|
||||
bundleName = bundleName.Replace("\\", "/").Replace("/", "_").Replace(".", "_").ToLower();
|
||||
if (settings.ShaderBuildTogether && settings.ShaderExtensions.Exists(asset.Path.EndsWith))
|
||||
{
|
||||
bundleName = "shaders";
|
||||
}
|
||||
|
||||
return $"{PackageConfig.Name.ToLower()}/{bundleName}{BuildSettings.Instance.BundlesExtension}";
|
||||
}
|
||||
|
||||
#region GetAssets
|
||||
|
||||
protected List<BuildAsset> GetAssets()
|
||||
{
|
||||
List<BuildAsset> assets = new List<BuildAsset>();
|
||||
|
||||
var list = GroupConfig.Collectors;
|
||||
foreach (var obj in list)
|
||||
{
|
||||
var arr = GetAssets(obj, GroupConfig.Filter);
|
||||
if (arr != null && arr.Count > 0)
|
||||
{
|
||||
assets.AddRange(arr);
|
||||
}
|
||||
}
|
||||
|
||||
return assets;
|
||||
}
|
||||
|
||||
protected List<BuildAsset> GetAssets(Object obj, string filter = "")
|
||||
{
|
||||
List<BuildAsset> retList = new List<BuildAsset>();
|
||||
var path = AssetDatabase.GetAssetPath(obj);
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
var assetGuids = AssetDatabase.FindAssets(filter, new[]
|
||||
{
|
||||
path
|
||||
});
|
||||
foreach (var guid in assetGuids)
|
||||
{
|
||||
var childPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
|
||||
if (string.IsNullOrEmpty(childPath) || Directory.Exists(childPath)) continue;
|
||||
retList.Add(PathToBuildAsset(childPath, obj));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//如果是对象则不做过滤。直接加入列表
|
||||
retList.Add(ObjectToBuildAsset(obj));
|
||||
}
|
||||
|
||||
return retList;
|
||||
}
|
||||
|
||||
|
||||
protected BuildAsset ObjectToBuildAsset(Object collector)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(collector);
|
||||
return PathToBuildAsset(path, collector);
|
||||
}
|
||||
|
||||
protected BuildAsset PathToBuildAsset(string path, Object collector)
|
||||
{
|
||||
var type = AssetDatabase.GetMainAssetTypeAtPath(path);
|
||||
var ret = new BuildAsset
|
||||
{
|
||||
Path = path,
|
||||
Address = ToAddressPath(path, collector),
|
||||
Type = type == null ? "Missing" : type.Name,
|
||||
Tags = GroupConfig.Tags,
|
||||
Group = GroupConfig,
|
||||
// Dependencies = GetDependencies(path)
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected string[] GetDependencies(string path)
|
||||
{
|
||||
var ret = new HashSet<string>();
|
||||
ret.UnionWith(AssetDatabase.GetDependencies(path));
|
||||
ret.RemoveWhere(s => s.EndsWith(".unity"));
|
||||
ret.Remove(path);
|
||||
return ret.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换文件地址为可寻址地址
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <param name="collector"></param>
|
||||
/// <returns></returns>
|
||||
protected string ToAddressPath(string filePath, Object collector)
|
||||
{
|
||||
var mode = GroupConfig.AddressMode;
|
||||
var collectorName = collector != null ? collector.name : string.Empty;
|
||||
var path = AssetDatabase.GetAssetPath(collector);
|
||||
if (path == filePath)
|
||||
{
|
||||
collectorName = string.Empty;
|
||||
}
|
||||
|
||||
var fileName = Path.GetFileNameWithoutExtension(filePath);
|
||||
var groupName = GroupConfig.Name;
|
||||
var packageName = PackageConfig.Name;
|
||||
switch (mode)
|
||||
{
|
||||
case AddressMode.None:
|
||||
return filePath;
|
||||
case AddressMode.FileName:
|
||||
return fileName;
|
||||
case AddressMode.GroupAndFileName:
|
||||
return $"{groupName}/{fileName}";
|
||||
case AddressMode.PackAndGroupAndFileName:
|
||||
return $"{packageName}/{groupName}/{fileName}";
|
||||
case AddressMode.PackAndFileName:
|
||||
return $"{packageName}/{fileName}";
|
||||
case AddressMode.CollectorAndFileName:
|
||||
return string.IsNullOrEmpty(collectorName) ? fileName : $"{collectorName}/{fileName}";
|
||||
case AddressMode.PackAndCollectorAndFileName:
|
||||
return string.IsNullOrEmpty(collectorName)
|
||||
? $"{packageName}/{fileName}"
|
||||
: $"{packageName}/{collectorName}/{fileName}";
|
||||
}
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a9d7262122d4b439f86e48c9a47ea49
|
||||
timeCreated: 1673942495
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Bind(BundleMode.File)]
|
||||
public class GatherFile : GatherBase
|
||||
{
|
||||
protected override BuildAsset[] Execute()
|
||||
{
|
||||
List<BuildAsset> assets = GetAssets();
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
asset.Bundle = GetBundleName(asset);
|
||||
}
|
||||
|
||||
return assets.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c9c33f337ab4656a3dc89e495cbd873
|
||||
timeCreated: 1673943049
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Bind(BundleMode.Folder)]
|
||||
public class GatherFolder : GatherBase
|
||||
{
|
||||
protected override BuildAsset[] Execute()
|
||||
{
|
||||
List<BuildAsset> assets = GetAssets();
|
||||
var singleAssetPaths = GetSingleAssetPaths();
|
||||
Dictionary<string, List<BuildAsset>> dictionary = new Dictionary<string, List<BuildAsset>>();
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
var dirPath = Path.GetDirectoryName(asset.Path);
|
||||
if (singleAssetPaths.Contains(asset.Path)) dirPath = asset.Path;
|
||||
|
||||
if (string.IsNullOrEmpty(dirPath)) continue;
|
||||
if (!dictionary.TryGetValue(dirPath, out var list))
|
||||
{
|
||||
list = new List<BuildAsset>();
|
||||
dictionary[dirPath] = list;
|
||||
}
|
||||
|
||||
if (!list.Contains(asset)) list.Add(asset);
|
||||
}
|
||||
|
||||
List<BuildAsset> ret = new List<BuildAsset>();
|
||||
|
||||
foreach (var key in dictionary.Keys)
|
||||
{
|
||||
var value = dictionary[key];
|
||||
foreach (var asset in value)
|
||||
{
|
||||
asset.Bundle = GetBundleName(asset, key);
|
||||
ret.Add(asset);
|
||||
}
|
||||
}
|
||||
|
||||
return ret.ToArray();
|
||||
}
|
||||
|
||||
private List<string> GetSingleAssetPaths()
|
||||
{
|
||||
List<string> list = new List<string>();
|
||||
foreach (var obj in GroupConfig.Collectors)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(obj);
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
list.Add(path);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7364f38a2920403597a8453c74af4a97
|
||||
timeCreated: 1673942970
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Bind(BundleMode.FolderParent)]
|
||||
public class GatherFolderParent : GatherBase
|
||||
{
|
||||
protected override BuildAsset[] Execute()
|
||||
{
|
||||
List<BuildAsset> ret = new List<BuildAsset>();
|
||||
var list = GroupConfig.Collectors;
|
||||
foreach (var obj in list)
|
||||
{
|
||||
var assets = GetAssets(obj, GroupConfig.Filter);
|
||||
if (assets != null && assets.Count > 0)
|
||||
{
|
||||
var bundleName = AssetDatabase.GetAssetPath(obj);
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
asset.Bundle = GetBundleName(asset, bundleName);
|
||||
ret.Add(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d621c6e03b294f3e845112fdd120fd89
|
||||
timeCreated: 1673943009
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Bind(BundleMode.Single)]
|
||||
public class GatherSingle : GatherBase
|
||||
{
|
||||
protected override BuildAsset[] Execute()
|
||||
{
|
||||
List<BuildAsset> assets = GetAssets();
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
asset.Bundle = GetBundleName(asset, GroupConfig.Name);
|
||||
}
|
||||
|
||||
return assets.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74736578b5504c3e849ee5d1e0b7ced3
|
||||
timeCreated: 1673942520
|
||||
@@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Bind(BundleMode.WithoutSub)]
|
||||
public class GatherWithoutSub : GatherBase
|
||||
{
|
||||
protected override BuildAsset[] Execute()
|
||||
{
|
||||
List<BuildAsset> ret = new List<BuildAsset>();
|
||||
var list = GroupConfig.Collectors;
|
||||
foreach (var obj in list)
|
||||
{
|
||||
var assets = GetAssets(obj, GroupConfig.Filter);
|
||||
if (assets != null && assets.Count > 0)
|
||||
{
|
||||
assets = WithoutSub(obj, assets);
|
||||
var bundleName = AssetDatabase.GetAssetPath(obj);
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
asset.Bundle = GetBundleName(asset, bundleName);
|
||||
ret.Add(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret.ToArray();
|
||||
}
|
||||
|
||||
private List<BuildAsset> WithoutSub(Object obj, List<BuildAsset> assets)
|
||||
{
|
||||
List<BuildAsset> ret = new List<BuildAsset>();
|
||||
var path = AssetDatabase.GetAssetPath(obj);
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
var childPath = asset.Path;
|
||||
var dirName = Path.GetDirectoryName(childPath)?.Replace("\\", "/");
|
||||
if (dirName == path)
|
||||
{
|
||||
ret.Add(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.AddRange(assets);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a28e18aaf4d45b3903505257ab9542c
|
||||
timeCreated: 1675606827
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Builder/Tasks.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Builder/Tasks.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b102828c7294fe89e65179188906813
|
||||
timeCreated: 1675823185
|
||||
@@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Id(TaskId.BuildBundle)]
|
||||
public class BuildBundleTask : BuildTask
|
||||
{
|
||||
private BuildContext _context;
|
||||
|
||||
public override void Run(BuildContext context)
|
||||
{
|
||||
_context = context;
|
||||
var bundleDataList = _context.GenBundles();
|
||||
List<AssetBundleBuild> builds = _context.GetAssetBundleBuilds();
|
||||
EditUtil.CreateDirectory(BuildSettings.PlatformCachePath);
|
||||
var manifest = BuildAssetBundles(BuildSettings.PlatformCachePath, builds.ToArray(),
|
||||
BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);
|
||||
if (manifest != null)
|
||||
{
|
||||
var bundles = manifest.GetAllAssetBundles();
|
||||
foreach (var bundleName in bundles)
|
||||
{
|
||||
var bundle = _context.GetBundle(bundleName);
|
||||
if (bundle != null)
|
||||
{
|
||||
var path = BuildSettings.GetCachePath(bundleName);
|
||||
var hash = Util.ComputeHash(path);
|
||||
bundle.Dependencies = manifest.GetAllDependencies(bundleName);
|
||||
bundle.Hash = hash;
|
||||
bundle.Size = Util.GetFileSize(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Histories.AddHistory(bundleDataList);
|
||||
_context.SaveBundles();
|
||||
}
|
||||
|
||||
private static AssetBundleManifest BuildAssetBundles(string outputPath, AssetBundleBuild[] builds,
|
||||
BuildAssetBundleOptions options, BuildTarget target)
|
||||
{
|
||||
var manifest = BuildPipeline.BuildAssetBundles(outputPath, builds, options, target);
|
||||
|
||||
return manifest;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ed116b0b33144cb94cb189f4234f0ca
|
||||
timeCreated: 1675823335
|
||||
11
Assets/Scripts/NBC/Asset/Editor/Builder/Tasks/BuildTask.cs
Normal file
11
Assets/Scripts/NBC/Asset/Editor/Builder/Tasks/BuildTask.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public abstract class BuildTask
|
||||
{
|
||||
public abstract void Run(BuildContext context);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a28b318de2d45ef886f30fc4d1ffac9
|
||||
timeCreated: 1675822432
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.EditorTools;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Id(TaskId.CopyToStreamingAssets)]
|
||||
public class CopyToStreamingAssets : BuildTask
|
||||
{
|
||||
public override void Run(BuildContext context)
|
||||
{
|
||||
var last = HistoryUtil.GetLastVersionHistory();
|
||||
if (last != null)
|
||||
{
|
||||
last.CopyToStreamingAssets();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("copy version is null,version history is null");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2af47d5da6e844ce97d51af3a3ded489
|
||||
timeCreated: 1675845425
|
||||
@@ -0,0 +1,76 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 将生成的版本保存为可用的历史记录
|
||||
/// </summary>
|
||||
[Id(TaskId.CopyVersionBundle)]
|
||||
public class CopyVersionBundleTask : BuildTask
|
||||
{
|
||||
private Dictionary<string, string> _copyPaths = new Dictionary<string, string>();
|
||||
|
||||
public override void Run(BuildContext context)
|
||||
{
|
||||
TryCopy();
|
||||
}
|
||||
|
||||
private void TryCopy()
|
||||
{
|
||||
var versionPath = BuildSettings.GetCachePath(Const.VersionFileName);
|
||||
var versionData = Util.ReadJson<VersionData>(versionPath);
|
||||
|
||||
if (IsChange(versionData))
|
||||
{
|
||||
var versionPackagePath = BuildSettings.GetCachePath("packages.json");
|
||||
var lastHistoryData = Histories.LastHistoryData;
|
||||
_copyPaths.Add(versionPath, BuildSettings.GetBuildPath($"version_{lastHistoryData.Index}.json"));
|
||||
_copyPaths.Add(versionPackagePath, BuildSettings.GetBuildPath(versionData.NameHash));
|
||||
var versionPackageData = Util.ReadJson<VersionPackageData>(versionPackagePath);
|
||||
foreach (var package in versionPackageData.Packages)
|
||||
{
|
||||
foreach (var bundle in package.Bundles)
|
||||
{
|
||||
var bundleNameAddHash = Util.NameAddHash(bundle.Name, bundle.Hash);
|
||||
_copyPaths.Add(BuildSettings.GetCachePath(bundle.Name),
|
||||
BuildSettings.GetBuildPath(bundleNameAddHash));
|
||||
}
|
||||
}
|
||||
|
||||
CopyAll();
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyAll()
|
||||
{
|
||||
foreach (var path in _copyPaths.Keys)
|
||||
{
|
||||
var toPath = _copyPaths[path];
|
||||
if (File.Exists(path))
|
||||
{
|
||||
EditUtil.CreateDirectory(Path.GetDirectoryName(toPath));
|
||||
if (File.Exists(toPath)) File.Delete(toPath);
|
||||
File.Copy(path, toPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsChange(VersionData versionData)
|
||||
{
|
||||
var lastVersionData = Histories.GetLastVersion();
|
||||
if (lastVersionData != null)
|
||||
{
|
||||
if (versionData.Size != lastVersionData.Size || versionData.Hash != lastVersionData.Hash)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f706081edbe481ea7e727651d531e0a
|
||||
timeCreated: 1675823749
|
||||
66
Assets/Scripts/NBC/Asset/Editor/Builder/Tasks/GatherTask.cs
Normal file
66
Assets/Scripts/NBC/Asset/Editor/Builder/Tasks/GatherTask.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Id(TaskId.Gather)]
|
||||
public class GatherTask : BuildTask
|
||||
{
|
||||
private BuildContext _context;
|
||||
|
||||
public override void Run(BuildContext context)
|
||||
{
|
||||
_context = context;
|
||||
GatherAllAssets();
|
||||
_context.SaveAssets();
|
||||
}
|
||||
|
||||
public void GatherAllAssets()
|
||||
{
|
||||
var packages = CollectorSetting.Instance.Packages;
|
||||
|
||||
foreach (var package in packages)
|
||||
{
|
||||
if (!package.Enable) continue;
|
||||
foreach (var group in package.Groups)
|
||||
{
|
||||
if (group.FilterEnum != FilterEnum.Custom)
|
||||
{
|
||||
group.Filter = group.FilterEnum == FilterEnum.All ? "*" : $"t:{group.FilterEnum}";
|
||||
}
|
||||
else if (string.IsNullOrEmpty(group.Filter))
|
||||
{
|
||||
group.Filter = "*";
|
||||
}
|
||||
|
||||
if (!group.Enable) continue;
|
||||
var assets = GatherGroupAssets(package, group);
|
||||
_context.Add(group, assets.ToList());
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var package in packages)
|
||||
{
|
||||
foreach (var group in package.Groups)
|
||||
{
|
||||
var tag = group.Tags;
|
||||
if (string.IsNullOrEmpty(tag)) continue;
|
||||
var arr = tag.Split(",");
|
||||
foreach (var s in arr)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(s))
|
||||
{
|
||||
Defs.AddTag(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BuildAsset[] GatherGroupAssets(PackageConfig packageConfig, GroupConfig groupConfig)
|
||||
{
|
||||
if (groupConfig.Collectors == null || groupConfig.Collectors.Count == 0) return Array.Empty<BuildAsset>();
|
||||
return Builder.GatherAsset(packageConfig, groupConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79738d555c83467c954f240b9f3b0d00
|
||||
timeCreated: 1675823940
|
||||
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 生成打包的清单文件
|
||||
/// </summary>
|
||||
[Id(TaskId.GenPackageData)]
|
||||
public class GenPackageDataTask : BuildTask
|
||||
{
|
||||
private BuildContext _context;
|
||||
|
||||
public override void Run(BuildContext context)
|
||||
{
|
||||
_context = context;
|
||||
BuildPackagesData();
|
||||
}
|
||||
|
||||
private void BuildPackagesData()
|
||||
{
|
||||
Dictionary<string, BuildPackage> dictionary = new Dictionary<string, BuildPackage>();
|
||||
foreach (var bundle in _context.Bundles)
|
||||
{
|
||||
var package = Path.GetDirectoryName(bundle.Name);
|
||||
if (string.IsNullOrEmpty(package)) continue;
|
||||
if (!dictionary.TryGetValue(package, out var buildPackage))
|
||||
{
|
||||
buildPackage = new BuildPackage
|
||||
{
|
||||
Name = package,
|
||||
};
|
||||
dictionary[package] = buildPackage;
|
||||
}
|
||||
|
||||
buildPackage.Bundles.Add(bundle);
|
||||
}
|
||||
|
||||
var packages = CollectorSetting.Instance.Packages;
|
||||
foreach (var key in dictionary.Keys)
|
||||
{
|
||||
var p = packages.Find(p => p.Name == key);
|
||||
var package = dictionary[key];
|
||||
package.Size = package.Bundles.Sum(b => b.Size);
|
||||
package.Def = p.Default ? 1 : 0;
|
||||
var savePath = BuildSettings.GetCachePath($"{key}.json");
|
||||
Util.WriteJson(package, savePath);
|
||||
}
|
||||
|
||||
// var packages = CollectorSetting.Instance.Packages;
|
||||
// foreach (var key in dictionary.Keys)
|
||||
// {
|
||||
// var value = dictionary[key];
|
||||
// var packageData = value.ToPackagesData();
|
||||
// var savePath = BuildSettings.GetCachePath($"{key}.json");
|
||||
// Util.WriteJson(packageData, savePath);
|
||||
// }
|
||||
//
|
||||
// foreach (var key in dictionary.Keys)
|
||||
// {
|
||||
// var p = packages.Find(p => p.Name == key);
|
||||
// var packPath = BuildSettings.GetCachePath($"{key}.json");
|
||||
// VersionPackagesData versionPackagesData = new VersionPackagesData
|
||||
// {
|
||||
// Ver = DateTimeOffset.Now.ToUnixTimeSeconds().ToString(),
|
||||
// Def = p.Default ? 1 : 0,
|
||||
// Name = key,
|
||||
// Hash = Util.ComputeHash(packPath),
|
||||
// Size = Util.GetFileSize(packPath)
|
||||
// };
|
||||
// versionData.Packages.Add(versionPackagesData);
|
||||
// }
|
||||
//
|
||||
// var versionSavePath = BuildSettings.GetCachePath("version.json");
|
||||
// versionData.AppVer = UnityEditor.PlayerSettings.bundleVersion;
|
||||
// versionData.BuildTime = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||
// Util.WriteJson(versionData, versionSavePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9dca3963bf3d46f8a3734326ef1cfd1a
|
||||
timeCreated: 1680321963
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Id(TaskId.GenVersionData)]
|
||||
public class GenVersionDataTask : BuildTask
|
||||
{
|
||||
private BuildContext _context;
|
||||
|
||||
public override void Run(BuildContext context)
|
||||
{
|
||||
_context = context;
|
||||
BuildVersionData();
|
||||
}
|
||||
|
||||
|
||||
private void BuildVersionData()
|
||||
{
|
||||
VersionData versionData = new VersionData();
|
||||
var versionPackageData = new VersionPackageData();
|
||||
var packages = CollectorSetting.Instance.Packages;
|
||||
// Dictionary<string, PackageTempData> dictionary = new Dictionary<string, PackageTempData>();
|
||||
foreach (var package in packages)
|
||||
{
|
||||
var packPath = BuildSettings.GetCachePath($"{package.Name}.json");
|
||||
var buildPackage = Util.ReadJson<BuildPackage>(packPath);
|
||||
if (buildPackage != null)
|
||||
{
|
||||
var packageData = buildPackage.ToPackagesData();
|
||||
versionPackageData.Packages.Add(packageData);
|
||||
}
|
||||
}
|
||||
|
||||
var versionPackagesPath = BuildSettings.GetCachePath("packages.json");
|
||||
Util.WriteJson(versionPackageData, versionPackagesPath);
|
||||
|
||||
versionData.Hash = Util.ComputeHash(versionPackagesPath);
|
||||
versionData.Size = Util.GetFileSize(versionPackagesPath);
|
||||
var versionSavePath = BuildSettings.GetCachePath(Const.VersionFileName);
|
||||
versionData.AppVer = UnityEditor.PlayerSettings.bundleVersion;
|
||||
versionData.BuildTime = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||
Util.WriteJson(versionData, versionSavePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b4670cdc7f941558a69023329f42de2
|
||||
timeCreated: 1675837362
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Cache.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Cache.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: edb0a42389064bd69c59e545cf66efa9
|
||||
timeCreated: 1673936018
|
||||
64
Assets/Scripts/NBC/Asset/Editor/Cache/BuildAsset.cs
Normal file
64
Assets/Scripts/NBC/Asset/Editor/Cache/BuildAsset.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class BuildAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源路径
|
||||
/// </summary>
|
||||
public string Path;
|
||||
|
||||
/// <summary>
|
||||
/// 可寻址地址
|
||||
/// </summary>
|
||||
public string Address;
|
||||
|
||||
/// <summary>
|
||||
/// 资源类型
|
||||
/// </summary>
|
||||
public string Type;
|
||||
|
||||
/// <summary>
|
||||
/// 资源所属的bundle包
|
||||
/// </summary>
|
||||
public string Bundle;
|
||||
|
||||
/// <summary>
|
||||
/// 资源标签
|
||||
/// </summary>
|
||||
public string Tags;
|
||||
|
||||
// /// <summary>
|
||||
// /// 资源依赖
|
||||
// /// </summary>
|
||||
// public string[] Dependencies = Array.Empty<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 资源所属组
|
||||
/// </summary>
|
||||
[HideInInspector] public GroupConfig Group;
|
||||
|
||||
private long _size;
|
||||
|
||||
public long Size
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_size == 0)
|
||||
{
|
||||
if (File.Exists(Path))
|
||||
{
|
||||
FileInfo info = new FileInfo(Path);
|
||||
_size = info.Length;
|
||||
}
|
||||
}
|
||||
|
||||
return _size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Cache/BuildAsset.cs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Cache/BuildAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee63ea9c2adb468981d4e5c12832fe8d
|
||||
timeCreated: 1673939334
|
||||
46
Assets/Scripts/NBC/Asset/Editor/Cache/BuildBundle.cs
Normal file
46
Assets/Scripts/NBC/Asset/Editor/Cache/BuildBundle.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class BuildBundle
|
||||
{
|
||||
public string Name;
|
||||
public string Hash;
|
||||
public int Size;
|
||||
public List<BuildAsset> Assets = new List<BuildAsset>();
|
||||
public string[] Dependencies;
|
||||
|
||||
/// <summary>
|
||||
/// 资源包标签
|
||||
/// </summary>
|
||||
public string Tags;
|
||||
|
||||
public void AddAsset(ICollection<BuildAsset> assets)
|
||||
{
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
AddAsset(asset);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddAsset(BuildAsset asset)
|
||||
{
|
||||
asset.Bundle = Name;
|
||||
Assets.Add(asset);
|
||||
}
|
||||
|
||||
public string[] GetAssetNames()
|
||||
{
|
||||
HashSet<string> assetNames = new HashSet<string>();
|
||||
foreach (var asset in Assets)
|
||||
{
|
||||
assetNames.Add(asset.Path);
|
||||
}
|
||||
|
||||
return assetNames.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0cb3d650a76f48d5bfddfbe05a6d6ab7
|
||||
timeCreated: 1675311242
|
||||
99
Assets/Scripts/NBC/Asset/Editor/Cache/BuildPackage.cs
Normal file
99
Assets/Scripts/NBC/Asset/Editor/Cache/BuildPackage.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class BuildPackage
|
||||
{
|
||||
public string Name;
|
||||
public int Size;
|
||||
public int Def;
|
||||
public List<BuildBundle> Bundles = new List<BuildBundle>();
|
||||
|
||||
[NonSerialized] public List<BuildAsset> Assets = new List<BuildAsset>();
|
||||
|
||||
public int GetBundleIndex(string name)
|
||||
{
|
||||
return Bundles.FindIndex(p => p.Name == name);
|
||||
}
|
||||
|
||||
public int GetAssetIndex(string asset)
|
||||
{
|
||||
return Assets.FindIndex(p => p.Path == asset);
|
||||
}
|
||||
|
||||
public PackageData ToPackagesData()
|
||||
{
|
||||
PackageData packageData = new PackageData
|
||||
{
|
||||
Name = Name,
|
||||
Def = Def,
|
||||
Bundles = new List<BundleData>(),
|
||||
Assets = new List<AssetData>()
|
||||
};
|
||||
|
||||
foreach (var bundle in Bundles)
|
||||
{
|
||||
var b = new BundleData
|
||||
{
|
||||
Name = bundle.Name,
|
||||
Hash = bundle.Hash,
|
||||
Size = bundle.Size,
|
||||
Tags = EditUtil.GetTagsArr(bundle.Tags),
|
||||
};
|
||||
if (bundle.Dependencies != null && bundle.Dependencies.Length > 0)
|
||||
{
|
||||
foreach (var dependency in bundle.Dependencies)
|
||||
{
|
||||
b.Deps.Add(GetBundleIndex(dependency));
|
||||
}
|
||||
}
|
||||
|
||||
Assets.AddRange(bundle.Assets);
|
||||
packageData.Bundles.Add(b);
|
||||
}
|
||||
|
||||
HashSet<string> dirs = new HashSet<string>();
|
||||
foreach (var asset in Assets)
|
||||
{
|
||||
var dir = Path.GetDirectoryName(asset.Path)?.Replace("\\", "/");
|
||||
if (!string.IsNullOrEmpty(dir))
|
||||
{
|
||||
dirs.Add(dir);
|
||||
}
|
||||
}
|
||||
|
||||
packageData.Dirs = dirs.ToList();
|
||||
|
||||
foreach (var asset in Assets)
|
||||
{
|
||||
var dir = Path.GetDirectoryName(asset.Path)?.Replace("\\", "/");
|
||||
var a = new AssetData
|
||||
{
|
||||
Name = Path.GetFileName(asset.Path),
|
||||
Dir = packageData.Dirs.FindIndex(b => b == dir),
|
||||
Address = asset.Address,
|
||||
// Tags = EditUtil.GetTagsArr(asset.Tags),
|
||||
Bundle = GetBundleIndex(asset.Bundle)
|
||||
};
|
||||
// if (asset.Dependencies != null && asset.Dependencies.Length > 0)
|
||||
// {
|
||||
// foreach (var dependency in asset.Dependencies)
|
||||
// {
|
||||
// var index = GetAssetIndex(dependency);
|
||||
// if (index >= 0)
|
||||
// a.Deps.Add(index);
|
||||
// }
|
||||
// }
|
||||
|
||||
packageData.Assets.Add(a);
|
||||
}
|
||||
|
||||
|
||||
return packageData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6581ebcb347b4d4dbe2de0886dd23562
|
||||
timeCreated: 1680321488
|
||||
61
Assets/Scripts/NBC/Asset/Editor/Cache/Caches.cs
Normal file
61
Assets/Scripts/NBC/Asset/Editor/Cache/Caches.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[FilePath("Assets/AssetCaches.asset")]
|
||||
public class Caches : ScriptableSingleton<Caches>
|
||||
{
|
||||
public List<BuildAsset> Assets = new List<BuildAsset>();
|
||||
public List<BuildBundle> Bundles = new List<BuildBundle>();
|
||||
|
||||
public void ClearBundles()
|
||||
{
|
||||
Bundles.Clear();
|
||||
Save();
|
||||
}
|
||||
public void ClearAssets()
|
||||
{
|
||||
Assets.Clear();
|
||||
Save();
|
||||
}
|
||||
|
||||
public void AddOrUpdate(ICollection<BuildAsset> assets)
|
||||
{
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
AddOrUpdate(asset);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddOrUpdate(BuildAsset asset)
|
||||
{
|
||||
Assets.Add(asset);
|
||||
}
|
||||
|
||||
public void AddOrUpdate(ICollection<BuildBundle> bundles)
|
||||
{
|
||||
foreach (var bundle in bundles)
|
||||
{
|
||||
AddBundle(bundle);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddBundle(BuildBundle bundle)
|
||||
{
|
||||
Bundles.Add(bundle);
|
||||
}
|
||||
|
||||
public BuildBundle GetBundle(string name)
|
||||
{
|
||||
return Bundles.FirstOrDefault(bundle => bundle.Name == name);
|
||||
}
|
||||
|
||||
|
||||
public void Save()
|
||||
{
|
||||
EditorUtility.SetDirty(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Cache/Caches.cs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Cache/Caches.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9fa072029bab4df48fef4d84ac836775
|
||||
timeCreated: 1677727983
|
||||
180
Assets/Scripts/NBC/Asset/Editor/Cache/Histories.cs
Normal file
180
Assets/Scripts/NBC/Asset/Editor/Cache/Histories.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class HistoryData
|
||||
{
|
||||
public int Index;
|
||||
public List<BuildBundle> Bundles = new List<BuildBundle>();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class HistoriesData
|
||||
{
|
||||
private int _historyCount = 5;
|
||||
public List<HistoryData> Histories = new List<HistoryData>();
|
||||
|
||||
public HistoryData LastHistoryData => Histories.Last();
|
||||
|
||||
public int LastIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
var index = 0;
|
||||
if (Histories.Count > 0)
|
||||
{
|
||||
index = Histories[^1].Index;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
public bool AddHistory(List<BuildBundle> bundles)
|
||||
{
|
||||
var data = new HistoryData();
|
||||
|
||||
foreach (var bundle in bundles)
|
||||
{
|
||||
var b = new BuildBundle
|
||||
{
|
||||
Name = bundle.Name,
|
||||
Hash = bundle.Hash,
|
||||
Size = bundle.Size
|
||||
};
|
||||
data.Bundles.Add(b);
|
||||
}
|
||||
|
||||
if (CanAdd(data))
|
||||
{
|
||||
data.Index = LastIndex + 1;
|
||||
Histories.Add(data);
|
||||
}
|
||||
|
||||
if (Histories.Count > _historyCount)
|
||||
{
|
||||
var count = Histories.Count - _historyCount;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Histories.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CanAdd(HistoryData data)
|
||||
{
|
||||
var changes = new List<BuildBundle>();
|
||||
|
||||
if (Histories.Count > 0 && Histories.Last() != null)
|
||||
{
|
||||
var last = Histories.Last();
|
||||
foreach (var bundle in data.Bundles)
|
||||
{
|
||||
var old = last.Bundles.Find(t => t.Name == bundle.Name);
|
||||
if (old != null)
|
||||
{
|
||||
if (old.Size != bundle.Size || old.Hash != bundle.Hash)
|
||||
{
|
||||
changes.Add(bundle);
|
||||
}
|
||||
}
|
||||
else changes.Add(bundle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
changes.AddRange(data.Bundles);
|
||||
}
|
||||
|
||||
return changes.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Histories
|
||||
{
|
||||
private static readonly string FilePath = BuildSettings.GetCachePath("BuildHistories.json");
|
||||
|
||||
private static HistoriesData _data;
|
||||
|
||||
public static HistoryData LastHistoryData => _data != null ? _data.LastHistoryData : null;
|
||||
|
||||
public static void AddHistory(List<BuildBundle> bundles)
|
||||
{
|
||||
if (_data == null)
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
|
||||
if (_data != null && _data.AddHistory(bundles))
|
||||
{
|
||||
Save();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("添加历史记录失败!");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Reload()
|
||||
{
|
||||
_data = Util.ReadJson<HistoriesData>(FilePath) ?? new HistoriesData();
|
||||
}
|
||||
|
||||
public static void Save()
|
||||
{
|
||||
if (_data != null)
|
||||
{
|
||||
Util.WriteJson(_data, FilePath);
|
||||
}
|
||||
}
|
||||
|
||||
public static VersionData GetLastVersion()
|
||||
{
|
||||
if (!Directory.Exists(BuildSettings.PlatformPath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var files = Directory.GetFiles(BuildSettings.PlatformPath);
|
||||
List<string> paths = new List<string>();
|
||||
foreach (var file in files)
|
||||
{
|
||||
var name = Path.GetFileName(file);
|
||||
if (name.StartsWith("version")) paths.Add(file);
|
||||
}
|
||||
|
||||
var lastFilePath = string.Empty;
|
||||
if (paths.Count > 0)
|
||||
{
|
||||
long lastCreationTime = 0;
|
||||
foreach (var path in paths)
|
||||
{
|
||||
var file = new FileInfo(path);
|
||||
if (file.Exists)
|
||||
{
|
||||
var t = file.CreationTime.ToFileTime();
|
||||
if (t > lastCreationTime)
|
||||
{
|
||||
lastCreationTime = t;
|
||||
lastFilePath = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(lastFilePath))
|
||||
{
|
||||
return Util.ReadJson<VersionData>(lastFilePath);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Cache/Histories.cs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Cache/Histories.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed799f6364ab4e8c9a4179410f5756e7
|
||||
timeCreated: 1675909929
|
||||
137
Assets/Scripts/NBC/Asset/Editor/Cache/VersionHistory.cs
Normal file
137
Assets/Scripts/NBC/Asset/Editor/Cache/VersionHistory.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class VersionHistoryData
|
||||
{
|
||||
public string ShowName; // => $"version_{Index}_{VersionData?.BuildTime}";
|
||||
public string FileName;
|
||||
public VersionData VersionData;
|
||||
|
||||
/// <summary>
|
||||
/// 版本包
|
||||
/// </summary>
|
||||
public readonly List<PackageData> Packages = new List<PackageData>();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class PackageChangeData
|
||||
{
|
||||
public string PackageName;
|
||||
|
||||
/// <summary>
|
||||
/// 变化的bundle
|
||||
/// </summary>
|
||||
public List<BundleData> ChangeBundles = new List<BundleData>();
|
||||
|
||||
/// <summary>
|
||||
/// 新增的bundle
|
||||
/// </summary>
|
||||
public List<BundleData> AddBundles = new List<BundleData>();
|
||||
|
||||
/// <summary>
|
||||
/// 减少的bundle
|
||||
/// </summary>
|
||||
public List<BundleData> RemoveBundles = new List<BundleData>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 版本变化简略信息
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class VersionSimpleChangeData
|
||||
{
|
||||
/// <summary>
|
||||
/// 需要下载总数
|
||||
/// </summary>
|
||||
public long DownloadSize;
|
||||
|
||||
/// <summary>
|
||||
/// 每个资源包需要下载总数
|
||||
/// </summary>
|
||||
public Dictionary<string, long> PackageDownloadSize = new Dictionary<string, long>();
|
||||
|
||||
/// <summary>
|
||||
/// 每个资源包新增bundle
|
||||
/// </summary>
|
||||
public Dictionary<string, List<string>> PackageAddBundle = new Dictionary<string, List<string>>();
|
||||
|
||||
/// <summary>
|
||||
/// 每个资源包移除bundle
|
||||
/// </summary>
|
||||
public Dictionary<string, List<string>> PackageRemoveBundle = new Dictionary<string, List<string>>();
|
||||
|
||||
/// <summary>
|
||||
/// 每个资源包变化的bundle
|
||||
/// </summary>
|
||||
public Dictionary<string, List<string>> PackageChangeBundle = new Dictionary<string, List<string>>();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class VersionChangeData
|
||||
{
|
||||
public string NewVersionName;
|
||||
public string OldVersionName;
|
||||
public VersionSimpleChangeData SimpleChangeData = new VersionSimpleChangeData();
|
||||
|
||||
/// <summary>
|
||||
/// 变化的package
|
||||
/// </summary>
|
||||
public List<PackageChangeData> ChangePackage = new List<PackageChangeData>();
|
||||
|
||||
public enum TypeEnum
|
||||
{
|
||||
Add,
|
||||
Change,
|
||||
Remove
|
||||
}
|
||||
|
||||
public void Change(BundleData bundleData, TypeEnum typeEnum)
|
||||
{
|
||||
var packageChangeData = ChangePackage.Find(p => p.PackageName == bundleData.PackageName);
|
||||
if (packageChangeData == null)
|
||||
{
|
||||
packageChangeData = new PackageChangeData();
|
||||
packageChangeData.PackageName = bundleData.PackageName;
|
||||
ChangePackage.Add(packageChangeData);
|
||||
}
|
||||
|
||||
switch (typeEnum)
|
||||
{
|
||||
case TypeEnum.Add:
|
||||
packageChangeData.AddBundles.Add(bundleData);
|
||||
break;
|
||||
case TypeEnum.Remove:
|
||||
packageChangeData.RemoveBundles.Add(bundleData);
|
||||
break;
|
||||
case TypeEnum.Change:
|
||||
packageChangeData.ChangeBundles.Add(bundleData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Processing()
|
||||
{
|
||||
SimpleChangeData = new VersionSimpleChangeData();
|
||||
long allSize = 0;
|
||||
foreach (var package in ChangePackage)
|
||||
{
|
||||
var name = package.PackageName;
|
||||
var size = package.AddBundles.Sum(b => b.Size) + package.ChangeBundles.Sum(b => b.Size);
|
||||
allSize += size;
|
||||
SimpleChangeData.PackageDownloadSize[name] = size;
|
||||
|
||||
SimpleChangeData.PackageAddBundle[name] = package.AddBundles.Select(bundle => bundle.Name).ToList();
|
||||
SimpleChangeData.PackageRemoveBundle[name] =
|
||||
package.RemoveBundles.Select(bundle => bundle.Name).ToList();
|
||||
SimpleChangeData.PackageChangeBundle[name] =
|
||||
package.ChangeBundles.Select(bundle => bundle.Name).ToList();
|
||||
}
|
||||
|
||||
SimpleChangeData.DownloadSize = allSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7dfb832d1f340d4bd50c2f8922a44f0
|
||||
timeCreated: 1680151006
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Configs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Configs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bdb299374e124c9ea49469e24fd94a08
|
||||
timeCreated: 1673923827
|
||||
27
Assets/Scripts/NBC/Asset/Editor/Configs/GroupConfig.cs
Normal file
27
Assets/Scripts/NBC/Asset/Editor/Configs/GroupConfig.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class GroupConfig : ISelectTag
|
||||
{
|
||||
public string Name;
|
||||
[Header("是否启用")] public bool Enable = true;
|
||||
[Header("打包模式")] public BundleMode BundleMode = BundleMode.Single;
|
||||
[Header("寻址模式")] public AddressMode AddressMode = AddressMode.None;
|
||||
[Header("标签(,分隔)")] public string Tags;
|
||||
[Header("收集源")] public List<Object> Collectors = new List<Object>();
|
||||
[Header("过滤器规则")] public FilterEnum FilterEnum = FilterEnum.All;
|
||||
public string Filter = "*";
|
||||
|
||||
|
||||
public string ShowTags
|
||||
{
|
||||
get => Tags;
|
||||
set => Tags = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac530b0df8bb42a0a6f08ecc1cdf8984
|
||||
timeCreated: 1673923840
|
||||
7
Assets/Scripts/NBC/Asset/Editor/Configs/ISelectTag.cs
Normal file
7
Assets/Scripts/NBC/Asset/Editor/Configs/ISelectTag.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public interface ISelectTag
|
||||
{
|
||||
string ShowTags { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 149b01c9c6834709a5e3c7132f1b62e2
|
||||
timeCreated: 1679564478
|
||||
18
Assets/Scripts/NBC/Asset/Editor/Configs/PackageConfig.cs
Normal file
18
Assets/Scripts/NBC/Asset/Editor/Configs/PackageConfig.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
// [CreateAssetMenu(menuName = "NB/Res/" + nameof(PackageConfig), fileName = nameof(PackageConfig))]
|
||||
[Serializable]
|
||||
public class PackageConfig
|
||||
{
|
||||
public string Name;
|
||||
[Header("是否启用")] public bool Enable = true;
|
||||
[Header("是否默认包")] public bool Default = true;
|
||||
[Header("打包选项")] public BuildAssetBundleOptions BundleOptions = BuildAssetBundleOptions.ChunkBasedCompression;
|
||||
[Header("资源组")] public List<GroupConfig> Groups = new List<GroupConfig>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b762a65e11264f408a0a62631dfcfa3a
|
||||
timeCreated: 1673925286
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Defs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Defs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5db6f825229465890471817788059d9
|
||||
timeCreated: 1675826073
|
||||
46
Assets/Scripts/NBC/Asset/Editor/Defs/AddressMode.cs
Normal file
46
Assets/Scripts/NBC/Asset/Editor/Defs/AddressMode.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public enum AddressMode
|
||||
{
|
||||
/// <summary>
|
||||
/// 不启用寻址
|
||||
/// </summary>
|
||||
[DisplayName(Language.AddressModeNone)] None,
|
||||
|
||||
/// <summary>
|
||||
/// 文件名
|
||||
/// </summary>
|
||||
[DisplayName(Language.AddressModeFileName)]
|
||||
FileName,
|
||||
|
||||
/// <summary>
|
||||
/// 分组名+文件名
|
||||
/// </summary>
|
||||
[DisplayName(Language.AddressModeGroupAndFileName)]
|
||||
GroupAndFileName,
|
||||
|
||||
/// <summary>
|
||||
/// 收集源名称+文件名
|
||||
/// </summary>
|
||||
[DisplayName(Language.AddressModeCollectorAndFileName)]
|
||||
CollectorAndFileName,
|
||||
|
||||
/// <summary>
|
||||
/// 包名+组名+文件名
|
||||
/// </summary>
|
||||
[DisplayName(Language.AddressModePackAndGroupAndFileName)]
|
||||
PackAndGroupAndFileName,
|
||||
|
||||
/// <summary>
|
||||
/// 包名+文件名
|
||||
/// </summary>
|
||||
[DisplayName(Language.AddressModePackAndFileName)]
|
||||
PackAndFileName,
|
||||
|
||||
/// <summary>
|
||||
/// 包名+收集源名称+文件名
|
||||
/// </summary>
|
||||
[DisplayName(Language.AddressModePackAndCollectorAndFileName)]
|
||||
PackAndCollectorAndFileName,
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Defs/AddressMode.cs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Defs/AddressMode.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eeac94539b094cccb8b270ac674e7373
|
||||
timeCreated: 1678157999
|
||||
35
Assets/Scripts/NBC/Asset/Editor/Defs/BundleMode.cs
Normal file
35
Assets/Scripts/NBC/Asset/Editor/Defs/BundleMode.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public enum BundleMode
|
||||
{
|
||||
/// <summary>
|
||||
/// 一个ab
|
||||
/// </summary>
|
||||
[DisplayName(Language.BundleModeSingle)]
|
||||
Single,
|
||||
|
||||
/// <summary>
|
||||
/// 按文件夹(每个独立文件夹为一个ab包)
|
||||
/// </summary>
|
||||
[DisplayName(Language.BundleModeFolder)]
|
||||
Folder,
|
||||
|
||||
/// <summary>
|
||||
/// 父级文件夹
|
||||
/// </summary>
|
||||
[DisplayName(Language.BundleModeFolderParent)]
|
||||
FolderParent,
|
||||
|
||||
/// <summary>
|
||||
/// 每个文件一个ab
|
||||
/// </summary>
|
||||
[DisplayName(Language.BundleModeFile)]
|
||||
File,
|
||||
|
||||
/// <summary>
|
||||
/// 忽略子文件夹
|
||||
/// </summary>
|
||||
[DisplayName(Language.BundleModeWithoutSub)]
|
||||
WithoutSub
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Defs/BundleMode.cs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Defs/BundleMode.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcf5ff2b184f44d394f6d2837c124146
|
||||
timeCreated: 1675826079
|
||||
64
Assets/Scripts/NBC/Asset/Editor/Defs/Defs.cs
Normal file
64
Assets/Scripts/NBC/Asset/Editor/Defs/Defs.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public static class TaskId
|
||||
{
|
||||
/// <summary>
|
||||
/// 收集资源
|
||||
/// </summary>
|
||||
public const int Gather = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 打包bundle
|
||||
/// </summary>
|
||||
public const int BuildBundle = 2;
|
||||
|
||||
/// <summary>
|
||||
/// 生成版本清单
|
||||
/// </summary>
|
||||
public const int GenPackageData = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 生成版本清单
|
||||
/// </summary>
|
||||
public const int GenVersionData = 4;
|
||||
|
||||
/// <summary>
|
||||
/// 拷贝bundle和版本清单
|
||||
/// </summary>
|
||||
public const int CopyVersionBundle = 5;
|
||||
|
||||
/// <summary>
|
||||
/// 拷贝至StreamingAssets
|
||||
/// </summary>
|
||||
public const int CopyToStreamingAssets = 6;
|
||||
}
|
||||
|
||||
public class Defs
|
||||
{
|
||||
public static void AddTag(string tag)
|
||||
{
|
||||
if (!UserTags.Contains(tag))
|
||||
{
|
||||
UserTags.Add(tag);
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly List<string> UserTags = new List<string>() { };
|
||||
|
||||
public const float DefWindowWidth = 960;
|
||||
public const float DefWindowHeight = 600;
|
||||
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
public static readonly Type[] DockedWindowTypes =
|
||||
{
|
||||
typeof(CollectorWindow),
|
||||
typeof(ProfilerWindow),
|
||||
typeof(BuilderWindow),
|
||||
typeof(HistoryWindow)
|
||||
};
|
||||
#endif
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Defs/Defs.cs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Defs/Defs.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f71f781e73b4b898ae6bd3121528051
|
||||
timeCreated: 1675824656
|
||||
44
Assets/Scripts/NBC/Asset/Editor/Defs/FilterEnum.cs
Normal file
44
Assets/Scripts/NBC/Asset/Editor/Defs/FilterEnum.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public enum FilterEnum
|
||||
{
|
||||
//全部
|
||||
All = 0,
|
||||
//预制体
|
||||
Prefab,
|
||||
//场景
|
||||
Scene,
|
||||
//题图
|
||||
Texture,
|
||||
//精灵图片
|
||||
Sprite,
|
||||
//文件资产
|
||||
TextAsset,
|
||||
//材质
|
||||
Material,
|
||||
//网格
|
||||
Mesh,
|
||||
//字体
|
||||
Font,
|
||||
//模型
|
||||
Model,
|
||||
//着色器
|
||||
Shader,
|
||||
//音频
|
||||
AudioClip,
|
||||
//音频混音器
|
||||
AudioMixer,
|
||||
//视频
|
||||
VideoClip,
|
||||
//动画
|
||||
AnimationClip,
|
||||
//物理材质
|
||||
PhysicMaterial,
|
||||
//脚本
|
||||
Script,
|
||||
//动画控制器
|
||||
RuntimeAnimatorController,
|
||||
//自定义
|
||||
Custom
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Defs/FilterEnum.cs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Defs/FilterEnum.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79a86eb49eaf4efaa7869d03d5a41de5
|
||||
timeCreated: 1678157766
|
||||
134
Assets/Scripts/NBC/Asset/Editor/Defs/Language.cs
Normal file
134
Assets/Scripts/NBC/Asset/Editor/Defs/Language.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public static class Language
|
||||
{
|
||||
public const string AssetPackageName = "资源包";
|
||||
public const string AddPackage = "添加资源包";
|
||||
public const string EnableDefPackage = "设为默认包";
|
||||
public const string DisableDefPackage = "设为附加包";
|
||||
|
||||
public const string Enable = "启用";
|
||||
public const string Disable = "禁用";
|
||||
|
||||
public const string AssetGroupName = "资源组";
|
||||
public const string AddGroup = "添加资源组";
|
||||
|
||||
public const string Del = "删除";
|
||||
public const string ReName = "重命名";
|
||||
public const string Success = "成功";
|
||||
public const string Tips = "提示";
|
||||
public const string Confirm = "确定";
|
||||
public const string Error = "错误";
|
||||
|
||||
public const string AddressPath = "寻址地址";
|
||||
public const string FileSize = "文件大小";
|
||||
public const string Path = "真实地址";
|
||||
public const string CopyPath = "拷贝真实地址";
|
||||
public const string CopyAddressPath = "拷贝寻址地址";
|
||||
|
||||
|
||||
public const string NoSelectGroup = "没有选中的资源组";
|
||||
public const string GroupBundleMode = "打包模式";
|
||||
public const string GroupAddressMode = "寻址模式";
|
||||
public const string Tags = "资源标签";
|
||||
public const string Filter = "过滤器规则";
|
||||
public const string FilterCustom = "自定义过滤器规则";
|
||||
public const string CollectorTitle = "收集源{0}";
|
||||
|
||||
public const string RepetitiveName = "重复的名字";
|
||||
|
||||
public const string Save = "保存";
|
||||
public const string Build = "构建";
|
||||
public const string Tools = "工具";
|
||||
public const string Profiler = "资源监视";
|
||||
public const string Analyse = "资源分析";
|
||||
|
||||
public const string CollectorWindowName = "资源收集器";
|
||||
public const string ProfilerWindowName = "资源监视器";
|
||||
public const string BuilderWindowName = "资源构建器";
|
||||
public const string HistoryWindowName = "历史记录操作器";
|
||||
|
||||
public const string CollectorWindowMenuPath = "NBC/资源系统/资源收集器";
|
||||
public const string ProfilerWindowNameMenuPath = "NBC/资源系统/资源监视器";
|
||||
public const string BuilderWindowNameMenuPath = "NBC/资源系统/资源构建器";
|
||||
public const string HistoryWindowNameMenuPath = "NBC/资源系统/历史记录操作器";
|
||||
|
||||
public const string MenuDownloadPath = "NBC/资源系统/目录/下载解压目录";
|
||||
public const string MenuBuildPath = "NBC/资源系统/目录/构建目录";
|
||||
public const string MenuCachePath = "NBC/资源系统/目录/缓存目录";
|
||||
|
||||
public const string AddressModeNone = "不启用";
|
||||
public const string AddressModeFileName = "文件名";
|
||||
public const string AddressModeGroupAndFileName = "分组名+文件名";
|
||||
public const string AddressModeCollectorAndFileName = "收集源名称+文件名";
|
||||
public const string AddressModePackAndGroupAndFileName = "包名+组名+文件名";
|
||||
public const string AddressModePackAndFileName = "包名+文件名";
|
||||
public const string AddressModePackAndCollectorAndFileName = "包名+收集源名称+文件名";
|
||||
|
||||
public const string BundleModeSingle = "打包为一个AB";
|
||||
public const string BundleModeFolder = "每个独立文件夹为一个AB";
|
||||
public const string BundleModeFolderParent = "每个源文件夹为一个AB";
|
||||
public const string BundleModeFile = "每个文件一个AB";
|
||||
public const string BundleModeWithoutSub = "打包为一个AB且忽略子文件夹";
|
||||
|
||||
public const string LabelHintIdle = "输入筛选或添加新标签";
|
||||
public const string LabelHintSearchFoundIsEnabled = "<b>回车</b> 增加 '{0}'";
|
||||
public const string LabelHintSearchFoundIsDisabled = "<b>回车</b> 删除 '{0}'";
|
||||
|
||||
public const string InspectorUIAddressPath = "寻址路径: ";
|
||||
public const string InspectorUIPath = "真实路径: ";
|
||||
public const string InspectorUITitle = "文件可寻址信息";
|
||||
public const string InspectorUITitleNotOpen = "文件可寻址信息(未开启)";
|
||||
public const string Copy = "复制";
|
||||
|
||||
public const string ProfilerShowMode = "显示模式:";
|
||||
public const string ProfilerAssetMode = "资源";
|
||||
public const string ProfilerBundleMode = "资源包";
|
||||
public const string ImportProfiler = "导入";
|
||||
public const string ImportProfilerTips = "选择要导入文件";
|
||||
public const string BuildProfiler = "导出";
|
||||
public const string BuildProfilerTips = "选择要导出的目录";
|
||||
public const string Current = "采样";
|
||||
public const string Clear = "清理";
|
||||
public const string CurrentFrame = "当前帧:";
|
||||
public const string PrevFrame = "|上一帧";
|
||||
public const string NextFrame = "|下一帧";
|
||||
public const string ProfilerAssetPath = "资源路径";
|
||||
public const string ProfilerAssetType = "资源类型";
|
||||
public const string ProfilerLoadTime = "加载时间";
|
||||
public const string ProfilerStatus = "状态";
|
||||
public const string ProfilerLoadTotalTime = "加载耗时";
|
||||
public const string ProfilerLoadScene = "加载场景";
|
||||
public const string ProfilerRefCount = "引用数量";
|
||||
public const string ProfilerBundleName = "Bundle包名";
|
||||
public const string ProfilerDataMode = "数据源:";
|
||||
public const string ProfilerLocalData = "本地";
|
||||
public const string ProfilerRemoteData = "远程";
|
||||
public const string ProfilerRemoteUrl = "远程连接地址:";
|
||||
public const string ProfilerRemoteUrlIsNull = "远程连接地址未设置";
|
||||
|
||||
|
||||
public const string BuildBundleName = "构建AB包";
|
||||
public const string BuildStart = "立即构建";
|
||||
public const string BuildSuccessTips = "构建成功。热更内容大小:{0},新增Bundle:{1},修改Bunlde:{2},删除Bundle:{3}";
|
||||
|
||||
public const string HistoryVersionName = "历史打包版本";
|
||||
public const string HistoryBundleName = "资源包名";
|
||||
public const string HistoryHash = "资源哈希";
|
||||
public const string HistorySize = "大小";
|
||||
public const string HistoryDelete = "删除记录";
|
||||
public const string HistorySelectCompare = "选中为比较版本";
|
||||
public const string HistoryUnSelectCompare = "取消比较选中";
|
||||
public const string HistoryCompareBuild = "保存对比结果清单";
|
||||
public const string NoSelectHistoryCompareVersion = "无法显示比较信息:没有选中需要比较的旧版本,请在左侧侧栏中右键菜单选择要进行比较的旧版本";
|
||||
public const string NoSelectHistoryCompareOneVersion = "选中版本与当前版本一致";
|
||||
public const string HistoryBundleChangeTitle = "总数:{0} ({1})";
|
||||
public const string HistoryAddBundleCount = "新增的Bundle数";
|
||||
public const string HistoryChangeBundleCount = "修改的Bundle数";
|
||||
public const string HistoryRemoveBundleCount = "删除的Bundle包";
|
||||
public const string HistoryDownloadSize = "更新下载大小";
|
||||
public const string HistoryUse = "拷贝该版本到StreamingAssets";
|
||||
public const string HistoryCopyToFolder = "导出该版本到文件夹";
|
||||
public const string Refresh = "刷新";
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Defs/Language.cs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Defs/Language.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 830b0a745cd84048b1ad857c814d2347
|
||||
timeCreated: 1679369094
|
||||
56
Assets/Scripts/NBC/Asset/Editor/Defs/Styles.cs
Normal file
56
Assets/Scripts/NBC/Asset/Editor/Defs/Styles.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public static class Styles
|
||||
{
|
||||
private static bool _init;
|
||||
private static GUISkin styleSheet;
|
||||
private static GUIStyle _headerBoxStyle;
|
||||
|
||||
public static string EditorGUIPath;
|
||||
public static Texture2D Package;
|
||||
public static Texture2D PackageLow;
|
||||
public static Texture2D Group;
|
||||
public static Texture2D Add;
|
||||
|
||||
public static GUIStyle headerBoxStyle => _headerBoxStyle != null
|
||||
? _headerBoxStyle
|
||||
: _headerBoxStyle = styleSheet.GetStyle("HeaderBox");
|
||||
|
||||
public static GUIStyle headerLabelStyle => _headerBoxStyle != null
|
||||
? _headerBoxStyle
|
||||
: _headerBoxStyle = styleSheet.GetStyle("HeaderLabel");
|
||||
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
string[] folders = { "Assets", "Packages" };
|
||||
var assets = AssetDatabase.FindAssets("t:texture icon_package", folders);
|
||||
if (assets.Length > 0)
|
||||
{
|
||||
var assetPath = AssetDatabase.GUIDToAssetPath(assets[0]);
|
||||
EditorGUIPath = Path.GetDirectoryName(assetPath)?.Replace('\\', '/');
|
||||
}
|
||||
|
||||
|
||||
styleSheet = LoadRes<GUISkin>("StyleSheet.guiskin");
|
||||
Package = LoadIcon("icon_package.png");
|
||||
PackageLow = LoadIcon("icon_package2.png");
|
||||
Group = LoadIcon("icon_folder.png");
|
||||
Add = LoadIcon("icon_add.png");
|
||||
}
|
||||
|
||||
static Texture2D LoadIcon(string filename)
|
||||
{
|
||||
return LoadRes<Texture2D>(filename);
|
||||
}
|
||||
|
||||
static T LoadRes<T>(string filename) where T : Object
|
||||
{
|
||||
return AssetDatabase.LoadMainAssetAtPath(EditorGUIPath + "/" + filename) as T;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Asset/Editor/Defs/Styles.cs.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/Defs/Styles.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e719c6f260ec4447b6ec9e06eea4670c
|
||||
timeCreated: 1679380174
|
||||
3
Assets/Scripts/NBC/Asset/Editor/GUI.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/GUI.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a5226005f4849fa841906277373e1a2
|
||||
timeCreated: 1679321515
|
||||
3
Assets/Scripts/NBC/Asset/Editor/GUI/Builder.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/GUI/Builder.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85de779f0e1c49718afffe35427bca16
|
||||
timeCreated: 1679472125
|
||||
106
Assets/Scripts/NBC/Asset/Editor/GUI/Builder/BuilderWindow.cs
Normal file
106
Assets/Scripts/NBC/Asset/Editor/GUI/Builder/BuilderWindow.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public class BuilderWindow : EditorWindow
|
||||
{
|
||||
[MenuItem(Language.BuilderWindowNameMenuPath, false, 2)]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
BuilderWindow wnd = GetWindow<BuilderWindow>(Language.BuilderWindowName, true, Defs.DockedWindowTypes);
|
||||
wnd.minSize = new Vector2(Defs.DefWindowWidth, Defs.DefWindowHeight);
|
||||
}
|
||||
|
||||
const int _splitterThickness = 2;
|
||||
|
||||
public BuildBundle SelectBundleConfig;
|
||||
|
||||
readonly VerticalSplitter _verticalSplitter = new VerticalSplitter(0.8f, 0.7f, 0.8f);
|
||||
readonly HorizontalSplitter _horizontalSplitter = new HorizontalSplitter(0.4f, 0.3f, 0.6f);
|
||||
|
||||
private BuildBundleTreeEditor _buildBundleList;
|
||||
private BuildBundleAssetsTreeEditor _buildBundleAssetsTreeEditor;
|
||||
|
||||
public void UpdateSelectedBundle(string name)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
var cache = Caches.Get();
|
||||
if (cache.Bundles == null) return;
|
||||
foreach (var bundle in cache.Bundles)
|
||||
{
|
||||
if (bundle.Name != name) continue;
|
||||
SelectBundleConfig = bundle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectBundleConfig = null;
|
||||
}
|
||||
|
||||
_buildBundleAssetsTreeEditor?.Reload();
|
||||
}
|
||||
|
||||
protected void OnEnable()
|
||||
{
|
||||
Builder.Gather();
|
||||
Styles.Initialize();
|
||||
}
|
||||
|
||||
protected void OnGUI()
|
||||
{
|
||||
var barHeight = _splitterThickness;
|
||||
Rect contentRect = new Rect(_splitterThickness, barHeight, position.width - _splitterThickness * 4,
|
||||
position.height - barHeight - _splitterThickness);
|
||||
|
||||
var resizingPackage = _horizontalSplitter.OnGUI(contentRect, out var bundleRect, out var infoRect);
|
||||
|
||||
DrawBuildBundleList(bundleRect);
|
||||
bool resizingVer = _verticalSplitter.OnGUI(infoRect, out var top, out var bot);
|
||||
DrawAssetList(top);
|
||||
DrawBuildOperation(bot);
|
||||
if (resizingPackage || resizingVer)
|
||||
Repaint();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DrawBuildBundleList(Rect rect)
|
||||
{
|
||||
if (_buildBundleList == null)
|
||||
{
|
||||
_buildBundleList = new BuildBundleTreeEditor(new TreeViewState(), this,
|
||||
BuildBundleTreeEditor.CreateDefaultMultiColumnHeaderState());
|
||||
}
|
||||
|
||||
_buildBundleList.OnGUI(rect);
|
||||
}
|
||||
|
||||
void DrawAssetList(Rect rect)
|
||||
{
|
||||
if (_buildBundleAssetsTreeEditor == null)
|
||||
{
|
||||
_buildBundleAssetsTreeEditor = new BuildBundleAssetsTreeEditor(new TreeViewState(), this,
|
||||
BuildBundleAssetsTreeEditor.CreateDefaultMultiColumnHeaderState());
|
||||
}
|
||||
|
||||
_buildBundleAssetsTreeEditor.OnGUI(rect);
|
||||
}
|
||||
|
||||
void DrawBuildOperation(Rect rect)
|
||||
{
|
||||
GUILayout.BeginArea(rect);
|
||||
GUILayout.Space(20);
|
||||
var height = rect.height * 0.4f;
|
||||
if (GUILayout.Button(Language.BuildStart, GUILayout.Height((int)height)))
|
||||
{
|
||||
Builder.Build();
|
||||
HistoryUtil.ShowLastBuildInfo();
|
||||
}
|
||||
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 304020e2c4ff4a4d82c363ebc7da11f1
|
||||
timeCreated: 1679472136
|
||||
3
Assets/Scripts/NBC/Asset/Editor/GUI/Builder/SubView.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/GUI/Builder/SubView.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60848865285f41c0b85a659486785caf
|
||||
timeCreated: 1679977546
|
||||
@@ -0,0 +1,234 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public class BuildBundleAssetsTreeEditor : TreeView
|
||||
{
|
||||
public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState()
|
||||
{
|
||||
return new MultiColumnHeaderState(GetColumns());
|
||||
}
|
||||
|
||||
private static MultiColumnHeaderState.Column[] GetColumns()
|
||||
{
|
||||
List<MultiColumnHeaderState.Column> retVal = new List<MultiColumnHeaderState.Column>();
|
||||
retVal.Add(EditUtil.GetMultiColumnHeaderColumn(Language.Path, 200));
|
||||
retVal.Add(EditUtil.GetMultiColumnHeaderColumn(Language.FileSize));
|
||||
retVal.Add(EditUtil.GetMultiColumnHeaderColumn(Language.AddressPath));
|
||||
|
||||
return retVal.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前选中了
|
||||
/// </summary>
|
||||
private bool _contextOnItem = false;
|
||||
|
||||
BuilderWindow _window;
|
||||
public MultiColumnHeaderState HeaderState;
|
||||
|
||||
public BuildBundleAssetsTreeEditor(TreeViewState state, BuilderWindow window, MultiColumnHeaderState header) :
|
||||
base(state,
|
||||
new MultiColumnHeader(header))
|
||||
{
|
||||
_window = window;
|
||||
HeaderState = header;
|
||||
showBorder = true;
|
||||
showAlternatingRowBackgrounds = true;
|
||||
|
||||
Reload();
|
||||
}
|
||||
|
||||
private TreeViewItem _root = null;
|
||||
|
||||
protected override TreeViewItem BuildRoot()
|
||||
{
|
||||
_root = new TreeViewItem
|
||||
{
|
||||
id = -1,
|
||||
depth = -1,
|
||||
children = new List<TreeViewItem>()
|
||||
};
|
||||
int id = 0;
|
||||
|
||||
if (_window.SelectBundleConfig != null && _window.SelectBundleConfig != null)
|
||||
{
|
||||
var bundle = _window.SelectBundleConfig;
|
||||
foreach (var asset in bundle.Assets)
|
||||
{
|
||||
id++;
|
||||
var t = new AssetTreeViewItem(id, asset);
|
||||
_root.AddChild(t);
|
||||
}
|
||||
}
|
||||
|
||||
return _root;
|
||||
}
|
||||
|
||||
|
||||
#region 绘制
|
||||
|
||||
enum MyColumns
|
||||
{
|
||||
Asset,
|
||||
Size,
|
||||
Path
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect rect)
|
||||
{
|
||||
base.OnGUI(rect);
|
||||
HeaderState.AutoWidth(rect.width, 2);
|
||||
if (UnityEngine.Event.current.type == EventType.MouseDown && UnityEngine.Event.current.button == 0 &&
|
||||
rect.Contains(UnityEngine.Event.current.mousePosition))
|
||||
{
|
||||
SetSelection(Array.Empty<int>(), TreeViewSelectionOptions.FireSelectionChanged);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void RowGUI(RowGUIArgs args)
|
||||
{
|
||||
for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
|
||||
{
|
||||
CellGUI(args.GetCellRect(i), args.item, args.GetColumn(i), ref args);
|
||||
}
|
||||
}
|
||||
|
||||
private void CellGUI(Rect cellRect, TreeViewItem item, int column, ref RowGUIArgs args)
|
||||
{
|
||||
AssetTreeViewItem assetTreeViewItem = item as AssetTreeViewItem;
|
||||
if (assetTreeViewItem == null) return;
|
||||
var assetData = assetTreeViewItem.Asset;
|
||||
Color oldColor = GUI.color;
|
||||
CenterRectUsingSingleLineHeight(ref cellRect);
|
||||
if (!File.Exists(assetData.Path))
|
||||
{
|
||||
GUI.color = Color.red;
|
||||
}
|
||||
|
||||
switch ((MyColumns)column)
|
||||
{
|
||||
case MyColumns.Asset:
|
||||
{
|
||||
var iconRect = new Rect(cellRect.x + 1, cellRect.y + 1, cellRect.height - 2, cellRect.height - 2);
|
||||
if (item.icon != null)
|
||||
{
|
||||
GUI.DrawTexture(iconRect, item.icon, ScaleMode.ScaleToFit);
|
||||
}
|
||||
|
||||
var nameRect = new Rect(cellRect.x + iconRect.xMax + 1
|
||||
, cellRect.y, cellRect.width - iconRect.width, cellRect.height);
|
||||
|
||||
DefaultGUI.Label(nameRect,
|
||||
item.displayName,
|
||||
args.selected,
|
||||
args.focused);
|
||||
}
|
||||
break;
|
||||
case MyColumns.Size:
|
||||
EditorGUI.LabelField(cellRect, GetSizeString(assetData), GUITools.DefLabelStyle);
|
||||
break;
|
||||
case MyColumns.Path:
|
||||
DefaultGUI.Label(cellRect, assetData.Address, args.selected, args.focused);
|
||||
break;
|
||||
}
|
||||
|
||||
GUI.color = oldColor;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 事件
|
||||
|
||||
/// <summary>
|
||||
/// 点击的时候
|
||||
/// </summary>
|
||||
protected override void ContextClicked()
|
||||
{
|
||||
if (HasSelection())
|
||||
{
|
||||
_contextOnItem = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DoubleClickedItem(int id)
|
||||
{
|
||||
if (FindItem(id, rootItem) is AssetTreeViewItem assetItem)
|
||||
{
|
||||
UnityEngine.Object o = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetItem.Asset.Path);
|
||||
EditorGUIUtility.PingObject(o);
|
||||
Selection.activeObject = o;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ContextClickedItem(int id)
|
||||
{
|
||||
if (_contextOnItem)
|
||||
{
|
||||
_contextOnItem = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_contextOnItem = true;
|
||||
List<int> selectedNodes = new List<int>();
|
||||
foreach (var nodeID in GetSelection())
|
||||
{
|
||||
selectedNodes.Add(nodeID);
|
||||
}
|
||||
|
||||
GenericMenu menu = new GenericMenu();
|
||||
if (selectedNodes.Count == 1)
|
||||
{
|
||||
menu.AddItem(new GUIContent(Language.CopyPath), false, CopyPath, selectedNodes);
|
||||
menu.AddItem(new GUIContent(Language.CopyAddressPath), false, CopyAddressPath, selectedNodes);
|
||||
}
|
||||
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 私有方法
|
||||
|
||||
private string GetSizeString(BuildAsset asset)
|
||||
{
|
||||
if (asset.Size == 0)
|
||||
return "--";
|
||||
return EditorUtility.FormatBytes(asset.Size);
|
||||
}
|
||||
|
||||
private void CopyAddressPath(object context)
|
||||
{
|
||||
if (context is List<int> selectedNodes && selectedNodes.Count > 0)
|
||||
{
|
||||
TreeViewItem item = FindItem(selectedNodes[0], rootItem);
|
||||
if (item is AssetTreeViewItem assetTreeViewItem)
|
||||
{
|
||||
EditUtil.CopyToClipBoard(assetTreeViewItem.Asset.Address);
|
||||
Debug.Log($"copy success:{assetTreeViewItem.Asset.Address}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyPath(object context)
|
||||
{
|
||||
if (context is List<int> selectedNodes && selectedNodes.Count > 0)
|
||||
{
|
||||
TreeViewItem item = FindItem(selectedNodes[0], rootItem);
|
||||
if (item is AssetTreeViewItem assetTreeViewItem)
|
||||
{
|
||||
EditUtil.CopyToClipBoard(assetTreeViewItem.Asset.Path);
|
||||
Debug.Log($"copy success:{assetTreeViewItem.Asset.Path}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa3fa99bb63d4717b8c7aab8930a3953
|
||||
timeCreated: 1679978995
|
||||
@@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public class BuildBundleTreeViewItem : TreeViewItem
|
||||
{
|
||||
private BuildBundle _bundle;
|
||||
|
||||
public BuildBundle Bundle => _bundle;
|
||||
|
||||
public BuildBundleTreeViewItem(int id, BuildBundle bundle) : base(id, id, bundle.Name)
|
||||
{
|
||||
_bundle = bundle;
|
||||
}
|
||||
}
|
||||
|
||||
public class BuildBundleTreeEditor : TreeView
|
||||
{
|
||||
public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState()
|
||||
{
|
||||
return new MultiColumnHeaderState(GetColumns());
|
||||
}
|
||||
|
||||
private static MultiColumnHeaderState.Column[] GetColumns()
|
||||
{
|
||||
List<MultiColumnHeaderState.Column> retVal = new List<MultiColumnHeaderState.Column>();
|
||||
var fist = EditUtil.GetMultiColumnHeaderColumn(Language.BuildBundleName, 200, 200, 1000);
|
||||
retVal.Add(fist);
|
||||
return retVal.ToArray();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当前选中了
|
||||
/// </summary>
|
||||
private bool mContextOnItem = false;
|
||||
|
||||
BuilderWindow _window;
|
||||
|
||||
public MultiColumnHeaderState HeaderState;
|
||||
|
||||
public BuildBundleTreeEditor(TreeViewState state, BuilderWindow window, MultiColumnHeaderState header)
|
||||
: base(state, new MultiColumnHeader(header))
|
||||
{
|
||||
HeaderState = header;
|
||||
showBorder = true;
|
||||
|
||||
showAlternatingRowBackgrounds = false;
|
||||
_window = window;
|
||||
Refresh();
|
||||
Reload();
|
||||
}
|
||||
|
||||
|
||||
private TreeViewItem _root;
|
||||
|
||||
protected override TreeViewItem BuildRoot()
|
||||
{
|
||||
_root = new TreeViewItem
|
||||
{
|
||||
id = -1,
|
||||
depth = -1,
|
||||
children = new List<TreeViewItem>()
|
||||
};
|
||||
int id = 0;
|
||||
var caches = Caches.Get();
|
||||
foreach (var bundle in caches.Bundles)
|
||||
{
|
||||
id++;
|
||||
var t = new BuildBundleTreeViewItem(id, bundle);
|
||||
_root.AddChild(t);
|
||||
}
|
||||
|
||||
return _root;
|
||||
}
|
||||
|
||||
internal void Refresh()
|
||||
{
|
||||
var selection = GetSelection();
|
||||
|
||||
SelectionChanged(selection);
|
||||
}
|
||||
|
||||
#region 绘制
|
||||
|
||||
public override void OnGUI(Rect rect)
|
||||
{
|
||||
base.OnGUI(rect);
|
||||
HeaderState.AutoWidth(rect.width);
|
||||
if (Event.current.type == EventType.MouseDown && Event.current.button == 0 &&
|
||||
rect.Contains(Event.current.mousePosition))
|
||||
{
|
||||
SetSelection(Array.Empty<int>(), TreeViewSelectionOptions.FireSelectionChanged);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绘制行
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
protected override void RowGUI(RowGUIArgs args)
|
||||
{
|
||||
for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
|
||||
{
|
||||
CellGUI(args.GetCellRect(i), args.item, args.GetColumn(i), ref args);
|
||||
}
|
||||
}
|
||||
|
||||
private void CellGUI(Rect cellRect, TreeViewItem item, int column, ref RowGUIArgs args)
|
||||
{
|
||||
if (item is BuildBundleTreeViewItem bundleTreeViewItem)
|
||||
{
|
||||
CenterRectUsingSingleLineHeight(ref cellRect);
|
||||
if (column == 0)
|
||||
{
|
||||
var iconRect = new Rect(cellRect.x + 4, cellRect.y + 1, cellRect.height - 2, cellRect.height - 2);
|
||||
GUI.DrawTexture(iconRect, Styles.Package, ScaleMode.ScaleToFit);
|
||||
|
||||
var nameRect = new Rect(cellRect.x + iconRect.xMax + 1, cellRect.y, cellRect.width - iconRect.width,
|
||||
cellRect.height);
|
||||
DefaultGUI.Label(nameRect, item.displayName, args.selected, args.focused);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 接口实现
|
||||
|
||||
/// <summary>
|
||||
/// 是否能多选
|
||||
/// </summary>
|
||||
/// <param name="item">选中的文件</param>
|
||||
/// <returns></returns>
|
||||
protected override bool CanMultiSelect(TreeViewItem item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override float GetCustomRowHeight(int row, TreeViewItem item)
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 事件回调
|
||||
|
||||
protected override void SelectionChanged(IList<int> selectedIds)
|
||||
{
|
||||
var selectedBundles = new List<string>();
|
||||
foreach (var id in selectedIds)
|
||||
{
|
||||
var item = FindItem(id, rootItem);
|
||||
if (item != null)
|
||||
selectedBundles.Add(item.displayName);
|
||||
}
|
||||
|
||||
_window.UpdateSelectedBundle(selectedBundles.Count > 0 ? selectedBundles[0] : string.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3010c810f5344608b1612bd177dbd17
|
||||
timeCreated: 1679977834
|
||||
8
Assets/Scripts/NBC/Asset/Editor/GUI/Collector.meta
Normal file
8
Assets/Scripts/NBC/Asset/Editor/GUI/Collector.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ebef90b58f1fe744958dee119ebc373
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
192
Assets/Scripts/NBC/Asset/Editor/GUI/Collector/CollectorWindow.cs
Normal file
192
Assets/Scripts/NBC/Asset/Editor/GUI/Collector/CollectorWindow.cs
Normal file
@@ -0,0 +1,192 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public class CollectorWindow : EditorWindow
|
||||
{
|
||||
[MenuItem(Language.CollectorWindowMenuPath, false, 1)]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
CollectorWindow wnd =
|
||||
GetWindow<CollectorWindow>(Language.CollectorWindowName, true, Defs.DockedWindowTypes);
|
||||
wnd.minSize = new Vector2(Defs.DefWindowWidth, Defs.DefWindowHeight);
|
||||
}
|
||||
|
||||
public PackageConfig SelectPackageConfig;
|
||||
public GroupConfig SelectGroupConfig;
|
||||
|
||||
readonly VerticalSplitter _verticalSplitter = new VerticalSplitter();
|
||||
readonly HorizontalSplitter _horizontalSplitter1 = new HorizontalSplitter(0.2f, 0.1f, 0.3f);
|
||||
readonly HorizontalSplitter _horizontalSplitter2 = new HorizontalSplitter(0.2f, 0.1f, 0.3f);
|
||||
|
||||
const int _splitterThickness = 2;
|
||||
|
||||
PackageTreeEditor _packagesList;
|
||||
GroupTreeEditor _groupsList;
|
||||
private AssetsTreeEditor _assetsList;
|
||||
private GroupInfoGUI _groupInfoGUI;
|
||||
|
||||
public void UpdateSelectedPackage(string packageName)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(packageName))
|
||||
{
|
||||
var packages = CollectorSetting.Instance.Packages;
|
||||
if (packages == null) return;
|
||||
foreach (var package in packages)
|
||||
{
|
||||
if (package.Name != packageName) continue;
|
||||
SelectPackageConfig = package;
|
||||
SelectGroupConfig = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectPackageConfig = null;
|
||||
SelectGroupConfig = null;
|
||||
}
|
||||
|
||||
_groupsList?.Reload();
|
||||
_groupsList?.SetSelection(new List<int>());
|
||||
_assetsList?.Reload();
|
||||
}
|
||||
|
||||
public void UpdateSelectedGroup(string groupName)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(groupName))
|
||||
{
|
||||
if (SelectPackageConfig == null) return;
|
||||
foreach (var group in SelectPackageConfig.Groups)
|
||||
{
|
||||
if (group.Name != groupName) continue;
|
||||
SelectGroupConfig = group;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectGroupConfig = null;
|
||||
}
|
||||
|
||||
_assetsList?.Reload();
|
||||
}
|
||||
|
||||
public void UpdateAssets()
|
||||
{
|
||||
Builder.Gather();
|
||||
_assetsList?.Reload();
|
||||
}
|
||||
|
||||
protected void OnEnable()
|
||||
{
|
||||
Builder.Gather();
|
||||
Styles.Initialize();
|
||||
}
|
||||
|
||||
protected void OnGUI()
|
||||
{
|
||||
GUI.skin.label.richText = true;
|
||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||
EditorStyles.label.richText = true;
|
||||
EditorStyles.textField.wordWrap = true;
|
||||
EditorStyles.foldout.richText = true;
|
||||
|
||||
DrawToolBar();
|
||||
var barHeight = EditorStyles.toolbar.fixedHeight + _splitterThickness;
|
||||
Rect contentRect = new Rect(_splitterThickness, barHeight, position.width - _splitterThickness * 4,
|
||||
position.height - barHeight - _splitterThickness);
|
||||
|
||||
var resizingPackage = _horizontalSplitter1.OnGUI(contentRect, out var packageRect, out var groupRect);
|
||||
|
||||
DrawPackagesList(packageRect);
|
||||
|
||||
var resizingGroup = _horizontalSplitter2.OnGUI(groupRect, out var groupListRect, out var groupInfoRect);
|
||||
|
||||
DrawGroupList(groupListRect);
|
||||
|
||||
bool resizingVer = _verticalSplitter.OnGUI(groupInfoRect, out var groupBaseInfo, out var groupAssetList);
|
||||
|
||||
DrawGroupInfo(groupBaseInfo);
|
||||
DrawAssetList(groupAssetList);
|
||||
|
||||
if (resizingPackage || resizingGroup || resizingVer)
|
||||
Repaint();
|
||||
}
|
||||
|
||||
void DrawToolBar()
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
|
||||
var guiMode = new GUIContent(Language.Tools);
|
||||
Rect rMode = GUILayoutUtility.GetRect(guiMode, EditorStyles.toolbarDropDown);
|
||||
if (EditorGUI.DropdownButton(rMode, guiMode, FocusType.Passive, EditorStyles.toolbarDropDown))
|
||||
{
|
||||
var menu = new GenericMenu();
|
||||
menu.AddItem(new GUIContent(Language.Profiler), false, () => { });
|
||||
menu.AddItem(new GUIContent(Language.Analyse), false, () => { });
|
||||
menu.DropDown(rMode);
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button(Language.Build, EditorStyles.toolbarButton))
|
||||
{
|
||||
Builder.Build();
|
||||
}
|
||||
|
||||
if (GUILayout.Button(Language.Save, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
CollectorSetting.Instance.Save();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
void DrawPackagesList(Rect rect)
|
||||
{
|
||||
if (_packagesList == null)
|
||||
{
|
||||
_packagesList = new PackageTreeEditor(new TreeViewState(), this,
|
||||
PackageTreeEditor.CreateDefaultMultiColumnHeaderState());
|
||||
}
|
||||
|
||||
_packagesList.OnGUI(rect);
|
||||
}
|
||||
|
||||
void DrawGroupList(Rect rect)
|
||||
{
|
||||
if (_groupsList == null)
|
||||
{
|
||||
_groupsList = new GroupTreeEditor(new TreeViewState(), this,
|
||||
GroupTreeEditor.CreateDefaultMultiColumnHeaderState());
|
||||
}
|
||||
|
||||
_groupsList.OnGUI(rect);
|
||||
}
|
||||
|
||||
|
||||
void DrawGroupInfo(Rect rect)
|
||||
{
|
||||
if (_groupInfoGUI == null)
|
||||
{
|
||||
_groupInfoGUI = new GroupInfoGUI(this);
|
||||
}
|
||||
|
||||
_groupInfoGUI.OnGUI(rect);
|
||||
}
|
||||
|
||||
void DrawAssetList(Rect rect)
|
||||
{
|
||||
if (_assetsList == null)
|
||||
{
|
||||
_assetsList = new AssetsTreeEditor(new TreeViewState(), this,
|
||||
AssetsTreeEditor.CreateDefaultMultiColumnHeaderState());
|
||||
}
|
||||
|
||||
_assetsList.OnGUI(rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64eabfbca2143c940a620e3fe03f8e2c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
// using System.Collections.Generic;
|
||||
// using UnityEditor.IMGUI.Controls;
|
||||
//
|
||||
// namespace NBC.Asset.Editor
|
||||
// {
|
||||
// public class PackagesListTreeView : TreeView
|
||||
// {
|
||||
// private TreeViewItem mRoot = null;
|
||||
//
|
||||
// public PackagesListTreeView(TreeViewState state, AssetGroupMgr ctrl, MultiColumnHeaderState mchs) : base(state,
|
||||
// new MultiColumnHeader(mchs))
|
||||
// {
|
||||
// showBorder = true;
|
||||
//
|
||||
// showAlternatingRowBackgrounds = false;
|
||||
// mController = ctrl;
|
||||
// Refresh();
|
||||
// Reload();
|
||||
// }
|
||||
//
|
||||
// protected override TreeViewItem BuildRoot()
|
||||
// {
|
||||
// mRoot = new TreeViewItem
|
||||
// {
|
||||
// id = -1,
|
||||
// depth = -1,
|
||||
// children = new List<TreeViewItem>()
|
||||
// };
|
||||
// int id = 0;
|
||||
// var packages = CollectorSetting.Instance.Packages;
|
||||
// foreach (var package in packages)
|
||||
// {
|
||||
// id++;
|
||||
// var t = new PackageTreeViewItem(id, package);
|
||||
// mRoot.AddChild(t);
|
||||
// }
|
||||
//
|
||||
// return mRoot;
|
||||
// }
|
||||
//
|
||||
// public PackagesListTreeView(TreeViewState state) : base(state)
|
||||
// {
|
||||
// }
|
||||
//
|
||||
// public PackagesListTreeView(TreeViewState state, MultiColumnHeader multiColumnHeader) : base(state, multiColumnHeader)
|
||||
// {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a53cbb0029c40c6a39fa066cbae38d5
|
||||
timeCreated: 1679405350
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ef2c25ab0b24e8c90faeec8bbad5cf8
|
||||
timeCreated: 1679386737
|
||||
@@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public sealed class AssetTreeViewItem : TreeViewItem
|
||||
{
|
||||
private BuildAsset _asset;
|
||||
|
||||
public BuildAsset Asset => _asset;
|
||||
|
||||
public AssetTreeViewItem(int id, BuildAsset asset) : base(id, id, asset.Path)
|
||||
{
|
||||
_asset = asset;
|
||||
icon = AssetDatabase.GetCachedIcon(asset.Path) as Texture2D;
|
||||
}
|
||||
}
|
||||
|
||||
public class AssetsTreeEditor : TreeView
|
||||
{
|
||||
public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState()
|
||||
{
|
||||
return new MultiColumnHeaderState(GetColumns());
|
||||
}
|
||||
|
||||
private static MultiColumnHeaderState.Column[] GetColumns()
|
||||
{
|
||||
List<MultiColumnHeaderState.Column> retVal = new List<MultiColumnHeaderState.Column>();
|
||||
retVal.Add(EditUtil.GetMultiColumnHeaderColumn(Language.Path,200));
|
||||
retVal.Add(EditUtil.GetMultiColumnHeaderColumn(Language.FileSize));
|
||||
retVal.Add(EditUtil.GetMultiColumnHeaderColumn(Language.AddressPath));
|
||||
return retVal.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前选中了
|
||||
/// </summary>
|
||||
private bool mContextOnItem;
|
||||
|
||||
CollectorWindow _window;
|
||||
public MultiColumnHeaderState HeaderState;
|
||||
|
||||
public AssetsTreeEditor(TreeViewState state, CollectorWindow window, MultiColumnHeaderState header) : base(state,
|
||||
new MultiColumnHeader(header))
|
||||
{
|
||||
_window = window;
|
||||
HeaderState = header;
|
||||
showBorder = true;
|
||||
showAlternatingRowBackgrounds = true;
|
||||
|
||||
Reload();
|
||||
}
|
||||
|
||||
private TreeViewItem _root = null;
|
||||
|
||||
protected override TreeViewItem BuildRoot()
|
||||
{
|
||||
_root = new TreeViewItem
|
||||
{
|
||||
id = -1,
|
||||
depth = -1,
|
||||
children = new List<TreeViewItem>()
|
||||
};
|
||||
int id = 0;
|
||||
var cache = Caches.Get();
|
||||
if (cache.Assets.Count > 0)
|
||||
{
|
||||
if (_window.SelectPackageConfig != null && _window.SelectGroupConfig != null)
|
||||
{
|
||||
foreach (var asset in cache.Assets)
|
||||
{
|
||||
if (asset.Group == null) continue;
|
||||
if (asset.Group != _window.SelectGroupConfig)
|
||||
continue;
|
||||
id++;
|
||||
var t = new AssetTreeViewItem(id, asset);
|
||||
_root.AddChild(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _root;
|
||||
}
|
||||
|
||||
enum MyColumns
|
||||
{
|
||||
Asset,
|
||||
Size,
|
||||
Path
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect rect)
|
||||
{
|
||||
base.OnGUI(rect);
|
||||
HeaderState.AutoWidth(rect.width,2);
|
||||
if (UnityEngine.Event.current.type == EventType.MouseDown && UnityEngine.Event.current.button == 0 &&
|
||||
rect.Contains(UnityEngine.Event.current.mousePosition))
|
||||
{
|
||||
SetSelection(Array.Empty<int>(), TreeViewSelectionOptions.FireSelectionChanged);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void RowGUI(RowGUIArgs args)
|
||||
{
|
||||
for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
|
||||
{
|
||||
CellGUI(args.GetCellRect(i), args.item, args.GetColumn(i), ref args);
|
||||
}
|
||||
}
|
||||
|
||||
private void CellGUI(Rect cellRect, TreeViewItem item, int column, ref RowGUIArgs args)
|
||||
{
|
||||
AssetTreeViewItem assetTreeViewItem = item as AssetTreeViewItem;
|
||||
if (assetTreeViewItem == null) return;
|
||||
var assetData = assetTreeViewItem.Asset;
|
||||
Color oldColor = GUI.color;
|
||||
CenterRectUsingSingleLineHeight(ref cellRect);
|
||||
if (!File.Exists(assetData.Path))
|
||||
{
|
||||
GUI.color = Color.red;
|
||||
}
|
||||
|
||||
switch ((MyColumns)column)
|
||||
{
|
||||
case MyColumns.Asset:
|
||||
{
|
||||
var iconRect = new Rect(cellRect.x + 1, cellRect.y + 1, cellRect.height - 2, cellRect.height - 2);
|
||||
if (item.icon != null)
|
||||
{
|
||||
GUI.DrawTexture(iconRect, item.icon, ScaleMode.ScaleToFit);
|
||||
}
|
||||
|
||||
var nameRect = new Rect(cellRect.x + iconRect.xMax + 1
|
||||
, cellRect.y, cellRect.width - iconRect.width, cellRect.height);
|
||||
|
||||
DefaultGUI.Label(nameRect,
|
||||
item.displayName,
|
||||
args.selected,
|
||||
args.focused);
|
||||
}
|
||||
break;
|
||||
case MyColumns.Size:
|
||||
EditorGUI.LabelField(cellRect, GetSizeString(assetData), GUITools.DefLabelStyle);
|
||||
break;
|
||||
case MyColumns.Path:
|
||||
DefaultGUI.Label(cellRect, assetData.Address, args.selected, args.focused);
|
||||
break;
|
||||
}
|
||||
|
||||
GUI.color = oldColor;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 点击的时候
|
||||
/// </summary>
|
||||
protected override void ContextClicked()
|
||||
{
|
||||
if (HasSelection())
|
||||
{
|
||||
mContextOnItem = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DoubleClickedItem(int id)
|
||||
{
|
||||
if (FindItem(id, rootItem) is AssetTreeViewItem assetItem)
|
||||
{
|
||||
UnityEngine.Object o = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetItem.Asset.Path);
|
||||
EditorGUIUtility.PingObject(o);
|
||||
Selection.activeObject = o;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ContextClickedItem(int id)
|
||||
{
|
||||
if (mContextOnItem)
|
||||
{
|
||||
mContextOnItem = false;
|
||||
return;
|
||||
}
|
||||
|
||||
mContextOnItem = true;
|
||||
List<int> selectedNodes = new List<int>();
|
||||
foreach (var nodeID in GetSelection())
|
||||
{
|
||||
selectedNodes.Add(nodeID);
|
||||
}
|
||||
|
||||
GenericMenu menu = new GenericMenu();
|
||||
if (selectedNodes.Count == 1)
|
||||
{
|
||||
menu.AddItem(new GUIContent(Language.CopyPath), false, CopyPath, selectedNodes);
|
||||
menu.AddItem(new GUIContent(Language.CopyAddressPath), false, CopyAddressPath, selectedNodes);
|
||||
}
|
||||
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
|
||||
public string GetSizeString(BuildAsset asset)
|
||||
{
|
||||
if (asset.Size == 0)
|
||||
return "--";
|
||||
return EditorUtility.FormatBytes(asset.Size);
|
||||
}
|
||||
|
||||
private void CopyAddressPath(object context)
|
||||
{
|
||||
if (context is List<int> selectedNodes && selectedNodes.Count > 0)
|
||||
{
|
||||
TreeViewItem item = FindItem(selectedNodes[0], rootItem);
|
||||
if (item is AssetTreeViewItem assetTreeViewItem)
|
||||
{
|
||||
EditUtil.CopyToClipBoard(assetTreeViewItem.Asset.Address);
|
||||
Debug.Log($"copy success:{assetTreeViewItem.Asset.Address}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyPath(object context)
|
||||
{
|
||||
if (context is List<int> selectedNodes && selectedNodes.Count > 0)
|
||||
{
|
||||
TreeViewItem item = FindItem(selectedNodes[0], rootItem);
|
||||
if (item is AssetTreeViewItem assetTreeViewItem)
|
||||
{
|
||||
EditUtil.CopyToClipBoard(assetTreeViewItem.Asset.Path);
|
||||
Debug.Log($"copy success:{assetTreeViewItem.Asset.Path}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b65c85668d04d64aca7657c2305fd32
|
||||
timeCreated: 1679386505
|
||||
@@ -0,0 +1,168 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public class GroupInfoGUI
|
||||
{
|
||||
private bool _groupBaseInfoFold = true;
|
||||
|
||||
private bool _groupCollectorsInfoFold = true;
|
||||
Vector2 _collectorsScrollPos;
|
||||
private CollectorWindow _window;
|
||||
private LabelGUI _labelGUI;
|
||||
|
||||
public GroupInfoGUI(CollectorWindow window)
|
||||
{
|
||||
_window = window;
|
||||
}
|
||||
|
||||
public void OnGUI(Rect rect)
|
||||
{
|
||||
if (_window == null) return;
|
||||
GUILayout.BeginArea(rect);
|
||||
if (_window.SelectGroupConfig == null)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField(Language.NoSelectGroup);
|
||||
GUILayout.EndArea();
|
||||
return;
|
||||
}
|
||||
|
||||
DrawInfo();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.Space();
|
||||
|
||||
DrawCollectors();
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
void DrawInfo()
|
||||
{
|
||||
GUI.color = new Color(0, 0, 0, 0.2f);
|
||||
GUILayout.BeginHorizontal(Styles.headerBoxStyle);
|
||||
GUI.color = Color.white;
|
||||
GUILayout.Label(
|
||||
$"<b><size=18>{(_groupBaseInfoFold ? "▼" : "▶")} 【{_window.SelectGroupConfig.Name}】 基础信息</size></b>");
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
var lastRect = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.MouseDown && lastRect.Contains(Event.current.mousePosition))
|
||||
{
|
||||
_groupBaseInfoFold = !_groupBaseInfoFold;
|
||||
Event.current.Use();
|
||||
}
|
||||
|
||||
if (!_groupBaseInfoFold) return;
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (GUITools.EnumGUILayout(Language.GroupBundleMode, _window.SelectGroupConfig, "BundleMode"))
|
||||
{
|
||||
_window.UpdateAssets();
|
||||
}
|
||||
|
||||
if (GUITools.EnumGUILayout(Language.GroupAddressMode, _window.SelectGroupConfig, "AddressMode"))
|
||||
{
|
||||
_window.UpdateAssets();
|
||||
}
|
||||
|
||||
|
||||
var newFilter =
|
||||
(FilterEnum)EditorGUILayout.EnumPopup(Language.Filter, _window.SelectGroupConfig.FilterEnum);
|
||||
|
||||
if (newFilter != _window.SelectGroupConfig.FilterEnum)
|
||||
{
|
||||
_window.SelectGroupConfig.FilterEnum = newFilter;
|
||||
|
||||
_window.UpdateAssets();
|
||||
}
|
||||
|
||||
if (_window.SelectGroupConfig.FilterEnum == FilterEnum.Custom)
|
||||
{
|
||||
var newField =
|
||||
EditorGUILayout.TextField(Language.FilterCustom, _window.SelectGroupConfig.Filter);
|
||||
if (newField != _window.SelectGroupConfig.Filter)
|
||||
{
|
||||
_window.SelectGroupConfig.Filter = newField;
|
||||
_window.UpdateAssets();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DrawLabels();
|
||||
}
|
||||
|
||||
void DrawLabels()
|
||||
{
|
||||
if (_labelGUI == null)
|
||||
{
|
||||
_labelGUI = new LabelGUI();
|
||||
}
|
||||
|
||||
_labelGUI?.OnGUI(_window.SelectGroupConfig);
|
||||
// if (_labelGUI != null && _labelGUI.Lable != _window.SelectGroupConfig.Tags)
|
||||
// {
|
||||
// _window.SelectGroupConfig.Tags = _labelGUI.Lable;
|
||||
// }
|
||||
}
|
||||
|
||||
void DrawCollectors()
|
||||
{
|
||||
GUI.color = new Color(0, 0, 0, 0.2f);
|
||||
GUILayout.BeginHorizontal(Styles.headerBoxStyle);
|
||||
GUI.color = Color.white;
|
||||
GUILayout.Label(
|
||||
$"<b><size=18>{(_groupCollectorsInfoFold ? "▼" : "▶")} 【{_window.SelectGroupConfig.Name}】 收集源 ({_window.SelectGroupConfig.Collectors.Count})</size></b>");
|
||||
GUI.backgroundColor = default(Color);
|
||||
if (GUILayout.Button(Styles.Add, GUILayout.Width(40)))
|
||||
{
|
||||
_window.SelectGroupConfig.Collectors.Add(null);
|
||||
}
|
||||
|
||||
GUI.backgroundColor = Color.white;
|
||||
GUILayout.EndHorizontal();
|
||||
var lastRect = GUILayoutUtility.GetLastRect();
|
||||
if (Event.current.type == EventType.MouseDown && lastRect.Contains(Event.current.mousePosition))
|
||||
{
|
||||
_groupCollectorsInfoFold = !_groupCollectorsInfoFold;
|
||||
Event.current.Use();
|
||||
}
|
||||
|
||||
if (!_groupCollectorsInfoFold) return;
|
||||
EditorGUILayout.Space();
|
||||
|
||||
_collectorsScrollPos = EditorGUILayout.BeginScrollView(_collectorsScrollPos);
|
||||
|
||||
if (_window.SelectGroupConfig.Collectors == null)
|
||||
{
|
||||
_window.SelectGroupConfig.Collectors = new List<Object>();
|
||||
}
|
||||
|
||||
for (int i = 0; i < _window.SelectGroupConfig.Collectors.Count; i++)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label(string.Format(Language.CollectorTitle, i), GUILayout.Width(60));
|
||||
var collector = _window.SelectGroupConfig.Collectors[i];
|
||||
var newObj = EditorGUILayout.ObjectField("", collector, typeof(Object), false);
|
||||
if (newObj != collector)
|
||||
{
|
||||
_window.SelectGroupConfig.Collectors[i] = newObj;
|
||||
_window.UpdateAssets();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("-", GUILayout.Width(20)))
|
||||
{
|
||||
_window.SelectGroupConfig.Collectors.RemoveAt(i);
|
||||
_window.UpdateAssets();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bafa30ca55c64371b097be0fc2dbfaf8
|
||||
timeCreated: 1679468108
|
||||
@@ -0,0 +1,375 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public class GroupTreeViewItem : TreeViewItem
|
||||
{
|
||||
private GroupConfig _group;
|
||||
|
||||
public GroupConfig GroupConfig => _group;
|
||||
|
||||
public GroupTreeViewItem(int id, GroupConfig group) : base(id, id, group.Name)
|
||||
{
|
||||
_group = group;
|
||||
}
|
||||
}
|
||||
|
||||
public class GroupTreeEditor : TreeView
|
||||
{
|
||||
public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState()
|
||||
{
|
||||
return new MultiColumnHeaderState(GetColumns());
|
||||
}
|
||||
|
||||
private static MultiColumnHeaderState.Column[] GetColumns()
|
||||
{
|
||||
List<MultiColumnHeaderState.Column> retVal = new List<MultiColumnHeaderState.Column>();
|
||||
var fist = EditUtil.GetMultiColumnHeaderColumn(Language.AssetGroupName);
|
||||
retVal.Add(fist);
|
||||
return retVal.ToArray();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当前选中了
|
||||
/// </summary>
|
||||
private bool mContextOnItem = false;
|
||||
|
||||
CollectorWindow m_Window;
|
||||
public MultiColumnHeaderState HeaderState;
|
||||
|
||||
public GroupTreeEditor(TreeViewState state, CollectorWindow window, MultiColumnHeaderState header)
|
||||
: base(state, new MultiColumnHeader(header))
|
||||
{
|
||||
showBorder = true;
|
||||
HeaderState = header;
|
||||
showAlternatingRowBackgrounds = false;
|
||||
m_Window = window;
|
||||
Refresh();
|
||||
Reload();
|
||||
}
|
||||
|
||||
|
||||
private TreeViewItem mRoot = null;
|
||||
|
||||
protected override TreeViewItem BuildRoot()
|
||||
{
|
||||
mRoot = new TreeViewItem
|
||||
{
|
||||
id = -1,
|
||||
depth = -1,
|
||||
children = new List<TreeViewItem>()
|
||||
};
|
||||
int id = 0;
|
||||
var package = m_Window.SelectPackageConfig;
|
||||
if (package != null && package.Groups.Count > 0)
|
||||
{
|
||||
foreach (var group in package.Groups)
|
||||
{
|
||||
id++;
|
||||
var t = new GroupTreeViewItem(id, group);
|
||||
mRoot.AddChild(t);
|
||||
}
|
||||
}
|
||||
|
||||
return mRoot;
|
||||
}
|
||||
|
||||
internal void Refresh()
|
||||
{
|
||||
var selection = GetSelection();
|
||||
|
||||
SelectionChanged(selection);
|
||||
}
|
||||
|
||||
private void ReloadAndSelect(IList<int> hashCodes)
|
||||
{
|
||||
Reload();
|
||||
SetSelection(hashCodes, TreeViewSelectionOptions.RevealAndFrame);
|
||||
SelectionChanged(hashCodes);
|
||||
}
|
||||
|
||||
#region 绘制
|
||||
|
||||
public override void OnGUI(Rect rect)
|
||||
{
|
||||
base.OnGUI(rect);
|
||||
HeaderState.AutoWidth(rect.width);
|
||||
if (Event.current.type == EventType.MouseDown && Event.current.button == 0 &&
|
||||
rect.Contains(Event.current.mousePosition))
|
||||
{
|
||||
SetSelection(Array.Empty<int>(), TreeViewSelectionOptions.FireSelectionChanged);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绘制行
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
protected override void RowGUI(RowGUIArgs args)
|
||||
{
|
||||
for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
|
||||
{
|
||||
CellGUI(args.GetCellRect(i), args.item, args.GetColumn(i), ref args);
|
||||
}
|
||||
}
|
||||
|
||||
private void CellGUI(Rect cellRect, TreeViewItem item, int column, ref RowGUIArgs args)
|
||||
{
|
||||
if (item is GroupTreeViewItem groupTreeViewItem)
|
||||
{
|
||||
Color oldColor = GUI.color;
|
||||
if (!groupTreeViewItem.GroupConfig.Enable)
|
||||
{
|
||||
GUI.color = Color.gray;
|
||||
}
|
||||
|
||||
CenterRectUsingSingleLineHeight(ref cellRect);
|
||||
if (column == 0)
|
||||
{
|
||||
var iconRect = new Rect(cellRect.x + 4, cellRect.y + 1, cellRect.height - 2, cellRect.height - 2);
|
||||
GUI.DrawTexture(iconRect, Styles.Group, ScaleMode.ScaleToFit);
|
||||
|
||||
var nameRect = new Rect(cellRect.x + iconRect.xMax + 1, cellRect.y, cellRect.width - iconRect.width,
|
||||
cellRect.height);
|
||||
DefaultGUI.Label(nameRect, item.displayName, args.selected, args.focused);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 接口实现
|
||||
|
||||
/// <summary>
|
||||
/// 是否能多选
|
||||
/// </summary>
|
||||
/// <param name="item">选中的文件</param>
|
||||
/// <returns></returns>
|
||||
protected override bool CanMultiSelect(TreeViewItem item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 能否重新命名
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
protected override bool CanRename(TreeViewItem item)
|
||||
{
|
||||
return item.displayName.Length > 0;
|
||||
}
|
||||
|
||||
protected override Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item)
|
||||
{
|
||||
return rowRect;
|
||||
}
|
||||
|
||||
protected override float GetCustomRowHeight(int row, TreeViewItem item)
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 事件回调
|
||||
|
||||
/// <summary>
|
||||
/// 更改名称完成
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
protected override void RenameEnded(RenameEndedArgs args)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(args.newName) && args.newName != args.originalName)
|
||||
{
|
||||
if (NameIsOnly(args.newName))
|
||||
{
|
||||
var group = m_Window.SelectPackageConfig.Groups[args.itemID - 1];
|
||||
if (group.Name == args.originalName)
|
||||
{
|
||||
group.Name = args.newName;
|
||||
}
|
||||
|
||||
Reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError(Language.RepetitiveName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args.acceptedRename = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SelectionChanged(IList<int> selectedIds)
|
||||
{
|
||||
var selectedBundles = new List<string>();
|
||||
foreach (var id in selectedIds)
|
||||
{
|
||||
var item = FindItem(id, rootItem);
|
||||
if (item != null)
|
||||
selectedBundles.Add(item.displayName);
|
||||
}
|
||||
|
||||
m_Window.UpdateSelectedGroup(selectedBundles.Count > 0 ? selectedBundles[0] : string.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 菜单事件
|
||||
|
||||
/// <summary>
|
||||
/// 点击的时候
|
||||
/// </summary>
|
||||
protected override void ContextClicked()
|
||||
{
|
||||
if (HasSelection())
|
||||
{
|
||||
mContextOnItem = false;
|
||||
return;
|
||||
}
|
||||
|
||||
GenericMenu menu = new GenericMenu();
|
||||
menu.AddItem(new GUIContent(Language.AddGroup), false, CreateResGroup, null);
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
protected override void ContextClickedItem(int id)
|
||||
{
|
||||
if (mContextOnItem)
|
||||
{
|
||||
mContextOnItem = false;
|
||||
return;
|
||||
}
|
||||
|
||||
mContextOnItem = true;
|
||||
List<int> selectedNodes = new List<int>();
|
||||
foreach (var nodeID in GetSelection())
|
||||
{
|
||||
selectedNodes.Add(nodeID);
|
||||
}
|
||||
|
||||
GenericMenu menu = new GenericMenu();
|
||||
if (selectedNodes.Count == 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
var index = selectedNodes[0] - 1;
|
||||
var package = m_Window.SelectPackageConfig.Groups[index];
|
||||
menu.AddItem(new GUIContent(package.Enable ? Language.Disable : Language.Enable), false,
|
||||
ChangeEnable,
|
||||
selectedNodes);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
|
||||
menu.AddItem(new GUIContent(Language.ReName), false, RenameGroupName, selectedNodes);
|
||||
menu.AddItem(new GUIContent(Language.Del), false, DeleteGroups, selectedNodes);
|
||||
}
|
||||
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
protected override void KeyEvent()
|
||||
{
|
||||
if (Event.current.keyCode == KeyCode.Delete && GetSelection().Count > 0)
|
||||
{
|
||||
var list = GetSelection();
|
||||
DeleteGroups(list.ToList());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ChangeEnable(object b)
|
||||
{
|
||||
if (b is List<int> selectedNodes)
|
||||
{
|
||||
var groups = m_Window.SelectPackageConfig.Groups;
|
||||
foreach (var id in selectedNodes)
|
||||
{
|
||||
var pack = groups[id - 1];
|
||||
pack.Enable = !pack.Enable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CreateResGroup(object context)
|
||||
{
|
||||
var group = new GroupConfig
|
||||
{
|
||||
Name = GetOnlyName()
|
||||
};
|
||||
m_Window.SelectPackageConfig.Groups.Add(group);
|
||||
var id = m_Window.SelectPackageConfig.Groups.Count;
|
||||
ReloadAndSelect(new List<int>() { id });
|
||||
}
|
||||
|
||||
void DeleteGroups(object b)
|
||||
{
|
||||
if (b is List<int> selectedNodes)
|
||||
{
|
||||
foreach (var i in selectedNodes)
|
||||
{
|
||||
var index = i - 1;
|
||||
m_Window.SelectPackageConfig.Groups.RemoveAt(index);
|
||||
}
|
||||
|
||||
Reload();
|
||||
m_Window.UpdateSelectedGroup(string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
void RenameGroupName(object context)
|
||||
{
|
||||
if (context is List<int> selectedNodes && selectedNodes.Count > 0)
|
||||
{
|
||||
TreeViewItem item = FindItem(selectedNodes[0], rootItem);
|
||||
BeginRename(item, 0.25f);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 工具方法
|
||||
|
||||
bool NameIsOnly(string name)
|
||||
{
|
||||
foreach (var group in m_Window.SelectPackageConfig.Groups)
|
||||
{
|
||||
if (group.Name == name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string GetOnlyName()
|
||||
{
|
||||
var index = m_Window.SelectPackageConfig.Groups.Count;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var name = $"group{index + i}";
|
||||
if (NameIsOnly(name))
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return $"group{DateTimeOffset.Now.ToUnixTimeSeconds()}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ac8a0e5654140f2a53b3c6ad600f51e
|
||||
timeCreated: 1679368950
|
||||
@@ -0,0 +1,399 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public class PackageTreeViewItem : TreeViewItem
|
||||
{
|
||||
private PackageConfig _package;
|
||||
|
||||
public PackageConfig Package => _package;
|
||||
|
||||
public PackageTreeViewItem(int id, PackageConfig package) : base(id, id, package.Name)
|
||||
{
|
||||
_package = package;
|
||||
}
|
||||
}
|
||||
|
||||
public class PackageTreeEditor : TreeView
|
||||
{
|
||||
public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState()
|
||||
{
|
||||
return new MultiColumnHeaderState(GetColumns());
|
||||
}
|
||||
|
||||
private static MultiColumnHeaderState.Column[] GetColumns()
|
||||
{
|
||||
List<MultiColumnHeaderState.Column> retVal = new List<MultiColumnHeaderState.Column>();
|
||||
var fist = EditUtil.GetMultiColumnHeaderColumn(Language.AssetPackageName);
|
||||
retVal.Add(fist);
|
||||
return retVal.ToArray();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当前选中了
|
||||
/// </summary>
|
||||
private bool mContextOnItem = false;
|
||||
|
||||
CollectorWindow m_Window;
|
||||
public MultiColumnHeaderState HeaderState;
|
||||
public PackageTreeEditor(TreeViewState state, CollectorWindow window, MultiColumnHeaderState header)
|
||||
: base(state, new MultiColumnHeader(header))
|
||||
{
|
||||
showBorder = true;
|
||||
HeaderState = header;
|
||||
showAlternatingRowBackgrounds = false;
|
||||
m_Window = window;
|
||||
Refresh();
|
||||
Reload();
|
||||
}
|
||||
|
||||
|
||||
private TreeViewItem mRoot = null;
|
||||
|
||||
protected override TreeViewItem BuildRoot()
|
||||
{
|
||||
mRoot = new TreeViewItem
|
||||
{
|
||||
id = -1,
|
||||
depth = -1,
|
||||
children = new List<TreeViewItem>()
|
||||
};
|
||||
int id = 0;
|
||||
var packages = CollectorSetting.Instance.Packages;
|
||||
foreach (var package in packages)
|
||||
{
|
||||
id++;
|
||||
var t = new PackageTreeViewItem(id, package);
|
||||
mRoot.AddChild(t);
|
||||
}
|
||||
|
||||
return mRoot;
|
||||
}
|
||||
|
||||
internal void Refresh()
|
||||
{
|
||||
var selection = GetSelection();
|
||||
|
||||
SelectionChanged(selection);
|
||||
}
|
||||
|
||||
private void ReloadAndSelect(IList<int> hashCodes)
|
||||
{
|
||||
Reload();
|
||||
SetSelection(hashCodes, TreeViewSelectionOptions.RevealAndFrame);
|
||||
SelectionChanged(hashCodes);
|
||||
}
|
||||
|
||||
#region 绘制
|
||||
|
||||
public override void OnGUI(Rect rect)
|
||||
{
|
||||
base.OnGUI(rect);
|
||||
HeaderState.AutoWidth(rect.width);
|
||||
if (Event.current.type == EventType.MouseDown && Event.current.button == 0 &&
|
||||
rect.Contains(Event.current.mousePosition))
|
||||
{
|
||||
SetSelection(Array.Empty<int>(), TreeViewSelectionOptions.FireSelectionChanged);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绘制行
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
protected override void RowGUI(RowGUIArgs args)
|
||||
{
|
||||
for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
|
||||
{
|
||||
CellGUI(args.GetCellRect(i), args.item, args.GetColumn(i), ref args);
|
||||
}
|
||||
}
|
||||
|
||||
private void CellGUI(Rect cellRect, TreeViewItem item, int column, ref RowGUIArgs args)
|
||||
{
|
||||
if (item is PackageTreeViewItem packageTreeViewItem)
|
||||
{
|
||||
Color oldColor = GUI.color;
|
||||
if (!packageTreeViewItem.Package.Enable)
|
||||
{
|
||||
GUI.color = Color.gray;
|
||||
}
|
||||
|
||||
CenterRectUsingSingleLineHeight(ref cellRect);
|
||||
if (column == 0)
|
||||
{
|
||||
var iconRect = new Rect(cellRect.x + 4, cellRect.y + 1, cellRect.height - 2, cellRect.height - 2);
|
||||
var icon = packageTreeViewItem.Package.Default ? Styles.Package : Styles.PackageLow;
|
||||
GUI.DrawTexture(iconRect, icon, ScaleMode.ScaleToFit);
|
||||
|
||||
var nameRect = new Rect(cellRect.x + iconRect.xMax + 1, cellRect.y, cellRect.width - iconRect.width,
|
||||
cellRect.height);
|
||||
if (packageTreeViewItem.Package.Default)
|
||||
{
|
||||
DefaultGUI.BoldLabel(nameRect, item.displayName, args.selected, args.focused);
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultGUI.Label(nameRect, item.displayName, args.selected, args.focused);
|
||||
}
|
||||
}
|
||||
|
||||
GUI.color = oldColor;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 接口实现
|
||||
|
||||
/// <summary>
|
||||
/// 是否能多选
|
||||
/// </summary>
|
||||
/// <param name="item">选中的文件</param>
|
||||
/// <returns></returns>
|
||||
protected override bool CanMultiSelect(TreeViewItem item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 能否重新命名
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
protected override bool CanRename(TreeViewItem item)
|
||||
{
|
||||
return item.displayName.Length > 0;
|
||||
}
|
||||
|
||||
protected override Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item)
|
||||
{
|
||||
return rowRect;
|
||||
}
|
||||
|
||||
protected override float GetCustomRowHeight(int row, TreeViewItem item)
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 事件回调
|
||||
|
||||
/// <summary>
|
||||
/// 更改名称完成
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
protected override void RenameEnded(RenameEndedArgs args)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(args.newName) && args.newName != args.originalName)
|
||||
{
|
||||
if (NameIsOnly(args.newName))
|
||||
{
|
||||
var packages = CollectorSetting.Instance.Packages;
|
||||
var package = packages[args.itemID - 1];
|
||||
if (package.Name == args.originalName)
|
||||
{
|
||||
package.Name = args.newName;
|
||||
}
|
||||
|
||||
Reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError(Language.RepetitiveName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args.acceptedRename = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SelectionChanged(IList<int> selectedIds)
|
||||
{
|
||||
var selectedBundles = new List<string>();
|
||||
foreach (var id in selectedIds)
|
||||
{
|
||||
var item = FindItem(id, rootItem);
|
||||
if (item != null)
|
||||
selectedBundles.Add(item.displayName);
|
||||
}
|
||||
|
||||
m_Window.UpdateSelectedPackage(selectedBundles.Count > 0 ? selectedBundles[0] : string.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 菜单事件
|
||||
|
||||
/// <summary>
|
||||
/// 点击的时候
|
||||
/// </summary>
|
||||
protected override void ContextClicked()
|
||||
{
|
||||
if (HasSelection())
|
||||
{
|
||||
mContextOnItem = false;
|
||||
return;
|
||||
}
|
||||
|
||||
GenericMenu menu = new GenericMenu();
|
||||
menu.AddItem(new GUIContent(Language.AddPackage), false, CreateResGroup, null);
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
protected override void ContextClickedItem(int id)
|
||||
{
|
||||
if (mContextOnItem)
|
||||
{
|
||||
mContextOnItem = false;
|
||||
return;
|
||||
}
|
||||
|
||||
mContextOnItem = true;
|
||||
List<int> selectedNodes = new List<int>();
|
||||
foreach (var nodeID in GetSelection())
|
||||
{
|
||||
selectedNodes.Add(nodeID);
|
||||
}
|
||||
|
||||
GenericMenu menu = new GenericMenu();
|
||||
if (selectedNodes.Count == 1)
|
||||
{
|
||||
menu.AddItem(new GUIContent(Language.AddGroup), false, CreateResGroup, null);
|
||||
try
|
||||
{
|
||||
var index = selectedNodes[0] - 1;
|
||||
var package = CollectorSetting.Instance.Packages[index];
|
||||
menu.AddItem(new GUIContent(package.Enable ? Language.Disable : Language.Enable), false,
|
||||
ChangeEnable,
|
||||
selectedNodes);
|
||||
|
||||
var str = package.Default ? Language.DisableDefPackage : Language.EnableDefPackage;
|
||||
menu.AddItem(new GUIContent(str), false, ChangeDefPackage, selectedNodes);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
|
||||
menu.AddItem(new GUIContent(Language.ReName), false, RenameGroupName, selectedNodes);
|
||||
menu.AddItem(new GUIContent(Language.Del), false, DeleteGroups, selectedNodes);
|
||||
}
|
||||
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
protected override void KeyEvent()
|
||||
{
|
||||
if (Event.current.keyCode == KeyCode.Delete && GetSelection().Count > 0)
|
||||
{
|
||||
var list = GetSelection();
|
||||
DeleteGroups(list.ToList());
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeDefPackage(object b)
|
||||
{
|
||||
if (b is List<int> selectedNodes)
|
||||
{
|
||||
var packages = CollectorSetting.Instance.Packages;
|
||||
foreach (var id in selectedNodes)
|
||||
{
|
||||
var pack = packages[id - 1];
|
||||
pack.Default = !pack.Default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeEnable(object b)
|
||||
{
|
||||
if (b is List<int> selectedNodes)
|
||||
{
|
||||
var packages = CollectorSetting.Instance.Packages;
|
||||
foreach (var id in selectedNodes)
|
||||
{
|
||||
var pack = packages[id - 1];
|
||||
pack.Enable = !pack.Enable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CreateResGroup(object context)
|
||||
{
|
||||
var package = new PackageConfig()
|
||||
{
|
||||
Name = GetOnlyName()
|
||||
};
|
||||
CollectorSetting.Instance.Packages.Add(package);
|
||||
var id = CollectorSetting.Instance.Packages.Count;
|
||||
ReloadAndSelect(new List<int>() { id });
|
||||
}
|
||||
|
||||
void DeleteGroups(object b)
|
||||
{
|
||||
if (b is List<int> selectedNodes)
|
||||
{
|
||||
foreach (var i in selectedNodes)
|
||||
{
|
||||
var index = i - 1;
|
||||
CollectorSetting.Instance.Packages.RemoveAt(index);
|
||||
}
|
||||
|
||||
ReloadAndSelect(new List<int>());
|
||||
m_Window.UpdateSelectedPackage(string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
void RenameGroupName(object context)
|
||||
{
|
||||
if (context is List<int> selectedNodes && selectedNodes.Count > 0)
|
||||
{
|
||||
TreeViewItem item = FindItem(selectedNodes[0], rootItem);
|
||||
BeginRename(item, 0.25f);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 工具方法
|
||||
|
||||
bool NameIsOnly(string name)
|
||||
{
|
||||
var packages = CollectorSetting.Instance.Packages;
|
||||
foreach (var package in packages)
|
||||
{
|
||||
if (package.Name == name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string GetOnlyName()
|
||||
{
|
||||
var index = CollectorSetting.Instance.Packages.Count;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var name = $"package{index + i}";
|
||||
if (NameIsOnly(name))
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return $"package{DateTimeOffset.Now.ToUnixTimeSeconds()}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d89d8be5d8fb487aa4f5c21469255890
|
||||
timeCreated: 1679369408
|
||||
3
Assets/Scripts/NBC/Asset/Editor/GUI/Commom.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/GUI/Commom.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c44a0a8c03cb4b6796415eace15ed796
|
||||
timeCreated: 1679993913
|
||||
103
Assets/Scripts/NBC/Asset/Editor/GUI/Commom/Splitter.cs
Normal file
103
Assets/Scripts/NBC/Asset/Editor/GUI/Commom/Splitter.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class VerticalSplitter
|
||||
{
|
||||
[NonSerialized] Rect m_Rect = new Rect(0, 0, 0, 3);
|
||||
public Rect SplitterRect => m_Rect;
|
||||
|
||||
[FormerlySerializedAs("m_currentPercent")] [SerializeField]
|
||||
float m_CurrentPercent;
|
||||
|
||||
bool m_Resizing;
|
||||
float m_MinPercent;
|
||||
float m_MaxPercent;
|
||||
|
||||
public VerticalSplitter(float percent = .6f, float minPer = .4f, float maxPer = .9f)
|
||||
{
|
||||
m_CurrentPercent = percent;
|
||||
m_MinPercent = minPer;
|
||||
m_MaxPercent = maxPer;
|
||||
}
|
||||
|
||||
public bool OnGUI(Rect content, out Rect top, out Rect bot)
|
||||
{
|
||||
m_Rect.x = content.x;
|
||||
m_Rect.y = (int)(content.y + content.height * m_CurrentPercent);
|
||||
m_Rect.width = content.width;
|
||||
|
||||
EditorGUIUtility.AddCursorRect(m_Rect, MouseCursor.ResizeVertical);
|
||||
if (Event.current.type == EventType.MouseDown && m_Rect.Contains(Event.current.mousePosition))
|
||||
m_Resizing = true;
|
||||
|
||||
if (m_Resizing)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(content, MouseCursor.ResizeVertical);
|
||||
|
||||
var mousePosInRect = Event.current.mousePosition.y - content.y;
|
||||
m_CurrentPercent = Mathf.Clamp(mousePosInRect / content.height, m_MinPercent, m_MaxPercent);
|
||||
m_Rect.y = Mathf.Min((int)(content.y + content.height * m_CurrentPercent),
|
||||
content.yMax - m_Rect.height);
|
||||
if (Event.current.type == EventType.MouseUp)
|
||||
m_Resizing = false;
|
||||
}
|
||||
|
||||
top = new Rect(content.x, content.y, content.width, m_Rect.yMin - content.yMin);
|
||||
bot = new Rect(content.x, m_Rect.yMax, content.width, content.yMax - m_Rect.yMax);
|
||||
return m_Resizing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class HorizontalSplitter
|
||||
{
|
||||
[NonSerialized] Rect m_Rect = new Rect(0, 0, 3, 0);
|
||||
|
||||
public Rect SplitterRect => m_Rect;
|
||||
|
||||
[FormerlySerializedAs("m_currentPercent")] [SerializeField]
|
||||
float m_CurrentPercent;
|
||||
|
||||
bool m_Resizing;
|
||||
float m_MinPercent;
|
||||
float m_MaxPercent;
|
||||
|
||||
public HorizontalSplitter(float percent = .6f, float minPer = .4f, float maxPer = .9f)
|
||||
{
|
||||
m_CurrentPercent = percent;
|
||||
m_MinPercent = minPer;
|
||||
m_MaxPercent = maxPer;
|
||||
}
|
||||
|
||||
public bool OnGUI(Rect content, out Rect left, out Rect right)
|
||||
{
|
||||
m_Rect.y = content.y;
|
||||
m_Rect.x = (int)(content.x + content.width * m_CurrentPercent);
|
||||
m_Rect.height = content.height;
|
||||
|
||||
EditorGUIUtility.AddCursorRect(m_Rect, MouseCursor.ResizeHorizontal);
|
||||
if (Event.current.type == EventType.MouseDown && m_Rect.Contains(Event.current.mousePosition))
|
||||
m_Resizing = true;
|
||||
|
||||
if (m_Resizing)
|
||||
{
|
||||
EditorGUIUtility.AddCursorRect(content, MouseCursor.ResizeHorizontal);
|
||||
|
||||
var mousePosInRect = Event.current.mousePosition.x - content.x;
|
||||
m_CurrentPercent = Mathf.Clamp(mousePosInRect / content.width, m_MinPercent, m_MaxPercent);
|
||||
m_Rect.x = Mathf.Min((int)(content.x + content.width * m_CurrentPercent), content.xMax - m_Rect.width);
|
||||
if (Event.current.type == EventType.MouseUp)
|
||||
m_Resizing = false;
|
||||
}
|
||||
left = new Rect(content.x, content.y, content.width * m_CurrentPercent, content.height);
|
||||
right = new Rect(m_Rect.xMax, content.y, content.width - content.width * m_CurrentPercent, content.height);
|
||||
return m_Resizing;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ff764a382104fe1970089f4ae39dd83
|
||||
timeCreated: 1679805403
|
||||
3
Assets/Scripts/NBC/Asset/Editor/GUI/History.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/GUI/History.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1b3fb95b2f24d68876df91fc6676eda
|
||||
timeCreated: 1680142226
|
||||
283
Assets/Scripts/NBC/Asset/Editor/GUI/History/HistoryWindow.cs
Normal file
283
Assets/Scripts/NBC/Asset/Editor/GUI/History/HistoryWindow.cs
Normal file
@@ -0,0 +1,283 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset.Editor
|
||||
{
|
||||
public class HistoryWindow : EditorWindow
|
||||
{
|
||||
[MenuItem(Language.HistoryWindowNameMenuPath, false, 4)]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
var s = string.Empty;
|
||||
HistoryWindow wnd = GetWindow<HistoryWindow>(Language.HistoryWindowName, true, Defs.DockedWindowTypes);
|
||||
wnd.minSize = new Vector2(Defs.DefWindowWidth, Defs.DefWindowHeight);
|
||||
}
|
||||
|
||||
|
||||
const int _splitterThickness = 2;
|
||||
|
||||
public VersionHistoryData SelectVersion;
|
||||
|
||||
/// <summary>
|
||||
/// 选中需要比较的版本
|
||||
/// </summary>
|
||||
public VersionHistoryData SelectCompareVersion;
|
||||
|
||||
readonly VerticalSplitter _verticalSplitter = new VerticalSplitter(0.7f, 0.7f, 0.8f);
|
||||
readonly HorizontalSplitter _horizontalSplitter = new HorizontalSplitter(0.3f, 0.3f, 0.4f);
|
||||
|
||||
private HistoryVersionTreeEditor _versionList;
|
||||
private HistoryBundleTreeEditor _bundleTreeEditor;
|
||||
|
||||
private List<VersionHistoryData> _versionHistory = new List<VersionHistoryData>();
|
||||
|
||||
public List<VersionHistoryData> ShowVersionHistory => _versionHistory;
|
||||
|
||||
public void UpdateCompareSelectedVersion(string name)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
foreach (var version in _versionHistory)
|
||||
{
|
||||
if (version.ShowName != name) continue;
|
||||
SelectCompareVersion = version;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectCompareVersion = null;
|
||||
}
|
||||
|
||||
_versionList?.Reload();
|
||||
}
|
||||
|
||||
public void UpdateSelectedVersion(string name)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
foreach (var version in _versionHistory)
|
||||
{
|
||||
if (version.ShowName != name) continue;
|
||||
SelectVersion = version;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectVersion = null;
|
||||
}
|
||||
|
||||
_bundleTreeEditor?.Reload();
|
||||
}
|
||||
|
||||
public void ReloadVersions()
|
||||
{
|
||||
_versionHistory = HistoryUtil.GetHistoryVersions();
|
||||
if (SelectCompareVersion == null && _versionHistory.Count > 1)
|
||||
{
|
||||
SelectCompareVersion = _versionHistory[1];
|
||||
}
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
ReloadVersions();
|
||||
UpdateSelectedVersion(string.Empty);
|
||||
}
|
||||
|
||||
protected void OnEnable()
|
||||
{
|
||||
SelectVersion = null;
|
||||
SelectCompareVersion = null;
|
||||
ReloadVersions();
|
||||
Styles.Initialize();
|
||||
}
|
||||
|
||||
protected void OnGUI()
|
||||
{
|
||||
var barHeight = _splitterThickness;
|
||||
Rect contentRect = new Rect(_splitterThickness, barHeight, position.width - _splitterThickness * 4,
|
||||
position.height - _splitterThickness);
|
||||
|
||||
var resizingPackage = _horizontalSplitter.OnGUI(contentRect, out var bundleRect, out var infoRect);
|
||||
|
||||
DrawVersionList(bundleRect);
|
||||
bool resizingVer = _verticalSplitter.OnGUI(infoRect, out var top, out var bot);
|
||||
DrawBundleList(top);
|
||||
DrawCompareInfo(bot);
|
||||
if (resizingPackage || resizingVer)
|
||||
Repaint();
|
||||
}
|
||||
|
||||
|
||||
void DrawVersionList(Rect rect)
|
||||
{
|
||||
if (_versionList == null)
|
||||
{
|
||||
_versionList = new HistoryVersionTreeEditor(new TreeViewState(), this,
|
||||
HistoryVersionTreeEditor.CreateDefaultMultiColumnHeaderState());
|
||||
}
|
||||
|
||||
_versionList.OnGUI(rect);
|
||||
}
|
||||
|
||||
void DrawBundleList(Rect rect)
|
||||
{
|
||||
if (_bundleTreeEditor == null)
|
||||
{
|
||||
_bundleTreeEditor = new HistoryBundleTreeEditor(new TreeViewState(), this,
|
||||
HistoryBundleTreeEditor.CreateDefaultMultiColumnHeaderState());
|
||||
}
|
||||
|
||||
_bundleTreeEditor.OnGUI(rect);
|
||||
}
|
||||
|
||||
void DrawCompareInfo(Rect rect)
|
||||
{
|
||||
if (SelectVersion == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GUILayout.BeginArea(rect);
|
||||
|
||||
if (SelectCompareVersion == null)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField(Language.NoSelectHistoryCompareVersion);
|
||||
}
|
||||
else if (SelectCompareVersion == SelectVersion)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField(Language.NoSelectHistoryCompareOneVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawCompareDetails();
|
||||
}
|
||||
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
void DrawCompareDetails()
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
var compareInfo = HistoryUtil.CompareVersion(SelectVersion, SelectCompareVersion);
|
||||
var simpleData = compareInfo.SimpleChangeData;
|
||||
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
var strAdd = GetPackageChangeInfo(simpleData.PackageAddBundle);
|
||||
EditorGUILayout.TextField(Language.HistoryAddBundleCount, strAdd);
|
||||
if (GUILayout.Button(Language.Copy, GUILayout.Width(50)))
|
||||
{
|
||||
EditUtil.CopyToClipBoard(strAdd);
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
var strChange = GetPackageChangeInfo(simpleData.PackageChangeBundle);
|
||||
EditorGUILayout.TextField(Language.HistoryChangeBundleCount, strChange);
|
||||
if (GUILayout.Button(Language.Copy, GUILayout.Width(50)))
|
||||
{
|
||||
EditUtil.CopyToClipBoard(strChange);
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
var strRemove = GetPackageChangeInfo(simpleData.PackageRemoveBundle);
|
||||
EditorGUILayout.TextField(Language.HistoryRemoveBundleCount, strRemove);
|
||||
if (GUILayout.Button(Language.Copy, GUILayout.Width(50)))
|
||||
{
|
||||
EditUtil.CopyToClipBoard(strRemove);
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
var strDownload = GetPackageDownloadInfo(simpleData.PackageDownloadSize);
|
||||
EditorGUILayout.TextField(Language.HistoryDownloadSize, strDownload);
|
||||
if (GUILayout.Button(Language.Copy, GUILayout.Width(50)))
|
||||
{
|
||||
EditUtil.CopyToClipBoard(strDownload);
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
|
||||
EditorGUILayout.Space();
|
||||
if (GUILayout.Button(Language.HistoryCompareBuild, GUILayout.Height(40)))
|
||||
{
|
||||
var saveJson =
|
||||
JsonConvert.SerializeObject(compareInfo,
|
||||
Formatting.Indented); //JsonUtility.ToJson(compareInfo, true);
|
||||
|
||||
var saveFolder =
|
||||
EditorUtility.OpenFolderPanel(Language.BuildProfilerTips, Environment.CurrentDirectory, "");
|
||||
|
||||
|
||||
var savePath = $"{saveFolder}/history_compare_{DateTime.Now.ToString("yyyyMMddHHmmss")}.json";
|
||||
File.WriteAllText(savePath, saveJson);
|
||||
EditorUtility.DisplayDialog(Language.Tips, Language.Success + $", path={savePath}", Language.Confirm);
|
||||
}
|
||||
}
|
||||
|
||||
string GetPackageChangeInfo(Dictionary<string, List<string>> dictionary)
|
||||
{
|
||||
var all = 0;
|
||||
var packageStr = "";
|
||||
var index = 0;
|
||||
foreach (var key in dictionary.Keys)
|
||||
{
|
||||
index++;
|
||||
var value = dictionary[key];
|
||||
all += value.Count;
|
||||
packageStr += $"{key}={value.Count}";
|
||||
if (index < dictionary.Count)
|
||||
{
|
||||
packageStr += "、 ";
|
||||
}
|
||||
}
|
||||
|
||||
var str = string.Format(Language.HistoryBundleChangeTitle, all, packageStr);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
string GetPackageDownloadInfo(Dictionary<string, long> dictionary)
|
||||
{
|
||||
long all = 0;
|
||||
var packageStr = "";
|
||||
var index = 0;
|
||||
foreach (var key in dictionary.Keys)
|
||||
{
|
||||
index++;
|
||||
var value = dictionary[key];
|
||||
all += value;
|
||||
packageStr += $"{key}={Util.GetFriendlySize(value)}";
|
||||
if (index < dictionary.Count)
|
||||
{
|
||||
packageStr += "、 ";
|
||||
}
|
||||
}
|
||||
|
||||
var str = string.Format(Language.HistoryBundleChangeTitle, Util.GetFriendlySize(all), packageStr);
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c688eedf74e6448b950e6975f675b3b1
|
||||
timeCreated: 1680142237
|
||||
3
Assets/Scripts/NBC/Asset/Editor/GUI/History/SubView.meta
Normal file
3
Assets/Scripts/NBC/Asset/Editor/GUI/History/SubView.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a69a28535dc4e99b1b9bdf70b380d4d
|
||||
timeCreated: 1680143027
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user