mirror of https://github.com/tuyoogame/YooAsset
Update AssetBundleGrouper
parent
1278d76f49
commit
144a2ffad8
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b19f23ac31124274d942d32bec434450
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,176 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class AssetBundleCollector
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 收集路径
|
||||||
|
/// 注意:支持文件夹或单个资源文件
|
||||||
|
/// </summary>
|
||||||
|
public string CollectPath = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 打包规则类名
|
||||||
|
/// </summary>
|
||||||
|
public string PackRuleName = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 过滤规则类名
|
||||||
|
/// </summary>
|
||||||
|
public string FilterRuleName = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 不写入资源列表
|
||||||
|
/// </summary>
|
||||||
|
public bool NotWriteToAssetList = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源分类标签
|
||||||
|
/// </summary>
|
||||||
|
public string AssetTags = string.Empty;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取打包收集的资源文件
|
||||||
|
/// </summary>
|
||||||
|
public List<CollectAssetInfo> GetAllCollectAssets(AssetBundleGrouper grouper)
|
||||||
|
{
|
||||||
|
Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(1000);
|
||||||
|
bool isRawAsset = PackRuleName == nameof(PackRawFile);
|
||||||
|
|
||||||
|
// 如果是文件夹
|
||||||
|
if (AssetDatabase.IsValidFolder(CollectPath))
|
||||||
|
{
|
||||||
|
string collectDirectory = CollectPath;
|
||||||
|
string[] findAssets = EditorTools.FindAssets(EAssetSearchType.All, collectDirectory);
|
||||||
|
foreach (string assetPath in findAssets)
|
||||||
|
{
|
||||||
|
if (IsValidateAsset(assetPath) == false)
|
||||||
|
continue;
|
||||||
|
if (IsCollectAsset(assetPath) == false)
|
||||||
|
continue;
|
||||||
|
if (result.ContainsKey(assetPath) == false)
|
||||||
|
{
|
||||||
|
string bundleName = GetBundleName(grouper, assetPath);
|
||||||
|
List<string> assetTags = GetAssetTags(grouper);
|
||||||
|
var collectAssetInfo = new CollectAssetInfo(bundleName, assetPath, assetTags, isRawAsset, NotWriteToAssetList);
|
||||||
|
collectAssetInfo.DependAssets = GetAllDependencies(assetPath);
|
||||||
|
result.Add(assetPath, collectAssetInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"The collecting asset file is existed : {assetPath} in collector : {CollectPath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string assetPath = CollectPath;
|
||||||
|
if (result.ContainsKey(assetPath) == false)
|
||||||
|
{
|
||||||
|
if (isRawAsset && NotWriteToAssetList)
|
||||||
|
UnityEngine.Debug.LogWarning($"Are you sure raw file are not write to asset list : {assetPath}");
|
||||||
|
|
||||||
|
string bundleName = GetBundleName(grouper, assetPath);
|
||||||
|
List<string> assetTags = GetAssetTags(grouper);
|
||||||
|
var collectAssetInfo = new CollectAssetInfo(bundleName, assetPath, assetTags, isRawAsset, NotWriteToAssetList);
|
||||||
|
result.Add(assetPath, collectAssetInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"The collecting asset file is existed : {assetPath} in collector : {CollectPath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回列表
|
||||||
|
return result.Values.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsValidateAsset(string assetPath)
|
||||||
|
{
|
||||||
|
if (assetPath.StartsWith("Assets/") == false && assetPath.StartsWith("Packages/") == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (AssetDatabase.IsValidFolder(assetPath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 注意:忽略编辑器下的类型资源
|
||||||
|
Type type = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
|
||||||
|
if (type == typeof(LightingDataAsset))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
string ext = System.IO.Path.GetExtension(assetPath);
|
||||||
|
if (ext == "" || ext == ".dll" || ext == ".cs" || ext == ".js" || ext == ".boo" || ext == ".meta")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
private bool IsCollectAsset(string assetPath)
|
||||||
|
{
|
||||||
|
// 如果收集全路径着色器
|
||||||
|
if (AssetBundleGrouperSettingData.Setting.AutoCollectShaders)
|
||||||
|
{
|
||||||
|
Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
|
||||||
|
if (assetType == typeof(UnityEngine.Shader))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据规则设置过滤资源文件
|
||||||
|
IFilterRule filterRuleInstance = AssetBundleGrouperSettingData.GetFilterRuleInstance(FilterRuleName);
|
||||||
|
return filterRuleInstance.IsCollectAsset(assetPath);
|
||||||
|
}
|
||||||
|
private string GetBundleName(AssetBundleGrouper grouper, string assetPath)
|
||||||
|
{
|
||||||
|
// 如果收集全路径着色器
|
||||||
|
if (AssetBundleGrouperSettingData.Setting.AutoCollectShaders)
|
||||||
|
{
|
||||||
|
System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
|
||||||
|
if (assetType == typeof(UnityEngine.Shader))
|
||||||
|
{
|
||||||
|
return RevisedBundleName(AssetBundleGrouperSettingData.Setting.ShadersBundleName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据规则设置获取资源包名称
|
||||||
|
IPackRule packRuleInstance = AssetBundleGrouperSettingData.GetPackRuleInstance(PackRuleName);
|
||||||
|
string bundleName = packRuleInstance.GetBundleName(new PackRuleData(assetPath, CollectPath, grouper.GrouperName));
|
||||||
|
return RevisedBundleName(bundleName);
|
||||||
|
}
|
||||||
|
private List<string> GetAssetTags(AssetBundleGrouper grouper)
|
||||||
|
{
|
||||||
|
List<string> tags = StringUtility.StringToStringList(grouper.AssetTags, ';');
|
||||||
|
List<string> temper = StringUtility.StringToStringList(AssetTags, ';');
|
||||||
|
tags.AddRange(temper);
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
private List<string> GetAllDependencies(string mainAssetPath)
|
||||||
|
{
|
||||||
|
List<string> result = new List<string>();
|
||||||
|
string[] depends = AssetDatabase.GetDependencies(mainAssetPath, true);
|
||||||
|
foreach (string assetPath in depends)
|
||||||
|
{
|
||||||
|
if (IsValidateAsset(assetPath))
|
||||||
|
{
|
||||||
|
// 注意:排除主资源对象
|
||||||
|
if (assetPath != mainAssetPath)
|
||||||
|
result.Add(assetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修正资源包名
|
||||||
|
/// </summary>
|
||||||
|
public static string RevisedBundleName(string bundleName)
|
||||||
|
{
|
||||||
|
return EditorTools.GetRegularPath(bundleName).ToLower();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f79866c315d53ef4480d6fa4083c09ad
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,58 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class AssetBundleGrouper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 分组名称
|
||||||
|
/// </summary>
|
||||||
|
public string GrouperName = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分组描述
|
||||||
|
/// </summary>
|
||||||
|
public string GrouperDesc = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源分类标签
|
||||||
|
/// </summary>
|
||||||
|
public string AssetTags = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分组的收集器列表
|
||||||
|
/// </summary>
|
||||||
|
public List<AssetBundleCollector> Collectors = new List<AssetBundleCollector>();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取打包收集的资源文件
|
||||||
|
/// </summary>
|
||||||
|
public List<CollectAssetInfo> GetAllCollectAssets()
|
||||||
|
{
|
||||||
|
Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(10000);
|
||||||
|
foreach(var collector in Collectors)
|
||||||
|
{
|
||||||
|
var temper = collector.GetAllCollectAssets(this);
|
||||||
|
foreach(var assetInfo in temper)
|
||||||
|
{
|
||||||
|
if(result.ContainsKey(assetInfo.AssetPath) == false)
|
||||||
|
{
|
||||||
|
result.Add(assetInfo.AssetPath, assetInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"The collecting asset file is existed : {assetInfo.AssetPath} in grouper : {GrouperName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.Values.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e9f7615a761107d4ebf96d66be2f6b45
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,17 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class AssetBundleGrouperConfigDefine
|
||||||
|
{
|
||||||
|
public const string XmlGrouper = "Grouper";
|
||||||
|
public const string XmlCollector = "Collector";
|
||||||
|
public const string XmlDirectory = "CollectPath";
|
||||||
|
public const string XmlPackRule = "PackRule";
|
||||||
|
public const string XmlFilterRule = "FilterRule";
|
||||||
|
public const string XmlNotWriteToAssetList = "NotWriteToAssetList";
|
||||||
|
public const string XmlAssetTags = "AssetTags";
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f2190cc6d8995aa458ded22ffd7fc1e0
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class AssetBundleGrouperConfigExporter
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 57959ce1a0581284c8bb37655a81dc1e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class AssetBundleGrouperConfigImporter
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f9a030381c5944145a285c3212153ceb
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,51 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class AssetBundleGrouperSetting : ScriptableObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 自动收集着色器
|
||||||
|
/// </summary>
|
||||||
|
public bool AutoCollectShaders = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自动收集的着色器资源包名称
|
||||||
|
/// </summary>
|
||||||
|
public string ShadersBundleName = "myshaders";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分组列表
|
||||||
|
/// </summary>
|
||||||
|
public List<AssetBundleGrouper> Groupers = new List<AssetBundleGrouper>();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取打包收集的资源文件
|
||||||
|
/// </summary>
|
||||||
|
public List<CollectAssetInfo> GetAllCollectAssets()
|
||||||
|
{
|
||||||
|
Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(10000);
|
||||||
|
foreach (var grouper in Groupers)
|
||||||
|
{
|
||||||
|
var temper = grouper.GetAllCollectAssets();
|
||||||
|
foreach (var assetInfo in temper)
|
||||||
|
{
|
||||||
|
if (result.ContainsKey(assetInfo.AssetPath) == false)
|
||||||
|
{
|
||||||
|
result.Add(assetInfo.AssetPath, assetInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"The collecting asset file is existed : {assetInfo.AssetPath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.Values.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 185f6993d5150494d98da50e26cb1c25
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,267 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class AssetBundleGrouperSettingData
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<string, System.Type> _cachePackRuleTypes = new Dictionary<string, System.Type>();
|
||||||
|
private static readonly Dictionary<string, IPackRule> _cachePackRuleInstance = new Dictionary<string, IPackRule>();
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, System.Type> _cacheFilterRuleTypes = new Dictionary<string, System.Type>();
|
||||||
|
private static readonly Dictionary<string, IFilterRule> _cacheFilterRuleInstance = new Dictionary<string, IFilterRule>();
|
||||||
|
|
||||||
|
|
||||||
|
private static AssetBundleGrouperSetting _setting = null;
|
||||||
|
public static AssetBundleGrouperSetting Setting
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_setting == null)
|
||||||
|
LoadSettingData();
|
||||||
|
return _setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<string> GetPackRuleNames()
|
||||||
|
{
|
||||||
|
if (_setting == null)
|
||||||
|
LoadSettingData();
|
||||||
|
|
||||||
|
List<string> names = new List<string>();
|
||||||
|
foreach (var pair in _cachePackRuleTypes)
|
||||||
|
{
|
||||||
|
names.Add(pair.Key);
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
public static List<string> GetFilterRuleNames()
|
||||||
|
{
|
||||||
|
if (_setting == null)
|
||||||
|
LoadSettingData();
|
||||||
|
|
||||||
|
List<string> names = new List<string>();
|
||||||
|
foreach (var pair in _cacheFilterRuleTypes)
|
||||||
|
{
|
||||||
|
names.Add(pair.Key);
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
public static bool HasPackRuleName(string ruleName)
|
||||||
|
{
|
||||||
|
foreach (var pair in _cachePackRuleTypes)
|
||||||
|
{
|
||||||
|
if (pair.Key == ruleName)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool HasFilterRuleName(string ruleName)
|
||||||
|
{
|
||||||
|
foreach (var pair in _cacheFilterRuleTypes)
|
||||||
|
{
|
||||||
|
if (pair.Key == ruleName)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载配置文件
|
||||||
|
/// </summary>
|
||||||
|
private static void LoadSettingData()
|
||||||
|
{
|
||||||
|
// 加载配置文件
|
||||||
|
_setting = AssetDatabase.LoadAssetAtPath<AssetBundleGrouperSetting>(EditorDefine.AssetBundleGrouperSettingFilePath);
|
||||||
|
if (_setting == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Create new {nameof(AssetBundleGrouperSetting)}.asset : {EditorDefine.AssetBundleGrouperSettingFilePath}");
|
||||||
|
_setting = ScriptableObject.CreateInstance<AssetBundleGrouperSetting>();
|
||||||
|
EditorTools.CreateFileDirectory(EditorDefine.AssetBundleGrouperSettingFilePath);
|
||||||
|
AssetDatabase.CreateAsset(Setting, EditorDefine.AssetBundleGrouperSettingFilePath);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log($"Load {nameof(AssetBundleGrouperSetting)}.asset ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPackRule
|
||||||
|
{
|
||||||
|
// 清空缓存集合
|
||||||
|
_cachePackRuleTypes.Clear();
|
||||||
|
_cachePackRuleInstance.Clear();
|
||||||
|
|
||||||
|
// 获取所有类型
|
||||||
|
List<Type> types = new List<Type>(100)
|
||||||
|
{
|
||||||
|
typeof(PackSeparately),
|
||||||
|
typeof(PackDirectory),
|
||||||
|
typeof(PackCollector),
|
||||||
|
typeof(PackGrouper),
|
||||||
|
typeof(PackRawFile),
|
||||||
|
};
|
||||||
|
var customTypes = AssemblyUtility.GetAssignableTypes(AssemblyUtility.UnityDefaultAssemblyEditorName, typeof(IPackRule));
|
||||||
|
types.AddRange(customTypes);
|
||||||
|
for (int i = 0; i < types.Count; i++)
|
||||||
|
{
|
||||||
|
Type type = types[i];
|
||||||
|
if (_cachePackRuleTypes.ContainsKey(type.Name) == false)
|
||||||
|
_cachePackRuleTypes.Add(type.Name, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IFilterRule
|
||||||
|
{
|
||||||
|
// 清空缓存集合
|
||||||
|
_cacheFilterRuleTypes.Clear();
|
||||||
|
_cacheFilterRuleInstance.Clear();
|
||||||
|
|
||||||
|
// 获取所有类型
|
||||||
|
List<Type> types = new List<Type>(100)
|
||||||
|
{
|
||||||
|
typeof(CollectAll),
|
||||||
|
typeof(CollectScene),
|
||||||
|
typeof(CollectPrefab),
|
||||||
|
typeof(CollectSprite)
|
||||||
|
};
|
||||||
|
var customTypes = AssemblyUtility.GetAssignableTypes(AssemblyUtility.UnityDefaultAssemblyEditorName, typeof(IFilterRule));
|
||||||
|
types.AddRange(customTypes);
|
||||||
|
for (int i = 0; i < types.Count; i++)
|
||||||
|
{
|
||||||
|
Type type = types[i];
|
||||||
|
if (_cacheFilterRuleTypes.ContainsKey(type.Name) == false)
|
||||||
|
_cacheFilterRuleTypes.Add(type.Name, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 存储文件
|
||||||
|
/// </summary>
|
||||||
|
public static void SaveFile()
|
||||||
|
{
|
||||||
|
if (Setting != null)
|
||||||
|
{
|
||||||
|
EditorUtility.SetDirty(Setting);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空所有数据
|
||||||
|
/// </summary>
|
||||||
|
public static void ClearAll()
|
||||||
|
{
|
||||||
|
Setting.AutoCollectShaders = false;
|
||||||
|
Setting.ShadersBundleName = string.Empty;
|
||||||
|
Setting.Groupers.Clear();
|
||||||
|
SaveFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实例类相关
|
||||||
|
public static IPackRule GetPackRuleInstance(string ruleName)
|
||||||
|
{
|
||||||
|
if (_cachePackRuleInstance.TryGetValue(ruleName, out IPackRule instance))
|
||||||
|
return instance;
|
||||||
|
|
||||||
|
// 如果不存在创建类的实例
|
||||||
|
if (_cachePackRuleTypes.TryGetValue(ruleName, out Type type))
|
||||||
|
{
|
||||||
|
instance = (IPackRule)Activator.CreateInstance(type);
|
||||||
|
_cachePackRuleInstance.Add(ruleName, instance);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"{nameof(IPackRule)}类型无效:{ruleName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static IFilterRule GetFilterRuleInstance(string ruleName)
|
||||||
|
{
|
||||||
|
if (_cacheFilterRuleInstance.TryGetValue(ruleName, out IFilterRule instance))
|
||||||
|
return instance;
|
||||||
|
|
||||||
|
// 如果不存在创建类的实例
|
||||||
|
if (_cacheFilterRuleTypes.TryGetValue(ruleName, out Type type))
|
||||||
|
{
|
||||||
|
instance = (IFilterRule)Activator.CreateInstance(type);
|
||||||
|
_cacheFilterRuleInstance.Add(ruleName, instance);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"{nameof(IFilterRule)}类型无效:{ruleName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 着色器编辑相关
|
||||||
|
public static void ModifyShader(bool isCollectAllShaders, string shadersBundleName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(shadersBundleName))
|
||||||
|
return;
|
||||||
|
Setting.AutoCollectShaders = isCollectAllShaders;
|
||||||
|
Setting.ShadersBundleName = shadersBundleName;
|
||||||
|
SaveFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 资源分组编辑相关
|
||||||
|
public static void CreateGrouper(string grouperName, string grouperDesc, string assetTags, bool saveFile = true)
|
||||||
|
{
|
||||||
|
AssetBundleGrouper grouper = new AssetBundleGrouper();
|
||||||
|
grouper.GrouperName = grouperName;
|
||||||
|
grouper.GrouperDesc = grouperDesc;
|
||||||
|
grouper.AssetTags = assetTags;
|
||||||
|
Setting.Groupers.Add(grouper);
|
||||||
|
|
||||||
|
if (saveFile)
|
||||||
|
SaveFile();
|
||||||
|
}
|
||||||
|
public static void RemoveGrouper(AssetBundleGrouper grouper)
|
||||||
|
{
|
||||||
|
if (Setting.Groupers.Remove(grouper))
|
||||||
|
{
|
||||||
|
SaveFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void ModifyGrouper(AssetBundleGrouper grouper)
|
||||||
|
{
|
||||||
|
if (grouper != null)
|
||||||
|
{
|
||||||
|
SaveFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 资源收集器编辑相关
|
||||||
|
public static void CreateCollector(AssetBundleGrouper grouper, string collectPath, string packRuleName, string filterRuleName, bool notWriteToAssetList, bool saveFile = true)
|
||||||
|
{
|
||||||
|
AssetBundleCollector collector = new AssetBundleCollector();
|
||||||
|
collector.CollectPath = collectPath;
|
||||||
|
collector.PackRuleName = packRuleName;
|
||||||
|
collector.FilterRuleName = filterRuleName;
|
||||||
|
collector.NotWriteToAssetList = notWriteToAssetList;
|
||||||
|
grouper.Collectors.Add(collector);
|
||||||
|
|
||||||
|
if (saveFile)
|
||||||
|
SaveFile();
|
||||||
|
}
|
||||||
|
public static void RemoveCollector(AssetBundleGrouper grouper, AssetBundleCollector collector)
|
||||||
|
{
|
||||||
|
if (grouper.Collectors.Remove(collector))
|
||||||
|
{
|
||||||
|
SaveFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void ModifyCollector(AssetBundleGrouper grouper, AssetBundleCollector collector)
|
||||||
|
{
|
||||||
|
if (grouper != null && collector != null)
|
||||||
|
{
|
||||||
|
SaveFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2fa91f25d246411459816310b09480a5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,394 @@
|
||||||
|
#if UNITY_2019_4_OR_NEWER
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor.UIElements;
|
||||||
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class AssetBundleGrouperWindow : EditorWindow
|
||||||
|
{
|
||||||
|
[MenuItem("YooAsset/AssetBundle Grouper", false, 100)]
|
||||||
|
public static void ShowExample()
|
||||||
|
{
|
||||||
|
AssetBundleGrouperWindow window = GetWindow<AssetBundleGrouperWindow>();
|
||||||
|
window.titleContent = new GUIContent("资源包分组工具");
|
||||||
|
window.minSize = new Vector2(800, 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<string> _packRuleList;
|
||||||
|
private List<string> _filterRuleList;
|
||||||
|
private ListView _grouperListView;
|
||||||
|
private ListView _collectorListView;
|
||||||
|
private Toggle _autoCollectShaderToogle;
|
||||||
|
private TextField _shaderBundleNameTxt;
|
||||||
|
private TextField _grouperNameTxt;
|
||||||
|
private TextField _grouperDescTxt;
|
||||||
|
private TextField _grouperAssetTagsTxt;
|
||||||
|
private VisualElement _rightContainer;
|
||||||
|
|
||||||
|
public void CreateGUI()
|
||||||
|
{
|
||||||
|
VisualElement root = this.rootVisualElement;
|
||||||
|
|
||||||
|
_packRuleList = AssetBundleGrouperSettingData.GetPackRuleNames();
|
||||||
|
_filterRuleList = AssetBundleGrouperSettingData.GetFilterRuleNames();
|
||||||
|
|
||||||
|
// 加载布局文件
|
||||||
|
string rootPath = EditorTools.GetYooAssetPath();
|
||||||
|
string uxml = $"{rootPath}/Editor/AssetBundleGrouper/{nameof(AssetBundleGrouperWindow)}.uxml";
|
||||||
|
var visualAsset = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(uxml);
|
||||||
|
if (visualAsset == null)
|
||||||
|
{
|
||||||
|
Debug.LogError($"Not found {nameof(AssetBundleGrouperWindow)}.uxml : {uxml}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
visualAsset.CloneTree(root);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 着色器相关
|
||||||
|
_autoCollectShaderToogle = root.Q<Toggle>("AutoCollectShader");
|
||||||
|
_autoCollectShaderToogle.SetValueWithoutNotify(AssetBundleGrouperSettingData.Setting.AutoCollectShaders);
|
||||||
|
_autoCollectShaderToogle.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
AssetBundleGrouperSettingData.ModifyShader(evt.newValue, _shaderBundleNameTxt.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
_shaderBundleNameTxt = root.Q<TextField>("ShaderBundleName");
|
||||||
|
_shaderBundleNameTxt.SetValueWithoutNotify(AssetBundleGrouperSettingData.Setting.ShadersBundleName);
|
||||||
|
_shaderBundleNameTxt.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
AssetBundleGrouperSettingData.ModifyShader(_autoCollectShaderToogle.value, evt.newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 分组列表相关
|
||||||
|
_grouperListView = root.Q<ListView>("GrouperListView");
|
||||||
|
_grouperListView.makeItem = MakeGrouperListViewItem;
|
||||||
|
_grouperListView.bindItem = BindGrouperListViewItem;
|
||||||
|
#if UNITY_2020_1_OR_NEWER
|
||||||
|
_grouperListView.onSelectionChange += GrouperListView_onSelectionChange;
|
||||||
|
#else
|
||||||
|
_grouperListView.onSelectionChanged += GrouperListView_onSelectionChange;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 分组添加删除按钮
|
||||||
|
var grouperAddContainer = root.Q("GrouperAddContainer");
|
||||||
|
{
|
||||||
|
var addBtn = grouperAddContainer.Q<Button>("AddBtn");
|
||||||
|
addBtn.clicked += AddGrouperBtn_clicked;
|
||||||
|
var removeBtn = grouperAddContainer.Q<Button>("RemoveBtn");
|
||||||
|
removeBtn.clicked += RemoveGrouperBtn_clicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 右侧容器
|
||||||
|
_rightContainer = root.Q("RightContainer");
|
||||||
|
_rightContainer.visible = false;
|
||||||
|
|
||||||
|
// 分组信息相关
|
||||||
|
_grouperNameTxt = root.Q<TextField>("GrouperName");
|
||||||
|
_grouperNameTxt.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
var selectGrouper = _grouperListView.selectedItem as AssetBundleGrouper;
|
||||||
|
if (selectGrouper != null)
|
||||||
|
{
|
||||||
|
selectGrouper.GrouperName = evt.newValue;
|
||||||
|
AssetBundleGrouperSettingData.ModifyGrouper(selectGrouper);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_grouperDescTxt = root.Q<TextField>("GrouperDesc");
|
||||||
|
_grouperDescTxt.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
var selectGrouper = _grouperListView.selectedItem as AssetBundleGrouper;
|
||||||
|
if (selectGrouper != null)
|
||||||
|
{
|
||||||
|
selectGrouper.GrouperDesc = evt.newValue;
|
||||||
|
AssetBundleGrouperSettingData.ModifyGrouper(selectGrouper);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_grouperAssetTagsTxt = root.Q<TextField>("GrouperAssetTags");
|
||||||
|
_grouperAssetTagsTxt.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
var selectGrouper = _grouperListView.selectedItem as AssetBundleGrouper;
|
||||||
|
if (selectGrouper != null)
|
||||||
|
{
|
||||||
|
selectGrouper.AssetTags = evt.newValue;
|
||||||
|
AssetBundleGrouperSettingData.ModifyGrouper(selectGrouper);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 收集列表相关
|
||||||
|
_collectorListView = root.Q<ListView>("CollectorListView");
|
||||||
|
_collectorListView.makeItem = MakeCollectorListViewItem;
|
||||||
|
_collectorListView.bindItem = BindCollectorListViewItem;
|
||||||
|
#if UNITY_2020_1_OR_NEWER
|
||||||
|
_collectorListView.onSelectionChange += CollectorListView_onSelectionChange;
|
||||||
|
#else
|
||||||
|
_collectorListView.onSelectionChanged += CollectorListView_onSelectionChange;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 收集添加删除按钮
|
||||||
|
var collectorAddContainer = root.Q("CollectorAddContainer");
|
||||||
|
{
|
||||||
|
var addBtn = collectorAddContainer.Q<Button>("AddBtn");
|
||||||
|
addBtn.clicked += AddCollectorBtn_clicked;
|
||||||
|
var removeBtn = collectorAddContainer.Q<Button>("RemoveBtn");
|
||||||
|
removeBtn.clicked += RemoveCollectorBtn_clicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化界面
|
||||||
|
FillGrouperViewData();
|
||||||
|
}
|
||||||
|
catch (System.Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogError(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分组列表相关
|
||||||
|
private void FillGrouperViewData()
|
||||||
|
{
|
||||||
|
_grouperListView.Clear();
|
||||||
|
_grouperListView.ClearSelection();
|
||||||
|
_grouperListView.itemsSource = AssetBundleGrouperSettingData.Setting.Groupers;
|
||||||
|
}
|
||||||
|
private VisualElement MakeGrouperListViewItem()
|
||||||
|
{
|
||||||
|
VisualElement element = new VisualElement();
|
||||||
|
|
||||||
|
{
|
||||||
|
var label = new Label();
|
||||||
|
label.name = "Label1";
|
||||||
|
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||||
|
label.style.flexGrow = 1f;
|
||||||
|
label.style.height = 20f;
|
||||||
|
element.Add(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
private void BindGrouperListViewItem(VisualElement element, int index)
|
||||||
|
{
|
||||||
|
var grouper = AssetBundleGrouperSettingData.Setting.Groupers[index];
|
||||||
|
|
||||||
|
// Grouper Name
|
||||||
|
var textField1 = element.Q<Label>("Label1");
|
||||||
|
textField1.text = grouper.GrouperName;
|
||||||
|
}
|
||||||
|
private void GrouperListView_onSelectionChange(IEnumerable<object> objs)
|
||||||
|
{
|
||||||
|
FillCollectorViewData();
|
||||||
|
}
|
||||||
|
private void AddGrouperBtn_clicked()
|
||||||
|
{
|
||||||
|
AssetBundleGrouperSettingData.CreateGrouper("Default Grouper", string.Empty, string.Empty, true);
|
||||||
|
FillGrouperViewData();
|
||||||
|
}
|
||||||
|
private void RemoveGrouperBtn_clicked()
|
||||||
|
{
|
||||||
|
var selectGrouper = _grouperListView.selectedItem as AssetBundleGrouper;
|
||||||
|
if (selectGrouper == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AssetBundleGrouperSettingData.RemoveGrouper(selectGrouper);
|
||||||
|
FillGrouperViewData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收集列表相关
|
||||||
|
private void FillCollectorViewData()
|
||||||
|
{
|
||||||
|
var selectGrouper = _grouperListView.selectedItem as AssetBundleGrouper;
|
||||||
|
if (selectGrouper == null)
|
||||||
|
{
|
||||||
|
_rightContainer.visible = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_rightContainer.visible = true;
|
||||||
|
_collectorListView.Clear();
|
||||||
|
_collectorListView.ClearSelection();
|
||||||
|
_collectorListView.itemsSource = selectGrouper.Collectors;
|
||||||
|
|
||||||
|
_grouperNameTxt.SetValueWithoutNotify(selectGrouper.GrouperName);
|
||||||
|
_grouperDescTxt.SetValueWithoutNotify(selectGrouper.GrouperDesc);
|
||||||
|
_grouperAssetTagsTxt.SetValueWithoutNotify(selectGrouper.AssetTags);
|
||||||
|
}
|
||||||
|
private VisualElement MakeCollectorListViewItem()
|
||||||
|
{
|
||||||
|
VisualElement element = new VisualElement();
|
||||||
|
|
||||||
|
VisualElement elementTop = new VisualElement();
|
||||||
|
elementTop.style.flexDirection = FlexDirection.Row;
|
||||||
|
element.Add(elementTop);
|
||||||
|
|
||||||
|
VisualElement elementBottom = new VisualElement();
|
||||||
|
elementBottom.style.flexDirection = FlexDirection.Row;
|
||||||
|
element.Add(elementBottom);
|
||||||
|
|
||||||
|
// Top VisualElement
|
||||||
|
{
|
||||||
|
var objectField = new ObjectField();
|
||||||
|
objectField.name = "ObjectField1";
|
||||||
|
objectField.label = "Collect Path";
|
||||||
|
objectField.objectType = typeof(UnityEngine.Object);
|
||||||
|
objectField.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||||
|
objectField.style.flexGrow = 1f;
|
||||||
|
elementTop.Add(objectField);
|
||||||
|
var label = objectField.Q<Label>();
|
||||||
|
label.style.minWidth = 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bottom VisualElement
|
||||||
|
{
|
||||||
|
var label = new Label();
|
||||||
|
label.style.width = 80;
|
||||||
|
elementBottom.Add(label);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var popupField = new PopupField<string>(_packRuleList, 0);
|
||||||
|
popupField.name = "PopupField1";
|
||||||
|
popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||||
|
popupField.style.width = 150;
|
||||||
|
elementBottom.Add(popupField);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var popupField = new PopupField<string>(_filterRuleList, 0);
|
||||||
|
popupField.name = "PopupField2";
|
||||||
|
popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||||
|
popupField.style.width = 150;
|
||||||
|
elementBottom.Add(popupField);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var toggle = new Toggle();
|
||||||
|
toggle.name = "Toggle1";
|
||||||
|
toggle.label = "NotWriteToAssetList";
|
||||||
|
toggle.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||||
|
toggle.style.width = 150;
|
||||||
|
toggle.style.marginLeft = 20;
|
||||||
|
elementBottom.Add(toggle);
|
||||||
|
var label = toggle.Q<Label>();
|
||||||
|
label.style.minWidth = 130;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var textField = new TextField();
|
||||||
|
textField.name = "TextField1";
|
||||||
|
textField.label = "Tags";
|
||||||
|
textField.style.width = 100;
|
||||||
|
textField.style.marginLeft = 20;
|
||||||
|
textField.style.flexGrow = 1;
|
||||||
|
elementBottom.Add(textField);
|
||||||
|
var label = textField.Q<Label>();
|
||||||
|
label.style.minWidth = 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
private void BindCollectorListViewItem(VisualElement element, int index)
|
||||||
|
{
|
||||||
|
var selectGrouper = _grouperListView.selectedItem as AssetBundleGrouper;
|
||||||
|
if (selectGrouper == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var collector = selectGrouper.Collectors[index];
|
||||||
|
var collectObject = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(collector.CollectPath);
|
||||||
|
if (collectObject != null)
|
||||||
|
collectObject.name = collector.CollectPath;
|
||||||
|
|
||||||
|
// Collect Path
|
||||||
|
var objectField1 = element.Q<ObjectField>("ObjectField1");
|
||||||
|
objectField1.SetValueWithoutNotify(collectObject);
|
||||||
|
objectField1.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
collector.CollectPath = AssetDatabase.GetAssetPath(evt.newValue);
|
||||||
|
objectField1.value.name = collector.CollectPath;
|
||||||
|
AssetBundleGrouperSettingData.ModifyCollector(selectGrouper, collector);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Pack Rule
|
||||||
|
var popupField1 = element.Q<PopupField<string>>("PopupField1");
|
||||||
|
popupField1.index = GetPackRuleIndex(collector.PackRuleName);
|
||||||
|
popupField1.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
collector.PackRuleName = evt.newValue;
|
||||||
|
AssetBundleGrouperSettingData.ModifyCollector(selectGrouper, collector);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filter Rule
|
||||||
|
var popupField2 = element.Q<PopupField<string>>("PopupField2");
|
||||||
|
popupField2.index = GetFilterRuleIndex(collector.FilterRuleName);
|
||||||
|
popupField2.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
collector.FilterRuleName = evt.newValue;
|
||||||
|
AssetBundleGrouperSettingData.ModifyCollector(selectGrouper, collector);
|
||||||
|
});
|
||||||
|
|
||||||
|
// NotWriteToAssetList
|
||||||
|
var toggle1 = element.Q<Toggle>("Toggle1");
|
||||||
|
toggle1.SetValueWithoutNotify(collector.NotWriteToAssetList);
|
||||||
|
toggle1.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
collector.NotWriteToAssetList = evt.newValue;
|
||||||
|
AssetBundleGrouperSettingData.ModifyCollector(selectGrouper, collector);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Tags
|
||||||
|
var textFiled1 = element.Q<TextField>("TextField1");
|
||||||
|
textFiled1.SetValueWithoutNotify(collector.AssetTags);
|
||||||
|
textFiled1.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
collector.AssetTags = evt.newValue;
|
||||||
|
AssetBundleGrouperSettingData.ModifyCollector(selectGrouper, collector);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private void CollectorListView_onSelectionChange(IEnumerable<object> objs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
private void AddCollectorBtn_clicked()
|
||||||
|
{
|
||||||
|
var selectGrouper = _grouperListView.selectedItem as AssetBundleGrouper;
|
||||||
|
if (selectGrouper == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AssetBundleGrouperSettingData.CreateCollector(selectGrouper, string.Empty, nameof(PackDirectory), nameof(CollectAll), false);
|
||||||
|
FillCollectorViewData();
|
||||||
|
}
|
||||||
|
private void RemoveCollectorBtn_clicked()
|
||||||
|
{
|
||||||
|
var selectGrouper = _grouperListView.selectedItem as AssetBundleGrouper;
|
||||||
|
if (selectGrouper == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var selectCollector = _collectorListView.selectedItem as AssetBundleCollector;
|
||||||
|
if (selectCollector == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AssetBundleGrouperSettingData.RemoveCollector(selectGrouper, selectCollector);
|
||||||
|
FillCollectorViewData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetPackRuleIndex(string packRuleName)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _packRuleList.Count; i++)
|
||||||
|
{
|
||||||
|
if (_packRuleList[i] == packRuleName)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
private int GetFilterRuleIndex(string filterRuleName)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _filterRuleList.Count; i++)
|
||||||
|
{
|
||||||
|
if (_filterRuleList[i] == filterRuleName)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b730ebd685b28964a9f002593751e98a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,30 @@
|
||||||
|
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
|
||||||
|
<uie:Toolbar name="Toolbar" style="display: flex;">
|
||||||
|
<uie:ToolbarSearchField focusable="true" name="SearchField" style="width: 300px; flex-grow: 1;" />
|
||||||
|
<ui:Button text="导出" display-tooltip-when-elided="true" name="ExportButton" style="width: 50px; background-color: rgb(56, 147, 58);" />
|
||||||
|
<ui:Button text="导入" display-tooltip-when-elided="true" name="ImportButton" style="width: 50px; background-color: rgb(56, 147, 58);" />
|
||||||
|
</uie:Toolbar>
|
||||||
|
<ui:VisualElement name="ShaderContainer" style="height: 24px; background-color: rgb(77, 77, 77); border-left-width: 2px; border-right-width: 2px; border-top-width: 2px; border-bottom-width: 2px; flex-direction: row; border-top-left-radius: 2px; border-bottom-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px;">
|
||||||
|
<ui:Toggle label="Auto Collect Shaders" name="AutoCollectShader" style="width: 196px; -unity-text-align: middle-left;" />
|
||||||
|
<ui:TextField picking-mode="Ignore" label="Shader Bundle Name" name="ShaderBundleName" style="flex-grow: 1; -unity-text-align: middle-left;" />
|
||||||
|
</ui:VisualElement>
|
||||||
|
<ui:VisualElement name="ContentContainer" style="flex-grow: 1; flex-direction: row;">
|
||||||
|
<ui:VisualElement name="LeftContainer" style="width: 200px; flex-grow: 0; background-color: rgb(67, 67, 67); border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
|
||||||
|
<ui:VisualElement name="GrouperAddContainer" style="height: 20px; flex-direction: row;">
|
||||||
|
<ui:Button text=" - " display-tooltip-when-elided="true" name="RemoveBtn" />
|
||||||
|
<ui:Button text=" + " display-tooltip-when-elided="true" name="AddBtn" />
|
||||||
|
</ui:VisualElement>
|
||||||
|
<ui:ListView focusable="true" name="GrouperListView" item-height="20" style="flex-grow: 1;" />
|
||||||
|
</ui:VisualElement>
|
||||||
|
<ui:VisualElement name="RightContainer" style="flex-grow: 1; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
|
||||||
|
<ui:TextField picking-mode="Ignore" label="Grouper Name" name="GrouperName" />
|
||||||
|
<ui:TextField picking-mode="Ignore" label="Grouper Desc" name="GrouperDesc" />
|
||||||
|
<ui:TextField picking-mode="Ignore" label="Grouper Asset Tags" name="GrouperAssetTags" />
|
||||||
|
<ui:VisualElement name="CollectorAddContainer" style="height: 20px; flex-direction: row-reverse;">
|
||||||
|
<ui:Button text=" - " display-tooltip-when-elided="true" name="RemoveBtn" />
|
||||||
|
<ui:Button text=" + " display-tooltip-when-elided="true" name="AddBtn" />
|
||||||
|
</ui:VisualElement>
|
||||||
|
<ui:ListView focusable="true" name="CollectorListView" item-height="50" style="flex-grow: 1;" />
|
||||||
|
</ui:VisualElement>
|
||||||
|
</ui:VisualElement>
|
||||||
|
</ui:UXML>
|
|
@ -0,0 +1,10 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 355c4ac5cdebddc4c8362bed6f17a79e
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
|
@ -0,0 +1,56 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class CollectAssetInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 资源包名称
|
||||||
|
/// </summary>
|
||||||
|
public string BundleName { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源路径
|
||||||
|
/// </summary>
|
||||||
|
public string AssetPath { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源分类标签
|
||||||
|
/// </summary>
|
||||||
|
public List<string> AssetTags { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为原生资源
|
||||||
|
/// </summary>
|
||||||
|
public bool IsRawAsset { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 不写入资源列表
|
||||||
|
/// </summary>
|
||||||
|
public bool NotWriteToAssetList { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 依赖的资源列表
|
||||||
|
/// </summary>
|
||||||
|
public List<string> DependAssets = new List<string>();
|
||||||
|
|
||||||
|
|
||||||
|
public CollectAssetInfo(string bundleName, string assetPath, List<string> assetTags, bool isRawAsset, bool notWriteToAssetList)
|
||||||
|
{
|
||||||
|
BundleName = bundleName;
|
||||||
|
AssetPath = assetPath;
|
||||||
|
AssetTags = assetTags;
|
||||||
|
IsRawAsset = isRawAsset;
|
||||||
|
NotWriteToAssetList = notWriteToAssetList;
|
||||||
|
}
|
||||||
|
public CollectAssetInfo(string assetPath, List<string> assetTags, bool isRawAsset, bool notWriteToAssetList)
|
||||||
|
{
|
||||||
|
BundleName = string.Empty;
|
||||||
|
AssetPath = assetPath;
|
||||||
|
AssetTags = assetTags;
|
||||||
|
IsRawAsset = isRawAsset;
|
||||||
|
NotWriteToAssetList = notWriteToAssetList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b44b2cc585bc59c4d879d1edac67f7c4
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,53 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 收集所有资源
|
||||||
|
/// </summary>
|
||||||
|
public class CollectAll : IFilterRule
|
||||||
|
{
|
||||||
|
public bool IsCollectAsset(string assetPath)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 只收集场景
|
||||||
|
/// </summary>
|
||||||
|
public class CollectScene : IFilterRule
|
||||||
|
{
|
||||||
|
public bool IsCollectAsset(string assetPath)
|
||||||
|
{
|
||||||
|
return Path.GetExtension(assetPath) == ".unity";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 只收集预制体
|
||||||
|
/// </summary>
|
||||||
|
public class CollectPrefab : IFilterRule
|
||||||
|
{
|
||||||
|
public bool IsCollectAsset(string assetPath)
|
||||||
|
{
|
||||||
|
return Path.GetExtension(assetPath) == ".prefab";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 只收集精灵类型的资源
|
||||||
|
/// </summary>
|
||||||
|
public class CollectSprite : IFilterRule
|
||||||
|
{
|
||||||
|
public bool IsCollectAsset(string assetPath)
|
||||||
|
{
|
||||||
|
if (AssetDatabase.GetMainAssetTypeAtPath(assetPath) == typeof(Sprite))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a74c81d149472fb4c960a1db1fd8accc
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,80 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 以文件路径作为资源包名
|
||||||
|
/// 注意:每个文件独自打资源包
|
||||||
|
/// </summary>
|
||||||
|
public class PackSeparately : IPackRule
|
||||||
|
{
|
||||||
|
string IPackRule.GetBundleName(PackRuleData data)
|
||||||
|
{
|
||||||
|
return StringUtility.RemoveExtension(data.AssetPath); //"Assets/Config/test.txt" --> "Assets/Config/test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以父类文件夹路径作为资源包名
|
||||||
|
/// 注意:文件夹下所有文件打进一个资源包
|
||||||
|
/// </summary>
|
||||||
|
public class PackDirectory : IPackRule
|
||||||
|
{
|
||||||
|
string IPackRule.GetBundleName(PackRuleData data)
|
||||||
|
{
|
||||||
|
return Path.GetDirectoryName(data.AssetPath); //"Assets/Config/test.txt" --> "Assets/Config"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以收集器路径作为资源包名
|
||||||
|
/// 注意:收集器下所有文件打进一个资源包
|
||||||
|
/// </summary>
|
||||||
|
public class PackCollector : IPackRule
|
||||||
|
{
|
||||||
|
string IPackRule.GetBundleName(PackRuleData data)
|
||||||
|
{
|
||||||
|
return StringUtility.RemoveExtension(data.CollectPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 以分组名称作为资源包名
|
||||||
|
/// 注意:分组内所有文件打进一个资源包
|
||||||
|
/// </summary>
|
||||||
|
public class PackGrouper : IPackRule
|
||||||
|
{
|
||||||
|
string IPackRule.GetBundleName(PackRuleData data)
|
||||||
|
{
|
||||||
|
return data.GrouperName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原生文件打包模式
|
||||||
|
/// 注意:原生文件打包支持:图片,音频,视频,文本
|
||||||
|
/// </summary>
|
||||||
|
public class PackRawFile : IPackRule
|
||||||
|
{
|
||||||
|
string IPackRule.GetBundleName(PackRuleData data)
|
||||||
|
{
|
||||||
|
string extension = StringUtility.RemoveFirstChar(Path.GetExtension(data.AssetPath));
|
||||||
|
if (extension == EAssetFileExtension.unity.ToString() || extension == EAssetFileExtension.prefab.ToString() ||
|
||||||
|
extension == EAssetFileExtension.mat.ToString() || extension == EAssetFileExtension.controller.ToString() ||
|
||||||
|
extension == EAssetFileExtension.fbx.ToString() || extension == EAssetFileExtension.anim.ToString() ||
|
||||||
|
extension == EAssetFileExtension.shader.ToString())
|
||||||
|
{
|
||||||
|
throw new Exception($"{nameof(PackRawFile)} is not support file estension : {extension}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注意:原生文件只支持无依赖关系的资源
|
||||||
|
string[] depends = AssetDatabase.GetDependencies(data.AssetPath, true);
|
||||||
|
if (depends.Length != 1)
|
||||||
|
throw new Exception($"{nameof(PackRawFile)} is not support estension : {extension}");
|
||||||
|
|
||||||
|
return StringUtility.RemoveExtension(data.AssetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4a924dc0a22fc104781bf9aaadd60c29
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 资源过滤规则接口
|
||||||
|
/// </summary>
|
||||||
|
public interface IFilterRule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为收集资源
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assetPath">资源路径</param>
|
||||||
|
/// <returns>如果收集该资源返回TRUE</returns>
|
||||||
|
bool IsCollectAsset(string assetPath);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ffe1385deb0bd9844a514f1c2fd65e62
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,37 @@
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 打包规则数据
|
||||||
|
/// </summary>
|
||||||
|
public struct PackRuleData
|
||||||
|
{
|
||||||
|
public string AssetPath;
|
||||||
|
public string CollectPath;
|
||||||
|
public string GrouperName;
|
||||||
|
|
||||||
|
public PackRuleData(string assetPath)
|
||||||
|
{
|
||||||
|
AssetPath = assetPath;
|
||||||
|
CollectPath = string.Empty;
|
||||||
|
GrouperName = string.Empty;
|
||||||
|
}
|
||||||
|
public PackRuleData(string assetPath, string collectPath, string grouperName)
|
||||||
|
{
|
||||||
|
AssetPath = assetPath;
|
||||||
|
CollectPath = collectPath;
|
||||||
|
GrouperName = grouperName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源打包规则接口
|
||||||
|
/// </summary>
|
||||||
|
public interface IPackRule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取资源打包所属的资源包名称
|
||||||
|
/// </summary>
|
||||||
|
string GetBundleName(PackRuleData data);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 577f7c1abcdf0a140958f1d1d44d6f40
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in New Issue