This commit is contained in:
MuHua-123
2025-06-17 10:53:45 +08:00
parent c6d9b71e95
commit 5374616980
87 changed files with 2265 additions and 1019 deletions
@@ -1,195 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using System.IO;
using System.Text.RegularExpressions;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
namespace AssetClean {
public class AssetCollector {
public static readonly string exportXMLPath = "referencemap.xml";
public List<string> deleteFileList = new List<string>();
List<CollectionData> referenceCollection = new List<CollectionData>();
public bool useCodeStrip = true;
public bool saveEditorExtensions = true;
public void Collection(string[] collectionFolders) {
try {
XmlSerializer serialize = new XmlSerializer(typeof(List<CollectionData>));
deleteFileList.Clear();
referenceCollection.Clear();
if (File.Exists(exportXMLPath)) {
using (StreamReader fileStream = new StreamReader(exportXMLPath)) {
referenceCollection = (List<CollectionData>)serialize.Deserialize(fileStream);
fileStream.Close();
}
}
List<IReferenceCollection> collectionList = new List<IReferenceCollection>();
if (useCodeStrip) {
collectionList.Add(new ClassReferenceCollection(saveEditorExtensions));
}
collectionList.AddRange(new IReferenceCollection[] {
new ShaderReferenceCollection (),
new AssetReferenceCollection (),
});
foreach (IReferenceCollection collection in collectionList) {
collection.Init(referenceCollection);
collection.CollectionFiles();
}
// Find assets
var files = StripTargetPathsAll(useCodeStrip, collectionFolders);
foreach (var path in files) {
var guid = AssetDatabase.AssetPathToGUID(path);
deleteFileList.Add(guid);
}
EditorUtility.DisplayProgressBar("checking", "collection all files", 0.2f);
UnregistReferenceFromResources();
EditorUtility.DisplayProgressBar("checking", "check reference from resources", 0.4f);
UnregistReferenceFromScenes();
EditorUtility.DisplayProgressBar("checking", "check reference from scenes", 0.6f);
if (saveEditorExtensions) {
UnregistEditorCodes();
}
EditorUtility.DisplayProgressBar("checking", "check reference from ignorelist", 0.8f);
UnregistReferenceFromIgnoreList();
UnregistReferenceFromExtensionMethod();
using (var fileStream = new StreamWriter(exportXMLPath)) {
serialize.Serialize(fileStream, referenceCollection);
fileStream.Close();
}
} finally {
EditorUtility.ClearProgressBar();
}
}
List<string> StripTargetPathsAll(bool isUseCodeStrip, string[] pathes) {
var files = pathes.SelectMany(c => Directory.GetFiles(c, "*.*", SearchOption.AllDirectories))
.Distinct()
.Where(item => Path.GetExtension(item) != ".meta")
.Where(item => Path.GetExtension(item) != ".js")
.Where(item => Path.GetExtension(item) != ".dll")
.Where(item => Regex.IsMatch(item, "[\\/\\\\]Gizmos[\\/\\\\]") == false)
.Where(item => Regex.IsMatch(item, "[\\/\\\\]Plugins[\\/\\\\]Android[\\/\\\\]") == false)
.Where(item => Regex.IsMatch(item, "[\\/\\\\]Plugins[\\/\\\\]iOS[\\/\\\\]") == false)
.Where(item => Regex.IsMatch(item, "[\\/\\\\]Resources[\\/\\\\]") == false);
if (isUseCodeStrip == false) {
files = files.Where(item => Path.GetExtension(item) != ".cs");
}
return files.ToList();
}
void UnregistReferenceFromIgnoreList() {
var codePaths = deleteFileList.Where(fileName => Path.GetExtension(fileName) == ".cs");
foreach (var path in codePaths) {
var code = ClassReferenceCollection.StripComment(File.ReadAllText(path));
if (Regex.IsMatch(code, "static\\s*(partial)*\\s*class")) {
UnregistFromDelteList(AssetDatabase.AssetPathToGUID(path));
continue;
}
}
}
void UnregistReferenceFromExtensionMethod() {
var resourcesFiles = deleteFileList
.Where(item => Path.GetExtension(item) != ".meta")
.ToArray();
foreach (var path in AssetDatabase.GetDependencies(resourcesFiles)) {
UnregistFromDelteList(AssetDatabase.AssetPathToGUID(path));
}
}
void UnregistReferenceFromResources() {
var resourcesFiles = deleteFileList
.Where(item => Regex.IsMatch(item, "[\\/\\\\]Resources[\\/\\\\]") == true)
.Where(item => Path.GetExtension(item) != ".meta")
.ToArray();
foreach (var path in AssetDatabase.GetDependencies(resourcesFiles)) {
UnregistFromDelteList(AssetDatabase.AssetPathToGUID(path));
}
}
void UnregistReferenceFromScenes() {
// Exclude objects that reference from scenes.
var scenes = EditorBuildSettings.scenes
.Where(item => item.enabled == true)
.Select(item => item.path)
.ToArray();
foreach (var path in AssetDatabase.GetDependencies(scenes)) {
UnregistFromDelteList(AssetDatabase.AssetPathToGUID(path));
}
}
void UnregistEditorCodes() {
// Exclude objects that reference from Editor API
var editorcodes = Directory.GetFiles("Assets", "*.*", SearchOption.AllDirectories)
.Where(fileName => Path.GetExtension(fileName) == ".cs")
.Where(item => Regex.IsMatch(item, "[\\/\\\\]Editor[\\/\\\\]") == true)
.ToArray();
EditorUtility.DisplayProgressBar("checking", "check reference from editor codes", 0.8f);
foreach (var path in editorcodes) {
var code = ClassReferenceCollection.StripComment(File.ReadAllText(path));
if (Regex.IsMatch(code, "(\\[MenuItem|AssetPostprocessor|EditorWindow)")) {
UnregistFromDelteList(AssetDatabase.AssetPathToGUID(path));
continue;
}
}
foreach (var path in editorcodes) {
var guid = AssetDatabase.AssetPathToGUID(path);
if (referenceCollection.Exists(c => c.fileGuid == guid) == false) {
continue;
}
var referenceGuids = referenceCollection.First(c => c.fileGuid == guid).referenceGids;
if (referenceGuids.Any(c => deleteFileList.Contains(c) == true) == false) {
UnregistFromDelteList(AssetDatabase.AssetPathToGUID(path));
}
}
}
void UnregistFromDelteList(string guid) {
if (deleteFileList.Contains(guid) == false) {
return;
}
deleteFileList.Remove(guid);
if (referenceCollection.Exists(c => c.fileGuid == guid)) {
var refInfo = referenceCollection.First(c => c.fileGuid == guid);
foreach (var referenceGuid in refInfo.referenceGids) {
UnregistFromDelteList(referenceGuid);
}
}
}
}
}
@@ -1,58 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using System.Linq;
public class AssetReferenceCollection : IReferenceCollection {
public void Init(List<CollectionData> refs) {
references = refs;
}
private List<CollectionData> references = null;
public void CollectionFiles() {
var allFiles = Directory.GetFiles("Assets", "*.*", SearchOption.AllDirectories)
.Where(c => Path.GetExtension(c) != ".meta")
.Where(c => Path.GetExtension(c) != ".shader")
.Where(c => Path.GetExtension(c) != ".cg")
.Where(c => Path.GetExtension(c) != ".cginc")
.Where(c => Path.GetExtension(c) != ".cs");
foreach (var file in allFiles) {
CollectionReferenceAssets(file);
}
}
public void CollectionReferenceAssets(string path) {
string guid = AssetDatabase.AssetPathToGUID(path);
if (File.Exists(path) == false) { return; }
string[] referenceFiles = AssetDatabase.GetDependencies(new string[] { path });
List<string> referenceList = null;
CollectionData reference = null;
if (references.Exists(c => c.fileGuid == guid) == false) {
referenceList = new List<string>();
reference = new CollectionData() {
fileGuid = guid,
referenceGids = referenceList,
};
references.Add(reference);
}
else {
reference = references.Find(c => c.fileGuid == guid);
referenceList = reference.referenceGids;
}
if (string.IsNullOrEmpty(AssetDatabase.GUIDToAssetPath(guid)) == false) {
reference.timeStamp = File.GetLastWriteTime(AssetDatabase.GUIDToAssetPath(guid));
}
foreach (string file in referenceFiles) {
if (referenceList.Contains(file) == false)
referenceList.Add(AssetDatabase.AssetPathToGUID(file));
}
}
}
@@ -1,356 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEditor;
using System.IO;
using System.Reflection;
using System.Linq;
using System.Xml.Serialization;
namespace AssetClean {
public class ClassReferenceCollection : IReferenceCollection {
// guid : types
private List<CollectionData> references = null;
// type : guid
private Dictionary<System.Type, List<string>> code2FileDic = new Dictionary<System.Type, List<string>>();
private List<TypeDate> fileTypeList = null;
public static readonly string xmlPath = "referenceType2File.xml";
private List<TypeDate> fileTypeXML {
get {
if (File.Exists(xmlPath) == true) {
using (var reader = new StreamReader(xmlPath)) {
XmlSerializer serialize = new XmlSerializer(typeof(List<TypeDate>));
return (List<TypeDate>)serialize.Deserialize(reader);
}
}
else {
return new List<TypeDate>();
}
}
set {
using (var writer = new StreamWriter(xmlPath)) {
XmlSerializer serialize = new XmlSerializer(typeof(List<TypeDate>));
serialize.Serialize(writer, value);
}
}
}
TypeDate GetTypeData(string guid) {
if (fileTypeList.Exists(c => c.guid == guid) == false) {
var path = AssetDatabase.GUIDToAssetPath(guid);
fileTypeList.Add(new TypeDate() {
guid = guid,
fileName = path,
timeStamp = File.GetLastWriteTime(path)
});
}
return fileTypeList.First(c => c.guid == guid);
}
private bool isSaveEditorCode = false;
public ClassReferenceCollection(bool saveStiroCode = false) {
isSaveEditorCode = saveStiroCode;
fileTypeList = fileTypeXML;
}
public void Init(List<CollectionData> refs) {
references = refs;
}
public void CollectionFiles() {
// connect each classes.
var firstPassList = new List<string>();
if (Directory.Exists("Assets/Plugins"))
firstPassList.AddRange(CodeList("Assets/Plugins"));
if (Directory.Exists("Assets/Standard Assets"))
firstPassList.AddRange(CodeList("Assets/Standard Assets"));
// Connect the files and class.
var codes = CodeList("Assets/").Where(c => firstPassList.Contains(c) == false);
var allFirstpassTypes = collectionAllFastspassClasses();
CollectionCodeFileDictionary(allFirstpassTypes, firstPassList.ToArray());
var alltypes = CollectionAllClasses();
CollectionCodeFileDictionary(alltypes, codes.ToArray());
alltypes.AddRange(allFirstpassTypes);
fileTypeXML = fileTypeList;
foreach (var type in alltypes) {
List<string> list = null;
if (code2FileDic.ContainsKey(type) == false) {
list = new List<string>();
code2FileDic.Add(type, list);
}
else {
list = code2FileDic[type];
}
var fullName = type.FullName;
var assembly = type.Assembly.FullName;
if (fileTypeList.Exists(c => c.assemblly == assembly && c.typeFullName.Contains(fullName))) {
var datas = fileTypeList.Where(c => c.assemblly == assembly && c.typeFullName.Contains(fullName));
foreach (var data in datas) {
list.Add(data.guid);
}
}
}
float count = 1, max = firstPassList.Count;
foreach (var codepath in firstPassList) {
EditorUtility.DisplayProgressBar("analytics", codepath, count++ / max);
CollectionReferenceClasses(AssetDatabase.AssetPathToGUID(codepath), allFirstpassTypes);
}
count = 1;
max = codes.Count();
foreach (var codepath in codes) {
EditorUtility.DisplayProgressBar("analytics", codepath, count++ / max);
CollectionReferenceClasses(AssetDatabase.AssetPathToGUID(codepath), alltypes);
}
if (isSaveEditorCode) {
CollectionCustomEditorClasses(alltypes);
}
}
List<string> CodeList(string path) {
string[] codes = Directory.GetFiles(path, "*.cs", SearchOption.AllDirectories);
List<string> needUpdateFileList = new List<string>();
foreach (var code in codes) {
var guid = AssetDatabase.AssetPathToGUID(code);
if (fileTypeList.Exists(c => c.guid == guid) == false) {
needUpdateFileList.Add(code);
continue;
}
var filetype = GetTypeData(guid);
var timeStamp = filetype.timeStamp;
var time = File.GetLastWriteTime(code);
if (time != timeStamp) {
filetype.timeStamp = time;
needUpdateFileList.Add(code);
continue;
}
}
return needUpdateFileList;
}
void CollectionCodeFileDictionary(List<System.Type> alltypes, string[] codes) {
float count = 1;
foreach (var codePath in codes) {
EditorUtility.DisplayProgressBar("checking", "search files", count++ / codes.Length);
// connect file and classes.
var code = StripComment(System.IO.File.ReadAllText(codePath));
var guid = AssetDatabase.AssetPathToGUID(codePath);
var typeList = GetTypeData(guid);
typeList.typeFullName.Clear();
foreach (var type in alltypes) {
if (type.IsNested) {
continue;
}
if (string.IsNullOrEmpty(type.Namespace) == false) {
var namespacepattern = string.Format("namespace\\s*{0}[{{\\s\\n]", type.Namespace);
if (Regex.IsMatch(code, namespacepattern) == false) {
continue;
}
}
string typeName = type.IsGenericTypeDefinition ? type.GetGenericTypeDefinition().Name.Split('`')[0] : type.Name;
if (type.IsClass) {
if (Regex.IsMatch(code, string.Format("class\\s*{0}?[\\s:<{{]", typeName))) {
typeList.Add(type);
var nested = type.GetNestedTypes(BindingFlags.Public | BindingFlags.Instance);
foreach (var nestedType in nested) {
typeList.Add(nestedType);
}
continue;
}
}
else if (type.IsInterface) {
if (Regex.IsMatch(code, string.Format("interface\\s*{0}[\\s<{{]", typeName))) {
typeList.Add(type);
continue;
}
}
else if (type.IsEnum) {
if (Regex.IsMatch(code, string.Format("enum\\s*{0}[\\s{{]", type.Name))) {
typeList.Add(type);
continue;
}
}
else {
if (Regex.IsMatch(code, string.Format("struct\\s*{0}[\\s:<{{]", typeName))) {
typeList.Add(type);
continue;
}
if (Regex.IsMatch(code, string.Format("delegate\\s*{0}\\s\\(", typeName))) {
typeList.Add(type);
continue;
}
}
}
}
}
List<System.Type> CollectionAllClasses() {
string path = Application.dataPath;
string absolutePath = path.Remove(path.Length - 6);
List<System.Type> alltypes = new List<System.Type>();
if (File.Exists(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp.dll"))
alltypes.AddRange(Assembly.LoadFile(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp.dll").GetTypes());
if (isSaveEditorCode && File.Exists(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp-Editor.dll"))
alltypes.AddRange(Assembly.LoadFile(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp-Editor.dll").GetTypes());
return alltypes.ToList();
}
List<System.Type> collectionAllFastspassClasses() {
string path = Application.dataPath;
string absolutePath = path.Remove(path.Length - 6);
List<System.Type> alltypes = new List<System.Type>();
if (File.Exists(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp-firstpass.dll"))
alltypes.AddRange(Assembly.LoadFile(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp-firstpass.dll").GetTypes());
if (isSaveEditorCode && File.Exists(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp-Editor-firstpass.dll"))
alltypes.AddRange(Assembly.LoadFile(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp-Editor-firstpass.dll").GetTypes());
return alltypes;
}
public static string StripComment(string code) {
code = Regex.Replace(code, "//.*[\\n\\r]", "");
code = Regex.Replace(code, "/\\*.*[\\n\\r]\\*/", "");
return code;
}
void CollectionReferenceClasses(string guid, List<System.Type> types) {
var codePath = AssetDatabase.GUIDToAssetPath(guid);
if (string.IsNullOrEmpty(codePath) || File.Exists(codePath) == false) {
return;
}
var code = StripComment(System.IO.File.ReadAllText(codePath));
List<string> referenceList = null;
CollectionData reference = null;
if (references.Exists(c => c.fileGuid == guid) == false) {
referenceList = new List<string>();
reference = new CollectionData() {
fileGuid = guid,
referenceGids = referenceList,
};
references.Add(reference);
}
else {
reference = references.Find(c => c.fileGuid == guid);
referenceList = reference.referenceGids;
}
referenceList.Clear();
var timestamp = File.GetLastWriteTime(codePath);
reference.timeStamp = timestamp;
foreach (var type in types) {
if (code2FileDic.ContainsKey(type) == false || code2FileDic[type].Contains(guid)) {
continue;
}
if (string.IsNullOrEmpty(type.Namespace) == false) {
var namespacepattern = string.Format("([namespace|using][\\s]{0}[{{\\s\\r\\n\\r;]|{0}\\.)", type.Namespace);
if (Regex.IsMatch(code, namespacepattern) == false) {
continue;
}
}
string match = string.Empty;
if (type.IsGenericTypeDefinition) {
string typeName = type.GetGenericTypeDefinition().Name.Split('`')[0];
match = string.Format("[!|&\\]\\[\\.\\s<(]{0}[\\.\\s\\n\\r>,<(){{]", typeName);
}
else {
string typeName = type.Name.Split('`')[0].Replace("Attribute", "");
match = string.Format("[!|&\\]\\[\\.\\s<(]{0}[\\.\\s\\n\\r>,<(){{\\]]", typeName);
// check Extension Methods
if (Regex.IsMatch(code, string.Format("this\\s{0}\\s", typeName))) {
foreach (var file in code2FileDic[type]) {
foreach (var baseReference in references.Where(c => c.fileGuid == file)) {
baseReference.referenceGids.Add(guid);
}
}
}
}
if (Regex.IsMatch(code, match)) {
var typeGuids = code2FileDic[type];
foreach (var typeGuid in typeGuids) {
if (referenceList.Contains(typeGuid) == false) {
referenceList.Add(typeGuid);
}
}
}
}
}
void CollectionCustomEditorClasses(IEnumerable<System.Type> types) {
foreach (var type in types) {
if (code2FileDic.ContainsKey(type) == false) {
continue;
}
var attributes = type.GetCustomAttributes(typeof(CustomEditor), true);
foreach (var attribute in attributes) {
if (attribute is CustomEditor == false) {
continue;
}
var customEditor = attribute as CustomEditor;
var customEditorReferenceTypeField = typeof(CustomEditor).GetField("m_InspectedType", BindingFlags.Instance | BindingFlags.NonPublic);
var customEditorReferenceType = (System.Type)customEditorReferenceTypeField.GetValue(customEditor);
if (code2FileDic.ContainsKey(customEditorReferenceType) == false) {
continue;
}
foreach (var filePath in code2FileDic[customEditorReferenceType]) {
if (references.Exists(c => c.fileGuid == filePath) == false) {
continue;
}
foreach (var refs in references.Where(c => c.fileGuid == filePath)) {
var list = refs.referenceGids;
list.AddRange(code2FileDic[type]);
}
}
}
}
}
}
}
@@ -1,42 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Linq;
[System.Serializable]
public class CollectionData {
public string fileGuid;
public string fileName;
public List<string> referenceGids = new List<string>();
public DateTime timeStamp;
}
[System.Serializable]
public class TypeDate {
public string guid;
public string fileName;
public DateTime timeStamp;
public List<string> typeFullName = new List<string>();
public string assemblly;
public void Add(Type addtype) {
assemblly = addtype.Assembly.FullName;
var typeName = addtype.FullName;
if (typeFullName.Contains(typeName) == false) {
typeFullName.Add(typeName);
}
}
public Type[] types {
get {
return typeFullName.Select(c => Type.GetType(c)).ToArray();
}
}
}
public interface IReferenceCollection {
void CollectionFiles();
void Init(List<CollectionData> refs);
}
@@ -1,214 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using System.IO;
using System.Linq;
namespace AssetClean {
public class FindUnusedAssetsWindow : EditorWindow {
AssetCollector collection = new AssetCollector();
List<DeleteAsset> deleteAssets = new List<DeleteAsset>();
Vector2 scroll;
[MenuItem("Window/Delete Unused Assets/only resource", false, 50)]
static void InitWithoutCode() {
var window = FindUnusedAssetsWindow.CreateInstance<FindUnusedAssetsWindow>();
window.collection.useCodeStrip = false;
window.collection.Collection(new string[] { "Assets" });
window.CopyDeleteFileList(window.collection.deleteFileList);
window.Show();
}
[MenuItem("Window/Delete Unused Assets/unused by editor", false, 51)]
static void InitWithout() {
var window = FindUnusedAssetsWindow.CreateInstance<FindUnusedAssetsWindow>();
window.collection.Collection(new string[] { "Assets" });
window.CopyDeleteFileList(window.collection.deleteFileList);
window.Show();
}
[MenuItem("Window/Delete Unused Assets/unused by game", false, 52)]
static void Init() {
FindUnusedAssetsWindow window = CreateInstance<FindUnusedAssetsWindow>();
window.collection.saveEditorExtensions = false;
window.collection.Collection(new string[] { "Assets" });
window.CopyDeleteFileList(window.collection.deleteFileList);
window.Show();
}
// [MenuItem("Assets/Delete Unused Assets/unused by editor", false, 52)]
// static void InitAssets ()
// {
// var paths = Selection.objects
// .Select(c=>AssetDatabase.GetAssetPath(c))
// .Where(c=>Directory.Exists(c));
// if( paths.Any(c=> string.IsNullOrEmpty(c) ) ){
// return;
// }
//
// var window = FindUnusedAssetsWindow.CreateInstance<FindUnusedAssetsWindow> ();
// window.collection.Collection (paths.ToArray());
// window.CopyDeleteFileList (window.collection.deleteFileList);
//
// window.Show ();
// }
//
// [MenuItem("Assets/Delete Unused Assets/unused by editor", true)]
// static bool InitAssetsA ()
// {
// var paths = Selection.objects
// .Select(c=>AssetDatabase.GetAssetPath(c))
// .Where(c=>Directory.Exists(c));
// return ! paths.Any(c=> string.IsNullOrEmpty(c) );
// }
[MenuItem("Assets/Delete Unused Assets/unused only resources", false, 52)]
static void InitAssetsOnlyResources() {
var paths = Selection.objects
.Select(c => AssetDatabase.GetAssetPath(c))
.Where(c => Directory.Exists(c));
if (paths.Any(c => string.IsNullOrEmpty(c))) {
return;
}
var window = FindUnusedAssetsWindow.CreateInstance<FindUnusedAssetsWindow>();
window.collection.useCodeStrip = false;
window.collection.Collection(paths.ToArray());
window.CopyDeleteFileList(window.collection.deleteFileList);
window.Show();
}
[MenuItem("Assets/Delete Unused Assets/unused only resources", true)]
static bool InitAssetsOnlyResourcesA() {
var paths = Selection.objects
.Select(c => AssetDatabase.GetAssetPath(c))
.Where(c => Directory.Exists(c));
return !paths.Any(c => string.IsNullOrEmpty(c));
}
[MenuItem("Window/Delete Unused Assets/Clear cache")]
static void ClearCache() {
File.Delete(AssetClean.AssetCollector.exportXMLPath);
File.Delete(AssetClean.ClassReferenceCollection.xmlPath);
EditorUtility.DisplayDialog("clear file", "clear file", "OK");
}
void OnGUI() {
using (var horizonal = new EditorGUILayout.HorizontalScope("box")) {
EditorGUILayout.LabelField("delete unreference assets from buildsettings and resources");
}
using (var scrollScope = new EditorGUILayout.ScrollViewScope(scroll)) {
scroll = scrollScope.scrollPosition;
foreach (var asset in deleteAssets) {
if (string.IsNullOrEmpty(asset.path)) {
continue;
}
using (var horizonal = new EditorGUILayout.HorizontalScope()) {
asset.isDelete = EditorGUILayout.Toggle(asset.isDelete, GUILayout.Width(20));
var icon = AssetDatabase.GetCachedIcon(asset.path);
GUILayout.Label(icon, GUILayout.Width(20), GUILayout.Height(20));
if (GUILayout.Button(asset.path, EditorStyles.largeLabel)) {
Selection.activeObject = AssetDatabase.LoadAssetAtPath<Object>(asset.path);
}
}
}
}
using (var horizonal = new EditorGUILayout.HorizontalScope("box")) {
EditorGUILayout.Space();
if (GUILayout.Button("Exclude from Project", GUILayout.Width(160)) && deleteAssets.Count != 0) {
EditorApplication.delayCall += Exclude;
}
}
}
void Exclude() {
RemoveFiles();
Close();
}
static void CleanDir() {
RemoveEmptyDirectry("Assets");
AssetDatabase.Refresh();
}
void CopyDeleteFileList(IEnumerable<string> deleteFileList) {
foreach (var asset in deleteFileList) {
var filePath = AssetDatabase.GUIDToAssetPath(asset);
if (string.IsNullOrEmpty(filePath) == false) {
deleteAssets.Add(new DeleteAsset() { path = filePath });
}
}
}
void RemoveFiles() {
try {
string exportDirectry = "BackupUnusedAssets";
Directory.CreateDirectory(exportDirectry);
var files = deleteAssets.Where(item => item.isDelete == true).Select(item => item.path).ToArray();
string backupPackageName = exportDirectry + "/package" + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".unitypackage";
EditorUtility.DisplayProgressBar("export package", backupPackageName, 0);
AssetDatabase.ExportPackage(files, backupPackageName);
int i = 0;
int length = deleteAssets.Count;
foreach (var assetPath in files) {
i++;
EditorUtility.DisplayProgressBar("delete unused assets", assetPath, (float)i / length);
AssetDatabase.DeleteAsset(assetPath);
if (File.Exists(assetPath)) {
File.Delete(assetPath);
}
}
EditorUtility.DisplayProgressBar("clean directory", "", 1);
foreach (var dir in Directory.GetDirectories("Assets")) {
RemoveEmptyDirectry(dir);
}
System.Diagnostics.Process.Start(exportDirectry);
AssetDatabase.Refresh();
}
catch (System.Exception e) {
Debug.Log(e.Message);
} finally {
EditorUtility.ClearProgressBar();
}
}
static void RemoveEmptyDirectry(string path) {
var dirs = Directory.GetDirectories(path);
foreach (var dir in dirs) {
RemoveEmptyDirectry(dir);
}
var files = Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly).Where(item => Path.GetExtension(item) != ".meta");
if (files.Count() == 0 && Directory.GetDirectories(path).Count() == 0) {
var metaFile = AssetDatabase.GetTextMetaFilePathFromAssetPath(path);
UnityEditor.FileUtil.DeleteFileOrDirectory(path);
UnityEditor.FileUtil.DeleteFileOrDirectory(metaFile);
}
}
class DeleteAsset {
public bool isDelete = true;
public string path;
}
}
}
@@ -1,95 +0,0 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
namespace AssetClean {
public class ShaderReferenceCollection : IReferenceCollection {
// shader name / shader file guid
public Dictionary<string, string> shaderFileList = new Dictionary<string, string>();
private List<CollectionData> references = new List<CollectionData>();
public void Init(List<CollectionData> refs) {
references = refs;
}
public void CollectionFiles() {
CollectionShaderFiles();
CheckReference();
}
void CollectionShaderFiles() {
var shaderFiles = Directory.GetFiles("Assets", "*.shader", SearchOption.AllDirectories);
foreach (var shaderFilePath in shaderFiles) {
var code = File.ReadAllText(shaderFilePath);
var match = Regex.Match(code, "Shader \"(?<name>.*)\"");
if (match.Success) {
var shaderName = match.Groups["name"].ToString();
if (shaderFileList.ContainsKey(shaderName) == false) {
shaderFileList.Add(shaderName, AssetDatabase.AssetPathToGUID(shaderFilePath));
}
}
}
var cgFiles = Directory.GetFiles("Assets", "*.cg", SearchOption.AllDirectories);
foreach (var cgFilePath in cgFiles) {
var file = Path.GetFileName(cgFilePath);
shaderFileList.Add(file, cgFilePath);
}
var cgincFiles = Directory.GetFiles("Assets", "*.cginc", SearchOption.AllDirectories);
foreach (var cgincPath in cgincFiles) {
var file = Path.GetFileName(cgincPath);
if (shaderFileList.ContainsKey(file) == false) {
shaderFileList.Add(file, cgincPath);
}
}
}
void CheckReference() {
foreach (var shader in shaderFileList) {
var shaderFilePath = AssetDatabase.GUIDToAssetPath(shader.Value);
if (File.Exists(shaderFilePath) == false) {
continue;
}
var guid = shader.Value;
List<string> referenceList = null;
CollectionData reference = null;
if (references.Exists(c => c.fileGuid == guid) == false) {
referenceList = new List<string>();
reference = new CollectionData() {
fileGuid = guid,
referenceGids = referenceList,
};
references.Add(reference);
}
else {
reference = references.Find(c => c.fileGuid == guid);
referenceList = reference.referenceGids;
}
reference.timeStamp = File.GetLastWriteTime(AssetDatabase.GUIDToAssetPath(guid));
var code = ClassReferenceCollection.StripComment(File.ReadAllText(shaderFilePath));
foreach (var checkingShaderName in shaderFileList.Keys) {
if (checkingShaderName == shader.Key) {
continue;
}
if (code.IndexOf(checkingShaderName) != -1 && shaderFileList.ContainsKey(checkingShaderName)) {
var fileGuid = shaderFileList[checkingShaderName];
if (referenceList.Contains(fileGuid) == false) {
referenceList.Add(fileGuid);
}
}
}
}
}
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 0ecc08ef1d6ca1148a200120e465d381
guid: 41a0350eab712da4c995987e78ea7730
folderAsset: yes
DefaultImporter:
externalObjects: {}
Binary file not shown.
@@ -0,0 +1,109 @@
fileFormatVersion: 2
guid: 67c2fd624cee7914fba45f64a3cb04d1
ModelImporter:
serializedVersion: 22200
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 2
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
removeConstantScaleCurves: 0
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importPhysicalCameras: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
nodeNameCollisionStrategy: 1
fileIdsGeneration: 2
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
bakeAxisConversion: 0
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
optimizeBones: 1
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVMarginMethod: 1
secondaryUVMinLightmapResolution: 40
secondaryUVMinObjectScale: 1
secondaryUVPackMargin: 4
useFileScale: 1
strictVertexDataChecks: 0
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
autoGenerateAvatarMappingIfUnspecified: 1
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
importBlendShapeDeformPercent: 1
remapMaterialsIfMaterialImportModeIsNone: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,61 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MuHua;
public class HexagonMapSystem : MonoBehaviour {
public const float InnerDiam = 1f;
public const float OuterDiam = InnerDiam * 1.154700538379252f;
public const float InnerRadius = InnerDiam * 0.5f;
public const float OuterRadius = OuterDiam * 0.5f;
public int wide, high;
public Transform prefab;
public GameObject[,] array;
private void Awake() {
array = new GameObject[wide, high];
Loop((x, y) => { array[x, y] = Generate(x, y); });
}
private void Update() {
if (Input.GetMouseButtonDown(0) && RayTool.GetMouseToWorldPosition(out Vector3 worldPosition)) {
Vector2Int xy = GetXY(worldPosition);
Debug.Log(xy);
}
}
public void Loop(Action<int, int> action) {
for (int y = 0; y < high; y++) {
for (int x = 0; x < wide; x++) { action?.Invoke(x, y); }
}
}
public GameObject Generate(int x, int y) {
Transform temp = Instantiate(prefab, transform);
temp.position = GetWorldPosition(x, y);
temp.gameObject.SetActive(true);
return temp.gameObject;
}
public Vector3 GetWorldPosition(int x, int y) {
float offset = (y % 2) == 1 ? InnerRadius : 0;
float xPosition = x * InnerDiam + offset;
float zPosition = y * OuterDiam * 0.75f;
return new Vector3(xPosition, 0, zPosition);
}
public Vector2Int GetXY(Vector3 worldPosition) {
float offsetX = worldPosition.x / (InnerRadius * 2f);
float offsetZ = worldPosition.z / (OuterRadius * 3f);
float originalX = offsetX - offsetZ;
float originalY = -offsetX - offsetZ;
int iX = Mathf.RoundToInt(originalX);
int iY = Mathf.RoundToInt(originalY);
int iZ = Mathf.RoundToInt(-originalX - originalY);
if (iX + iY + iZ != 0) {
float differenceX = Mathf.Abs(originalX - iX);
float differenceY = Mathf.Abs(originalY - iY);
float differenceZ = Mathf.Abs(-originalX - originalY - iZ);
if (differenceX > differenceY && differenceX > differenceZ) { iX = -iY - iZ; }
else if (differenceZ > differenceY) { iZ = -iX - iY; }
}
int offset = iZ > 0 ? 0 : (iZ % 2);
return new Vector2Int(iX + ((iZ + offset) / 2), iZ);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e2f8faf05999aac48876a91674f33225
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,83 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: "\u65B0\u5EFA\u6750\u8D28 1"
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 0.9825768, g: 1, b: 0.48627448, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 99d8f3da04e2d5c4d8b313f164a0b496
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,83 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: "\u65B0\u5EFA\u6750\u8D28"
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 0.61900413, g: 1, b: 0.48584908, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9129ff6f94545cd4e9b3f6e8abed0635
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -13,13 +13,19 @@ public class UITestPage : ModuleUIPage {
private UIToggle toggle;
private UIDropdown<string> dropdown;
private UIScrollView scrollView;
private UIScrollView scrollView1;
private UIScrollView scrollView2;
private UIScrollView scrollView3;
private UIScrollView scrollView4;
public override VisualElement Element => root;
public VisualElement Toggle => Q<VisualElement>("Toggle");
public VisualElement Dropdown => Q<VisualElement>("Dropdown");
public VisualElement ScrollView => Q<VisualElement>("ScrollView");
public VisualElement ScrollView1 => Q<VisualElement>("ScrollView1");
public VisualElement ScrollView2 => Q<VisualElement>("ScrollView2");
public VisualElement ScrollView3 => Q<VisualElement>("ScrollView3");
public VisualElement ScrollView4 => Q<VisualElement>("ScrollView4");
private void Awake() {
toggle = new UIToggle(Toggle);
@@ -29,11 +35,17 @@ public class UITestPage : ModuleUIPage {
dropdown.SetValue(list);
dropdown.ValueChanged += (value) => Debug.Log(value);
scrollView = new UIScrollView(ScrollView, root, UIDirection.Vertical, UIDirection.FromLeftToRight, UIDirection.FromTopToBottom);
scrollView1 = new UIScrollView(ScrollView1, root, UIDirection.Vertical, UIDirection.FromLeftToRight, UIDirection.FromTopToBottom);
scrollView2 = new UIScrollView(ScrollView2, root, UIDirection.Vertical, UIDirection.FromLeftToRight, UIDirection.FromBottomToTop);
scrollView3 = new UIScrollView(ScrollView3, root, UIDirection.Horizontal, UIDirection.FromLeftToRight);
scrollView4 = new UIScrollView(ScrollView4, root, UIDirection.Horizontal, UIDirection.FromLeftToRight);
}
private void Update() {
dropdown.Update();
scrollView.Update();
scrollView1.Update();
scrollView2.Update();
scrollView3.Update();
scrollView4.Update();
}
private void OnDestroy() {
dropdown.Release();
@@ -1,4 +1,5 @@
.scrollview {
flex-grow: 1;
}
.scrollview-viewport {
@@ -15,6 +16,7 @@
flex-direction: column;
align-self: flex-start;
flex-shrink: 0;
width: 100%;
}
.scrollview-horizontal-scroller {
@@ -1,8 +1,8 @@
<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="False">
<Style src="project://database/Assets/MuHua/UITool/UIScrollView/ScrollView.uss?fileID=7433441132597879392&amp;guid=d8db2d69206657346a4fe9aebc592327&amp;type=3#ScrollView" />
<ui:VisualElement name="ScrollView" class="scrollview" style="width: 350px; height: 450px;">
<Style src="project://database/Assets/UI%20Toolkit/Component/ScrollView/ScrollView.uss?fileID=7433441132597879392&amp;guid=d8db2d69206657346a4fe9aebc592327&amp;type=3#ScrollView" />
<ui:VisualElement name="ScrollView" class="scrollview">
<ui:VisualElement name="Viewport" class="scrollview-viewport" style="margin-right: 0;">
<ui:VisualElement name="Container" class="scrollview-container" style="width: 1000px; height: 100%;">
<ui:VisualElement name="Container" class="scrollview-container" style="height: 100%; width: auto; flex-direction: row;">
<ui:Button text="1" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="2" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="3" parse-escape-sequences="true" display-tooltip-when-elided="true" />
@@ -1,8 +1,8 @@
<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="False">
<Style src="project://database/Assets/MuHua/UITool/UIScrollView/ScrollView.uss?fileID=7433441132597879392&amp;guid=d8db2d69206657346a4fe9aebc592327&amp;type=3#ScrollView" />
<ui:VisualElement name="ScrollView" class="scrollview" style="width: 350px; height: 450px;">
<Style src="project://database/Assets/UI%20Toolkit/Component/ScrollView/ScrollView.uss?fileID=7433441132597879392&amp;guid=d8db2d69206657346a4fe9aebc592327&amp;type=3#ScrollView" />
<ui:VisualElement name="ScrollView" class="scrollview">
<ui:VisualElement name="Viewport" class="scrollview-viewport" style="margin-right: 30px; margin-bottom: 0;">
<ui:VisualElement name="Container" class="scrollview-container" style="width: 100%; height: 1000px;">
<ui:VisualElement name="Container" class="scrollview-container">
<ui:Label tabindex="-1" text="Label" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Toggle label="Toggle" />
@@ -12,7 +12,7 @@
<ui:FloatField label="Float Field" value="42.2" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="ScrollerHorizontal" class="scroller-horizontal scrollview-horizontal-scroller" style="right: 0; display: none;">
<ui:VisualElement name="ScrollerHorizontal" class="scroller-horizontal scrollview-horizontal-scroller" style="display: none;">
<ui:VisualElement name="Dragger" class="scroller-horizontal-dragger scrollview-horizontal-scroller-dragger" />
</ui:VisualElement>
<ui:VisualElement name="ScrollerVertical" class="scroller-vertical scrollview-vertical-scroller">
@@ -20,4 +20,4 @@
background-color: rgb(255, 126, 126);
width: 100%;
height: 30px;
}
}
@@ -1,4 +1,5 @@
<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="False">
<Style src="project://database/Assets/UI%20Toolkit/Component/Scroller/Scroller.uss?fileID=7433441132597879392&amp;guid=fa60433f4fc03c34e8b51e6a8c9b32db&amp;type=3#Scroller" />
<ui:VisualElement class="scroller-vertical">
<ui:VisualElement name="Dragger" class="scroller-vertical-dragger" />
</ui:VisualElement>
+103 -23
View File
@@ -1,32 +1,112 @@
<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="False">
<ui:Template name="Toggle" src="project://database/Assets/UI%20Toolkit/Component/Toggle/Toggle.uxml?fileID=9197481963319205126&amp;guid=1fb475832cb8d164fba93f4b38a10155&amp;type=3#Toggle" />
<ui:Template name="Dropdown" src="project://database/Assets/UI%20Toolkit/Component/Dropdown/Dropdown.uxml?fileID=9197481963319205126&amp;guid=58251f1c92414424eb285cc650757918&amp;type=3#Dropdown" />
<Style src="project://database/Assets/UI%20Toolkit/Document/Document.uss?fileID=7433441132597879392&amp;guid=9205939af30a4394f8f2e34232b27890&amp;type=3#Document" />
<ui:Instance template="Toggle" name="Toggle" style="width: 200px;" />
<ui:Instance template="Toggle" name="Toggle" style="width: 200px;" />
<ui:VisualElement name="ScrollView" class="scrollview" style="width: 350px; height: 450px;">
<ui:VisualElement name="Viewport" class="scrollview-viewport" style="margin-right: 30px; margin-bottom: 0; flex-direction: column;">
<ui:VisualElement name="Container" class="scrollview-container" style="width: 100%; height: auto;">
<ui:Label tabindex="-1" text="Label" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Toggle label="Toggle" />
<ui:Toggle label="Toggle" />
<ui:Instance template="Dropdown" name="Dropdown" style="width: 200px;" />
<ui:DropdownField label="Dropdown" />
<ui:TextField picking-mode="Ignore" label="Text Field" value="filler text" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:VisualElement style="flex-grow: 1; flex-direction: row;">
<ui:VisualElement name="ScrollView1" class="scrollview" style="width: 350px; height: 450px; flex-grow: 0;">
<ui:VisualElement name="Viewport" class="scrollview-viewport" style="margin-right: 30px; margin-bottom: 0; flex-direction: column;">
<ui:VisualElement name="Container" class="scrollview-container" style="width: 100%; height: auto;">
<ui:Label tabindex="-1" text="Label" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Toggle label="Toggle" />
<ui:Toggle label="Toggle" />
<ui:Instance template="Dropdown" name="Dropdown" style="width: 200px;" />
<ui:DropdownField label="Dropdown" />
<ui:TextField picking-mode="Ignore" label="Text Field" value="filler text" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="ScrollerHorizontal" class="scroller-horizontal scrollview-horizontal-scroller" style="right: 0; display: none;">
<ui:VisualElement name="Dragger" class="scroller-horizontal-dragger scrollview-horizontal-scroller-dragger" />
</ui:VisualElement>
<ui:VisualElement name="ScrollerVertical" class="scroller-vertical scrollview-vertical-scroller">
<ui:VisualElement name="Dragger" class="scroller-vertical-dragger scrollview-vertical-scroller-dragger" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="ScrollerHorizontal" class="scroller-horizontal scrollview-horizontal-scroller" style="right: 0; display: none;">
<ui:VisualElement name="Dragger" class="scroller-horizontal-dragger scrollview-horizontal-scroller-dragger" />
<ui:VisualElement name="ScrollView2" class="scrollview" style="width: 350px; height: 450px; flex-grow: 0;">
<ui:VisualElement name="Viewport" class="scrollview-viewport" style="margin-right: 30px; margin-bottom: 0; flex-direction: column;">
<ui:VisualElement name="Container" class="scrollview-container" style="width: 100%; height: auto;">
<ui:Label tabindex="-1" text="Label" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Toggle label="Toggle" />
<ui:Toggle label="Toggle" />
<ui:Instance template="Dropdown" name="Dropdown" style="width: 200px;" />
<ui:DropdownField label="Dropdown" />
<ui:TextField picking-mode="Ignore" label="Text Field" value="filler text" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
<ui:FloatField label="Float Field" value="42.2" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="ScrollerHorizontal" class="scroller-horizontal scrollview-horizontal-scroller" style="right: 0; display: none;">
<ui:VisualElement name="Dragger" class="scroller-horizontal-dragger scrollview-horizontal-scroller-dragger" />
</ui:VisualElement>
<ui:VisualElement name="ScrollerVertical" class="scroller-vertical scrollview-vertical-scroller">
<ui:VisualElement name="Dragger" class="scroller-vertical-dragger scrollview-vertical-scroller-dragger" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="ScrollerVertical" class="scroller-vertical scrollview-vertical-scroller" style="flex-direction: column;">
<ui:VisualElement name="Dragger" class="scroller-vertical-dragger scrollview-vertical-scroller-dragger" />
<ui:VisualElement name="ScrollView3" class="scrollview" style="flex-grow: 0; width: 350px; height: 450px;">
<ui:VisualElement name="Viewport" class="scrollview-viewport" style="margin-right: 0;">
<ui:VisualElement name="Container" class="scrollview-container" style="height: 100%; width: auto; flex-direction: row;">
<ui:Button text="1" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="2" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="3" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="4" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="5" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="6" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="7" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="8" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="9" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="10" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="ScrollerHorizontal" class="scroller-horizontal scrollview-horizontal-scroller" style="right: 0;">
<ui:VisualElement name="Dragger" class="scroller-horizontal-dragger scrollview-horizontal-scroller-dragger" />
</ui:VisualElement>
<ui:VisualElement name="ScrollerVertical" class="scroller-vertical scrollview-vertical-scroller" style="display: none;">
<ui:VisualElement name="Dragger" class="scroller-vertical-dragger scrollview-vertical-scroller-dragger" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="ScrollView4" class="scrollview" style="flex-grow: 0; width: 350px; height: 450px;">
<ui:VisualElement name="Viewport" class="scrollview-viewport" style="margin-right: 0;">
<ui:VisualElement name="Container" class="scrollview-container" style="height: 100%; width: auto; flex-direction: row;">
<ui:Button text="1" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="2" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="3" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="4" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="5" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="6" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="7" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="8" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="9" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="10" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="ScrollerHorizontal" class="scroller-horizontal scrollview-horizontal-scroller" style="right: 0;">
<ui:VisualElement name="Dragger" class="scroller-horizontal-dragger scrollview-horizontal-scroller-dragger" />
</ui:VisualElement>
<ui:VisualElement name="ScrollerVertical" class="scroller-vertical scrollview-vertical-scroller" style="display: none;">
<ui:VisualElement name="Dragger" class="scroller-vertical-dragger scrollview-vertical-scroller-dragger" />
</ui:VisualElement>
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ed131875727eb2f49ad3cb894e141f83
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+196
View File
@@ -0,0 +1,196 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using System.IO;
using System.Text.RegularExpressions;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
namespace MuHuaEditor {
public class AssetCollector {
public static readonly string exportXMLPath = "referencemap.xml";
public List<string> deleteFileList = new List<string>();
List<CollectionData> referenceCollection = new List<CollectionData>();
public bool useCodeStrip = true;
public bool saveEditorExtensions = true;
public void Collection(string[] collectionFolders) {
try {
XmlSerializer serialize = new XmlSerializer(typeof(List<CollectionData>));
deleteFileList.Clear();
referenceCollection.Clear();
if (File.Exists(exportXMLPath)) {
using (StreamReader fileStream = new StreamReader(exportXMLPath)) {
referenceCollection = (List<CollectionData>)serialize.Deserialize(fileStream);
fileStream.Close();
}
}
List<IReferenceCollection> collectionList = new List<IReferenceCollection>();
if (useCodeStrip) {
collectionList.Add(new ClassReferenceCollection(saveEditorExtensions));
}
collectionList.AddRange(new IReferenceCollection[] {
new ShaderReferenceCollection (),
new AssetReferenceCollection (),
});
foreach (IReferenceCollection collection in collectionList) {
collection.Init(referenceCollection);
collection.CollectionFiles();
}
// Find assets
var files = StripTargetPathsAll(useCodeStrip, collectionFolders);
foreach (var path in files) {
var guid = AssetDatabase.AssetPathToGUID(path);
deleteFileList.Add(guid);
}
EditorUtility.DisplayProgressBar("checking", "collection all files", 0.2f);
UnregistReferenceFromResources();
EditorUtility.DisplayProgressBar("checking", "check reference from resources", 0.4f);
UnregistReferenceFromScenes();
EditorUtility.DisplayProgressBar("checking", "check reference from scenes", 0.6f);
if (saveEditorExtensions) {
UnregistEditorCodes();
}
EditorUtility.DisplayProgressBar("checking", "check reference from ignorelist", 0.8f);
UnregistReferenceFromIgnoreList();
UnregistReferenceFromExtensionMethod();
using (var fileStream = new StreamWriter(exportXMLPath)) {
serialize.Serialize(fileStream, referenceCollection);
fileStream.Close();
}
}
finally {
EditorUtility.ClearProgressBar();
}
}
List<string> StripTargetPathsAll(bool isUseCodeStrip, string[] pathes) {
var files = pathes.SelectMany(c => Directory.GetFiles(c, "*.*", SearchOption.AllDirectories))
.Distinct()
.Where(item => Path.GetExtension(item) != ".meta")
.Where(item => Path.GetExtension(item) != ".js")
.Where(item => Path.GetExtension(item) != ".dll")
.Where(item => Regex.IsMatch(item, "[\\/\\\\]Gizmos[\\/\\\\]") == false)
.Where(item => Regex.IsMatch(item, "[\\/\\\\]Plugins[\\/\\\\]Android[\\/\\\\]") == false)
.Where(item => Regex.IsMatch(item, "[\\/\\\\]Plugins[\\/\\\\]iOS[\\/\\\\]") == false)
.Where(item => Regex.IsMatch(item, "[\\/\\\\]Resources[\\/\\\\]") == false);
if (isUseCodeStrip == false) {
files = files.Where(item => Path.GetExtension(item) != ".cs");
}
return files.ToList();
}
void UnregistReferenceFromIgnoreList() {
var codePaths = deleteFileList.Where(fileName => Path.GetExtension(fileName) == ".cs");
foreach (var path in codePaths) {
var code = ClassReferenceCollection.StripComment(File.ReadAllText(path));
if (Regex.IsMatch(code, "static\\s*(partial)*\\s*class")) {
UnregistFromDelteList(AssetDatabase.AssetPathToGUID(path));
continue;
}
}
}
void UnregistReferenceFromExtensionMethod() {
var resourcesFiles = deleteFileList
.Where(item => Path.GetExtension(item) != ".meta")
.ToArray();
foreach (var path in AssetDatabase.GetDependencies(resourcesFiles)) {
UnregistFromDelteList(AssetDatabase.AssetPathToGUID(path));
}
}
void UnregistReferenceFromResources() {
var resourcesFiles = deleteFileList
.Where(item => Regex.IsMatch(item, "[\\/\\\\]Resources[\\/\\\\]") == true)
.Where(item => Path.GetExtension(item) != ".meta")
.ToArray();
foreach (var path in AssetDatabase.GetDependencies(resourcesFiles)) {
UnregistFromDelteList(AssetDatabase.AssetPathToGUID(path));
}
}
void UnregistReferenceFromScenes() {
// Exclude objects that reference from scenes.
var scenes = EditorBuildSettings.scenes
.Where(item => item.enabled == true)
.Select(item => item.path)
.ToArray();
foreach (var path in AssetDatabase.GetDependencies(scenes)) {
UnregistFromDelteList(AssetDatabase.AssetPathToGUID(path));
}
}
void UnregistEditorCodes() {
// Exclude objects that reference from Editor API
var editorcodes = Directory.GetFiles("Assets", "*.*", SearchOption.AllDirectories)
.Where(fileName => Path.GetExtension(fileName) == ".cs")
.Where(item => Regex.IsMatch(item, "[\\/\\\\]Editor[\\/\\\\]") == true)
.ToArray();
EditorUtility.DisplayProgressBar("checking", "check reference from editor codes", 0.8f);
foreach (var path in editorcodes) {
var code = ClassReferenceCollection.StripComment(File.ReadAllText(path));
if (Regex.IsMatch(code, "(\\[MenuItem|AssetPostprocessor|EditorWindow)")) {
UnregistFromDelteList(AssetDatabase.AssetPathToGUID(path));
continue;
}
}
foreach (var path in editorcodes) {
var guid = AssetDatabase.AssetPathToGUID(path);
if (referenceCollection.Exists(c => c.fileGuid == guid) == false) {
continue;
}
var referenceGuids = referenceCollection.First(c => c.fileGuid == guid).referenceGids;
if (referenceGuids.Any(c => deleteFileList.Contains(c) == true) == false) {
UnregistFromDelteList(AssetDatabase.AssetPathToGUID(path));
}
}
}
void UnregistFromDelteList(string guid) {
if (deleteFileList.Contains(guid) == false) {
return;
}
deleteFileList.Remove(guid);
if (referenceCollection.Exists(c => c.fileGuid == guid)) {
var refInfo = referenceCollection.First(c => c.fileGuid == guid);
foreach (var referenceGuid in refInfo.referenceGids) {
UnregistFromDelteList(referenceGuid);
}
}
}
}
}
@@ -0,0 +1,59 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using System.Linq;
namespace MuHuaEditor {
public class AssetReferenceCollection : IReferenceCollection {
public void Init(List<CollectionData> refs) {
references = refs;
}
private List<CollectionData> references = null;
public void CollectionFiles() {
var allFiles = Directory.GetFiles("Assets", "*.*", SearchOption.AllDirectories)
.Where(c => Path.GetExtension(c) != ".meta")
.Where(c => Path.GetExtension(c) != ".shader")
.Where(c => Path.GetExtension(c) != ".cg")
.Where(c => Path.GetExtension(c) != ".cginc")
.Where(c => Path.GetExtension(c) != ".cs");
foreach (var file in allFiles) {
CollectionReferenceAssets(file);
}
}
public void CollectionReferenceAssets(string path) {
string guid = AssetDatabase.AssetPathToGUID(path);
if (File.Exists(path) == false) { return; }
string[] referenceFiles = AssetDatabase.GetDependencies(new string[] { path });
List<string> referenceList = null;
CollectionData reference = null;
if (references.Exists(c => c.fileGuid == guid) == false) {
referenceList = new List<string>();
reference = new CollectionData() {
fileGuid = guid,
referenceGids = referenceList,
};
references.Add(reference);
}
else {
reference = references.Find(c => c.fileGuid == guid);
referenceList = reference.referenceGids;
}
if (string.IsNullOrEmpty(AssetDatabase.GUIDToAssetPath(guid)) == false) {
reference.timeStamp = File.GetLastWriteTime(AssetDatabase.GUIDToAssetPath(guid));
}
foreach (string file in referenceFiles) {
if (referenceList.Contains(file) == false)
referenceList.Add(AssetDatabase.AssetPathToGUID(file));
}
}
}
}
@@ -0,0 +1,356 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEditor;
using System.IO;
using System.Reflection;
using System.Linq;
using System.Xml.Serialization;
namespace MuHuaEditor {
public class ClassReferenceCollection : IReferenceCollection {
// guid : types
private List<CollectionData> references = null;
// type : guid
private Dictionary<System.Type, List<string>> code2FileDic = new Dictionary<System.Type, List<string>>();
private List<TypeDate> fileTypeList = null;
public static readonly string xmlPath = "referenceType2File.xml";
private List<TypeDate> fileTypeXML {
get {
if (File.Exists(xmlPath) == true) {
using (var reader = new StreamReader(xmlPath)) {
XmlSerializer serialize = new XmlSerializer(typeof(List<TypeDate>));
return (List<TypeDate>)serialize.Deserialize(reader);
}
}
else {
return new List<TypeDate>();
}
}
set {
using (var writer = new StreamWriter(xmlPath)) {
XmlSerializer serialize = new XmlSerializer(typeof(List<TypeDate>));
serialize.Serialize(writer, value);
}
}
}
TypeDate GetTypeData(string guid) {
if (fileTypeList.Exists(c => c.guid == guid) == false) {
var path = AssetDatabase.GUIDToAssetPath(guid);
fileTypeList.Add(new TypeDate() {
guid = guid,
fileName = path,
timeStamp = File.GetLastWriteTime(path)
});
}
return fileTypeList.First(c => c.guid == guid);
}
private bool isSaveEditorCode = false;
public ClassReferenceCollection(bool saveStiroCode = false) {
isSaveEditorCode = saveStiroCode;
fileTypeList = fileTypeXML;
}
public void Init(List<CollectionData> refs) {
references = refs;
}
public void CollectionFiles() {
// connect each classes.
var firstPassList = new List<string>();
if (Directory.Exists("Assets/Plugins"))
firstPassList.AddRange(CodeList("Assets/Plugins"));
if (Directory.Exists("Assets/Standard Assets"))
firstPassList.AddRange(CodeList("Assets/Standard Assets"));
// Connect the files and class.
var codes = CodeList("Assets/").Where(c => firstPassList.Contains(c) == false);
var allFirstpassTypes = collectionAllFastspassClasses();
CollectionCodeFileDictionary(allFirstpassTypes, firstPassList.ToArray());
var alltypes = CollectionAllClasses();
CollectionCodeFileDictionary(alltypes, codes.ToArray());
alltypes.AddRange(allFirstpassTypes);
fileTypeXML = fileTypeList;
foreach (var type in alltypes) {
List<string> list = null;
if (code2FileDic.ContainsKey(type) == false) {
list = new List<string>();
code2FileDic.Add(type, list);
}
else {
list = code2FileDic[type];
}
var fullName = type.FullName;
var assembly = type.Assembly.FullName;
if (fileTypeList.Exists(c => c.assemblly == assembly && c.typeFullName.Contains(fullName))) {
var datas = fileTypeList.Where(c => c.assemblly == assembly && c.typeFullName.Contains(fullName));
foreach (var data in datas) {
list.Add(data.guid);
}
}
}
float count = 1, max = firstPassList.Count;
foreach (var codepath in firstPassList) {
EditorUtility.DisplayProgressBar("analytics", codepath, count++ / max);
CollectionReferenceClasses(AssetDatabase.AssetPathToGUID(codepath), allFirstpassTypes);
}
count = 1;
max = codes.Count();
foreach (var codepath in codes) {
EditorUtility.DisplayProgressBar("analytics", codepath, count++ / max);
CollectionReferenceClasses(AssetDatabase.AssetPathToGUID(codepath), alltypes);
}
if (isSaveEditorCode) {
CollectionCustomEditorClasses(alltypes);
}
}
List<string> CodeList(string path) {
string[] codes = Directory.GetFiles(path, "*.cs", SearchOption.AllDirectories);
List<string> needUpdateFileList = new List<string>();
foreach (var code in codes) {
var guid = AssetDatabase.AssetPathToGUID(code);
if (fileTypeList.Exists(c => c.guid == guid) == false) {
needUpdateFileList.Add(code);
continue;
}
var filetype = GetTypeData(guid);
var timeStamp = filetype.timeStamp;
var time = File.GetLastWriteTime(code);
if (time != timeStamp) {
filetype.timeStamp = time;
needUpdateFileList.Add(code);
continue;
}
}
return needUpdateFileList;
}
void CollectionCodeFileDictionary(List<System.Type> alltypes, string[] codes) {
float count = 1;
foreach (var codePath in codes) {
EditorUtility.DisplayProgressBar("checking", "search files", count++ / codes.Length);
// connect file and classes.
var code = StripComment(System.IO.File.ReadAllText(codePath));
var guid = AssetDatabase.AssetPathToGUID(codePath);
var typeList = GetTypeData(guid);
typeList.typeFullName.Clear();
foreach (var type in alltypes) {
if (type.IsNested) {
continue;
}
if (string.IsNullOrEmpty(type.Namespace) == false) {
var namespacepattern = string.Format("namespace\\s*{0}[{{\\s\\n]", type.Namespace);
if (Regex.IsMatch(code, namespacepattern) == false) {
continue;
}
}
string typeName = type.IsGenericTypeDefinition ? type.GetGenericTypeDefinition().Name.Split('`')[0] : type.Name;
if (type.IsClass) {
if (Regex.IsMatch(code, string.Format("class\\s*{0}?[\\s:<{{]", typeName))) {
typeList.Add(type);
var nested = type.GetNestedTypes(BindingFlags.Public | BindingFlags.Instance);
foreach (var nestedType in nested) {
typeList.Add(nestedType);
}
continue;
}
}
else if (type.IsInterface) {
if (Regex.IsMatch(code, string.Format("interface\\s*{0}[\\s<{{]", typeName))) {
typeList.Add(type);
continue;
}
}
else if (type.IsEnum) {
if (Regex.IsMatch(code, string.Format("enum\\s*{0}[\\s{{]", type.Name))) {
typeList.Add(type);
continue;
}
}
else {
if (Regex.IsMatch(code, string.Format("struct\\s*{0}[\\s:<{{]", typeName))) {
typeList.Add(type);
continue;
}
if (Regex.IsMatch(code, string.Format("delegate\\s*{0}\\s\\(", typeName))) {
typeList.Add(type);
continue;
}
}
}
}
}
List<System.Type> CollectionAllClasses() {
string path = Application.dataPath;
string absolutePath = path.Remove(path.Length - 6);
List<System.Type> alltypes = new List<System.Type>();
if (File.Exists(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp.dll"))
alltypes.AddRange(Assembly.LoadFile(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp.dll").GetTypes());
if (isSaveEditorCode && File.Exists(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp-Editor.dll"))
alltypes.AddRange(Assembly.LoadFile(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp-Editor.dll").GetTypes());
return alltypes.ToList();
}
List<System.Type> collectionAllFastspassClasses() {
string path = Application.dataPath;
string absolutePath = path.Remove(path.Length - 6);
List<System.Type> alltypes = new List<System.Type>();
if (File.Exists(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp-firstpass.dll"))
alltypes.AddRange(Assembly.LoadFile(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp-firstpass.dll").GetTypes());
if (isSaveEditorCode && File.Exists(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp-Editor-firstpass.dll"))
alltypes.AddRange(Assembly.LoadFile(absolutePath + "Library/ScriptAssemblies/Assembly-CSharp-Editor-firstpass.dll").GetTypes());
return alltypes;
}
public static string StripComment(string code) {
code = Regex.Replace(code, "//.*[\\n\\r]", "");
code = Regex.Replace(code, "/\\*.*[\\n\\r]\\*/", "");
return code;
}
void CollectionReferenceClasses(string guid, List<System.Type> types) {
var codePath = AssetDatabase.GUIDToAssetPath(guid);
if (string.IsNullOrEmpty(codePath) || File.Exists(codePath) == false) {
return;
}
var code = StripComment(System.IO.File.ReadAllText(codePath));
List<string> referenceList = null;
CollectionData reference = null;
if (references.Exists(c => c.fileGuid == guid) == false) {
referenceList = new List<string>();
reference = new CollectionData() {
fileGuid = guid,
referenceGids = referenceList,
};
references.Add(reference);
}
else {
reference = references.Find(c => c.fileGuid == guid);
referenceList = reference.referenceGids;
}
referenceList.Clear();
var timestamp = File.GetLastWriteTime(codePath);
reference.timeStamp = timestamp;
foreach (var type in types) {
if (code2FileDic.ContainsKey(type) == false || code2FileDic[type].Contains(guid)) {
continue;
}
if (string.IsNullOrEmpty(type.Namespace) == false) {
var namespacepattern = string.Format("([namespace|using][\\s]{0}[{{\\s\\r\\n\\r;]|{0}\\.)", type.Namespace);
if (Regex.IsMatch(code, namespacepattern) == false) {
continue;
}
}
string match = string.Empty;
if (type.IsGenericTypeDefinition) {
string typeName = type.GetGenericTypeDefinition().Name.Split('`')[0];
match = string.Format("[!|&\\]\\[\\.\\s<(]{0}[\\.\\s\\n\\r>,<(){{]", typeName);
}
else {
string typeName = type.Name.Split('`')[0].Replace("Attribute", "");
match = string.Format("[!|&\\]\\[\\.\\s<(]{0}[\\.\\s\\n\\r>,<(){{\\]]", typeName);
// check Extension Methods
if (Regex.IsMatch(code, string.Format("this\\s{0}\\s", typeName))) {
foreach (var file in code2FileDic[type]) {
foreach (var baseReference in references.Where(c => c.fileGuid == file)) {
baseReference.referenceGids.Add(guid);
}
}
}
}
if (Regex.IsMatch(code, match)) {
var typeGuids = code2FileDic[type];
foreach (var typeGuid in typeGuids) {
if (referenceList.Contains(typeGuid) == false) {
referenceList.Add(typeGuid);
}
}
}
}
}
void CollectionCustomEditorClasses(IEnumerable<System.Type> types) {
foreach (var type in types) {
if (code2FileDic.ContainsKey(type) == false) {
continue;
}
var attributes = type.GetCustomAttributes(typeof(CustomEditor), true);
foreach (var attribute in attributes) {
if (attribute is CustomEditor == false) {
continue;
}
var customEditor = attribute as CustomEditor;
var customEditorReferenceTypeField = typeof(CustomEditor).GetField("m_InspectedType", BindingFlags.Instance | BindingFlags.NonPublic);
var customEditorReferenceType = (System.Type)customEditorReferenceTypeField.GetValue(customEditor);
if (code2FileDic.ContainsKey(customEditorReferenceType) == false) {
continue;
}
foreach (var filePath in code2FileDic[customEditorReferenceType]) {
if (references.Exists(c => c.fileGuid == filePath) == false) {
continue;
}
foreach (var refs in references.Where(c => c.fileGuid == filePath)) {
var list = refs.referenceGids;
list.AddRange(code2FileDic[type]);
}
}
}
}
}
}
}
+44
View File
@@ -0,0 +1,44 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Linq;
namespace MuHuaEditor {
[System.Serializable]
public class CollectionData {
public string fileGuid;
public string fileName;
public List<string> referenceGids = new List<string>();
public DateTime timeStamp;
}
[System.Serializable]
public class TypeDate {
public string guid;
public string fileName;
public DateTime timeStamp;
public List<string> typeFullName = new List<string>();
public string assemblly;
public void Add(Type addtype) {
assemblly = addtype.Assembly.FullName;
var typeName = addtype.FullName;
if (typeFullName.Contains(typeName) == false) {
typeFullName.Add(typeName);
}
}
public Type[] types {
get {
return typeFullName.Select(c => Type.GetType(c)).ToArray();
}
}
}
public interface IReferenceCollection {
void CollectionFiles();
void Init(List<CollectionData> refs);
}
}
@@ -0,0 +1,215 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using System.IO;
using System.Linq;
namespace MuHuaEditor {
public class FindUnusedAssetsWindow : EditorWindow {
AssetCollector collection = new AssetCollector();
List<DeleteAsset> deleteAssets = new List<DeleteAsset>();
Vector2 scroll;
[MenuItem("Window/Delete Unused Assets/only resource", false, 50)]
static void InitWithoutCode() {
var window = FindUnusedAssetsWindow.CreateInstance<FindUnusedAssetsWindow>();
window.collection.useCodeStrip = false;
window.collection.Collection(new string[] { "Assets" });
window.CopyDeleteFileList(window.collection.deleteFileList);
window.Show();
}
[MenuItem("Window/Delete Unused Assets/unused by editor", false, 51)]
static void InitWithout() {
var window = FindUnusedAssetsWindow.CreateInstance<FindUnusedAssetsWindow>();
window.collection.Collection(new string[] { "Assets" });
window.CopyDeleteFileList(window.collection.deleteFileList);
window.Show();
}
[MenuItem("Window/Delete Unused Assets/unused by game", false, 52)]
static void Init() {
FindUnusedAssetsWindow window = CreateInstance<FindUnusedAssetsWindow>();
window.collection.saveEditorExtensions = false;
window.collection.Collection(new string[] { "Assets" });
window.CopyDeleteFileList(window.collection.deleteFileList);
window.Show();
}
// [MenuItem("Assets/Delete Unused Assets/unused by editor", false, 52)]
// static void InitAssets ()
// {
// var paths = Selection.objects
// .Select(c=>AssetDatabase.GetAssetPath(c))
// .Where(c=>Directory.Exists(c));
// if( paths.Any(c=> string.IsNullOrEmpty(c) ) ){
// return;
// }
//
// var window = FindUnusedAssetsWindow.CreateInstance<FindUnusedAssetsWindow> ();
// window.collection.Collection (paths.ToArray());
// window.CopyDeleteFileList (window.collection.deleteFileList);
//
// window.Show ();
// }
//
// [MenuItem("Assets/Delete Unused Assets/unused by editor", true)]
// static bool InitAssetsA ()
// {
// var paths = Selection.objects
// .Select(c=>AssetDatabase.GetAssetPath(c))
// .Where(c=>Directory.Exists(c));
// return ! paths.Any(c=> string.IsNullOrEmpty(c) );
// }
[MenuItem("Assets/Delete Unused Assets/unused only resources", false, 52)]
static void InitAssetsOnlyResources() {
var paths = Selection.objects
.Select(c => AssetDatabase.GetAssetPath(c))
.Where(c => Directory.Exists(c));
if (paths.Any(c => string.IsNullOrEmpty(c))) {
return;
}
var window = FindUnusedAssetsWindow.CreateInstance<FindUnusedAssetsWindow>();
window.collection.useCodeStrip = false;
window.collection.Collection(paths.ToArray());
window.CopyDeleteFileList(window.collection.deleteFileList);
window.Show();
}
[MenuItem("Assets/Delete Unused Assets/unused only resources", true)]
static bool InitAssetsOnlyResourcesA() {
var paths = Selection.objects
.Select(c => AssetDatabase.GetAssetPath(c))
.Where(c => Directory.Exists(c));
return !paths.Any(c => string.IsNullOrEmpty(c));
}
[MenuItem("Window/Delete Unused Assets/Clear cache")]
static void ClearCache() {
File.Delete(AssetCollector.exportXMLPath);
File.Delete(ClassReferenceCollection.xmlPath);
EditorUtility.DisplayDialog("clear file", "clear file", "OK");
}
void OnGUI() {
using (var horizonal = new EditorGUILayout.HorizontalScope("box")) {
EditorGUILayout.LabelField("delete unreference assets from buildsettings and resources");
}
using (var scrollScope = new EditorGUILayout.ScrollViewScope(scroll)) {
scroll = scrollScope.scrollPosition;
foreach (var asset in deleteAssets) {
if (string.IsNullOrEmpty(asset.path)) {
continue;
}
using (var horizonal = new EditorGUILayout.HorizontalScope()) {
asset.isDelete = EditorGUILayout.Toggle(asset.isDelete, GUILayout.Width(20));
var icon = AssetDatabase.GetCachedIcon(asset.path);
GUILayout.Label(icon, GUILayout.Width(20), GUILayout.Height(20));
if (GUILayout.Button(asset.path, EditorStyles.largeLabel)) {
Selection.activeObject = AssetDatabase.LoadAssetAtPath<Object>(asset.path);
}
}
}
}
using (var horizonal = new EditorGUILayout.HorizontalScope("box")) {
EditorGUILayout.Space();
if (GUILayout.Button("Exclude from Project", GUILayout.Width(160)) && deleteAssets.Count != 0) {
EditorApplication.delayCall += Exclude;
}
}
}
void Exclude() {
RemoveFiles();
Close();
}
static void CleanDir() {
RemoveEmptyDirectry("Assets");
AssetDatabase.Refresh();
}
void CopyDeleteFileList(IEnumerable<string> deleteFileList) {
foreach (var asset in deleteFileList) {
var filePath = AssetDatabase.GUIDToAssetPath(asset);
if (string.IsNullOrEmpty(filePath) == false) {
deleteAssets.Add(new DeleteAsset() { path = filePath });
}
}
}
void RemoveFiles() {
try {
string exportDirectry = "BackupUnusedAssets";
Directory.CreateDirectory(exportDirectry);
var files = deleteAssets.Where(item => item.isDelete == true).Select(item => item.path).ToArray();
string backupPackageName = exportDirectry + "/package" + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".unitypackage";
EditorUtility.DisplayProgressBar("export package", backupPackageName, 0);
AssetDatabase.ExportPackage(files, backupPackageName);
int i = 0;
int length = deleteAssets.Count;
foreach (var assetPath in files) {
i++;
EditorUtility.DisplayProgressBar("delete unused assets", assetPath, (float)i / length);
AssetDatabase.DeleteAsset(assetPath);
if (File.Exists(assetPath)) {
File.Delete(assetPath);
}
}
EditorUtility.DisplayProgressBar("clean directory", "", 1);
foreach (var dir in Directory.GetDirectories("Assets")) {
RemoveEmptyDirectry(dir);
}
System.Diagnostics.Process.Start(exportDirectry);
AssetDatabase.Refresh();
}
catch (System.Exception e) {
Debug.Log(e.Message);
}
finally {
EditorUtility.ClearProgressBar();
}
}
static void RemoveEmptyDirectry(string path) {
var dirs = Directory.GetDirectories(path);
foreach (var dir in dirs) {
RemoveEmptyDirectry(dir);
}
var files = Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly).Where(item => Path.GetExtension(item) != ".meta");
if (files.Count() == 0 && Directory.GetDirectories(path).Count() == 0) {
var metaFile = AssetDatabase.GetTextMetaFilePathFromAssetPath(path);
UnityEditor.FileUtil.DeleteFileOrDirectory(path);
UnityEditor.FileUtil.DeleteFileOrDirectory(metaFile);
}
}
class DeleteAsset {
public bool isDelete = true;
public string path;
}
}
}
@@ -0,0 +1,16 @@
{
"name": "MuHuaEditor.Cleaner",
"rootNamespace": "",
"references": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: be9939ebdb612cb4791a5cf10ba193a1
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,95 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
namespace MuHuaEditor {
public class ShaderReferenceCollection : IReferenceCollection {
// shader name / shader file guid
public Dictionary<string, string> shaderFileList = new Dictionary<string, string>();
private List<CollectionData> references = new List<CollectionData>();
public void Init(List<CollectionData> refs) {
references = refs;
}
public void CollectionFiles() {
CollectionShaderFiles();
CheckReference();
}
void CollectionShaderFiles() {
var shaderFiles = Directory.GetFiles("Assets", "*.shader", SearchOption.AllDirectories);
foreach (var shaderFilePath in shaderFiles) {
var code = File.ReadAllText(shaderFilePath);
var match = Regex.Match(code, "Shader \"(?<name>.*)\"");
if (match.Success) {
var shaderName = match.Groups["name"].ToString();
if (shaderFileList.ContainsKey(shaderName) == false) {
shaderFileList.Add(shaderName, AssetDatabase.AssetPathToGUID(shaderFilePath));
}
}
}
var cgFiles = Directory.GetFiles("Assets", "*.cg", SearchOption.AllDirectories);
foreach (var cgFilePath in cgFiles) {
var file = Path.GetFileName(cgFilePath);
shaderFileList.Add(file, cgFilePath);
}
var cgincFiles = Directory.GetFiles("Assets", "*.cginc", SearchOption.AllDirectories);
foreach (var cgincPath in cgincFiles) {
var file = Path.GetFileName(cgincPath);
if (shaderFileList.ContainsKey(file) == false) {
shaderFileList.Add(file, cgincPath);
}
}
}
void CheckReference() {
foreach (var shader in shaderFileList) {
var shaderFilePath = AssetDatabase.GUIDToAssetPath(shader.Value);
if (File.Exists(shaderFilePath) == false) {
continue;
}
var guid = shader.Value;
List<string> referenceList = null;
CollectionData reference = null;
if (references.Exists(c => c.fileGuid == guid) == false) {
referenceList = new List<string>();
reference = new CollectionData() {
fileGuid = guid,
referenceGids = referenceList,
};
references.Add(reference);
}
else {
reference = references.Find(c => c.fileGuid == guid);
referenceList = reference.referenceGids;
}
reference.timeStamp = File.GetLastWriteTime(AssetDatabase.GUIDToAssetPath(guid));
var code = ClassReferenceCollection.StripComment(File.ReadAllText(shaderFilePath));
foreach (var checkingShaderName in shaderFileList.Keys) {
if (checkingShaderName == shader.Key) {
continue;
}
if (code.IndexOf(checkingShaderName) != -1 && shaderFileList.ContainsKey(checkingShaderName)) {
var fileGuid = shaderFileList[checkingShaderName];
if (referenceList.Contains(fileGuid) == false) {
referenceList.Add(fileGuid);
}
}
}
}
}
}
}
+11
View File
@@ -0,0 +1,11 @@
{
"name": "muhua-cleaner",
"version": "1.0.0",
"displayName": "MuHua Cleaner",
"description": "\u8d44\u6e90\u6e05\u7406\u5de5\u5177\u5305",
"author": {
"name": "MuHua",
"email": "muhua233@qq.com"
},
"type": "tool"
}
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3e29d1e3e75ca7c468c288a53a519e8f
PackageManifestImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4fd2ab8e94f19634192c44036ad157f8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2470008fd80a4a44188e8e1780890bb0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8fa54f7600ab24240b9dbf8eb4eb9289
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,51 @@
.scrollview {
flex-grow: 1;
}
.scrollview-viewport {
background-color: rgba(255, 255, 255, 0.6);
overflow: hidden;
margin-right: 30px;
margin-bottom: 30px;
flex-grow: 1;
}
.scrollview-container {
background-color: rgba(0, 0, 0, 0.2);
transition-duration: 0.1s;
flex-direction: column;
align-self: flex-start;
flex-shrink: 0;
width: 100%;
}
.scrollview-horizontal-scroller {
height: 30px;
width: auto;
background-color: rgb(255, 255, 255);
position: absolute;
left: 0;
right: 30px;
bottom: 0;
}
.scrollview-horizontal-scroller-dragger {
width: 30px;
height: 100%;
background-color: rgb(255, 141, 141);
}
.scrollview-vertical-scroller {
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 30px;
background-color: rgb(255, 255, 255);
}
.scrollview-vertical-scroller-dragger {
background-color: rgb(255, 126, 126);
width: 100%;
height: 30px;
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 61f5023e45bbae04b90e5ef23337cdde
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0
@@ -0,0 +1,31 @@
<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="False">
<Style src="project://database/Assets/MuHua/UITool/UIScrollView/ScrollView.uss?fileID=7433441132597879392&amp;guid=d8db2d69206657346a4fe9aebc592327&amp;type=3#ScrollView" />
<ui:VisualElement name="ScrollView" class="scrollview" style="width: 350px; height: 450px;">
<ui:VisualElement name="Viewport" class="scrollview-viewport">
<ui:VisualElement name="Container" class="scrollview-container" style="width: 1000px; height: 1000px;">
<ui:Button text="1" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="2" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="3" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="4" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="5" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="6" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="7" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="8" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="9" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="10" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="ScrollerHorizontal" class="scrollview-horizontal-scroller">
<ui:VisualElement name="Dragger" class="scrollview-horizontal-scroller-dragger" />
</ui:VisualElement>
<ui:VisualElement name="ScrollerVertical" class="scrollview-vertical-scroller">
<ui:VisualElement name="Dragger" class="scrollview-vertical-scroller-dragger" />
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 26958eee1793a4748af56b3e45720dd3
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
@@ -0,0 +1,31 @@
<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="False">
<Style src="project://database/Assets/UI%20Toolkit/Component/ScrollView/ScrollView.uss?fileID=7433441132597879392&amp;guid=d8db2d69206657346a4fe9aebc592327&amp;type=3#ScrollView" />
<ui:VisualElement name="ScrollView" class="scrollview">
<ui:VisualElement name="Viewport" class="scrollview-viewport" style="margin-right: 0;">
<ui:VisualElement name="Container" class="scrollview-container" style="height: 100%; width: auto; flex-direction: row;">
<ui:Button text="1" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="2" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="3" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="4" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="5" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="6" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="7" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="8" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="9" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="10" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="ScrollerHorizontal" class="scroller-horizontal scrollview-horizontal-scroller" style="right: 0;">
<ui:VisualElement name="Dragger" class="scroller-horizontal-dragger scrollview-horizontal-scroller-dragger" />
</ui:VisualElement>
<ui:VisualElement name="ScrollerVertical" class="scroller-vertical scrollview-vertical-scroller" style="display: none;">
<ui:VisualElement name="Dragger" class="scroller-vertical-dragger scrollview-vertical-scroller-dragger" />
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 82e73952e577f914ba9e5e838e551eee
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
@@ -0,0 +1,22 @@
<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="False">
<Style src="project://database/Assets/UI%20Toolkit/Component/ScrollView/ScrollView.uss?fileID=7433441132597879392&amp;guid=d8db2d69206657346a4fe9aebc592327&amp;type=3#ScrollView" />
<ui:VisualElement name="ScrollView" class="scrollview">
<ui:VisualElement name="Viewport" class="scrollview-viewport" style="margin-right: 30px; margin-bottom: 0;">
<ui:VisualElement name="Container" class="scrollview-container">
<ui:Label tabindex="-1" text="Label" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Button text="Button" parse-escape-sequences="true" display-tooltip-when-elided="true" />
<ui:Toggle label="Toggle" />
<ui:Toggle label="Toggle" />
<ui:DropdownField label="Dropdown" />
<ui:TextField picking-mode="Ignore" label="Text Field" value="filler text" />
<ui:FloatField label="Float Field" value="42.2" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="ScrollerHorizontal" class="scroller-horizontal scrollview-horizontal-scroller" style="display: none;">
<ui:VisualElement name="Dragger" class="scroller-horizontal-dragger scrollview-horizontal-scroller-dragger" />
</ui:VisualElement>
<ui:VisualElement name="ScrollerVertical" class="scroller-vertical scrollview-vertical-scroller">
<ui:VisualElement name="Dragger" class="scroller-vertical-dragger scrollview-vertical-scroller-dragger" />
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 5019a8e69a4b8a14dae223bf68a5d58b
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 718a00c62e6f62349bad59995b2b226f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,23 @@
.scroller-horizontal {
width: 100%;
height: 30px;
background-color: rgb(255, 255, 255);
}
.scroller-horizontal-dragger {
background-color: rgb(255, 126, 126);
width: 30px;
height: 100%;
}
.scroller-vertical {
width: 30px;
height: 100%;
background-color: rgb(255, 255, 255);
}
.scroller-vertical-dragger {
background-color: rgb(255, 126, 126);
width: 100%;
height: 30px;
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 89a954f4160037542a9ebaa342d7996b
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0
@@ -0,0 +1,9 @@
<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="False">
<ui:Template name="ScrollerHorizontal" src="project://database/Assets/UI%20Toolkit/Component/Scroller/ScrollerHorizontal.uxml?fileID=9197481963319205126&amp;guid=5580a1adea643f747860b3cb601e12c5&amp;type=3#ScrollerHorizontal" />
<ui:Template name="ScrollerVertical" src="project://database/Assets/UI%20Toolkit/Component/Scroller/ScrollerVertical.uxml?fileID=9197481963319205126&amp;guid=d866b7570e7b3e642bced1d83309f5bf&amp;type=3#ScrollerVertical" />
<Style src="project://database/Assets/UI%20Toolkit/Component/Scroller/Scroller.uss?fileID=7433441132597879392&amp;guid=fa60433f4fc03c34e8b51e6a8c9b32db&amp;type=3#Scroller" />
<ui:Instance template="ScrollerHorizontal" name="ScrollerHorizontal" />
<ui:VisualElement style="flex-grow: 1; flex-direction: row;">
<ui:Instance template="ScrollerVertical" name="ScrollerVertical" />
</ui:VisualElement>
</ui:UXML>
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 8a810491179415340beedc045b3483e5
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
@@ -0,0 +1,5 @@
<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="False">
<ui:VisualElement class="scroller-horizontal">
<ui:VisualElement name="Dragger" class="scroller-horizontal-dragger" />
</ui:VisualElement>
</ui:UXML>
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: f1bfec9d00f10de43aaad2c429bacb75
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
@@ -0,0 +1,6 @@
<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="False">
<Style src="project://database/Assets/UI%20Toolkit/Component/Scroller/Scroller.uss?fileID=7433441132597879392&amp;guid=fa60433f4fc03c34e8b51e6a8c9b32db&amp;type=3#Scroller" />
<ui:VisualElement class="scroller-vertical">
<ui:VisualElement name="Dragger" class="scroller-vertical-dragger" />
</ui:VisualElement>
</ui:UXML>
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 90830e0c8de05234ab840f6226d13f31
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3eba862f5d8d48d45a14487fa58ac33c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,6 @@
@import url("unity-theme://default");
@import url("/Packages/muhua-tools/Assets/Component/Scroller/Scroller.uss");
@import url("/Packages/muhua-tools/Assets/Component/ScrollView/ScrollView.uss");
VisualElement {}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b270977e43076504c96c78f29c14a621
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12388, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 84d07484531517b439b3fcab64e4e683
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,23 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using MuHua;
namespace MuHuaEditor {
/// <summary>
/// 定义对带有 `CustomLabelAttribute` 特性的字段的面板内容的绘制行为。
/// </summary>
[CustomPropertyDrawer(typeof(CustomLabelAttribute))]
public class CustomLabelDrawer : PropertyDrawer {
private GUIContent _label = null;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
if (_label == null) {
string name = (attribute as CustomLabelAttribute).name;
_label = new GUIContent(name);
}
EditorGUI.PropertyField(position, property, _label);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc3616839f041cc4d929eb2fc85d09ea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+18
View File
@@ -0,0 +1,18 @@
{
"name": "MuHuaEditor",
"rootNamespace": "",
"references": [
"GUID:b88cc9b1727cc3a45a42964e99e119c1"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 37896a819dacc814aaaa2b9e188161a0
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+70
View File
@@ -0,0 +1,70 @@
using UnityEditor;
using UnityEngine;
using MuHua;
namespace MuHuaEditor {
[CustomPropertyDrawer(typeof(SceneNameAttribute))]
public class SceneNameDrawer : PropertyDrawer {
int sceneIndex = -1;
GUIContent[] sceneNames;
readonly string[] scenePathSplit = { "/", ".unity" };
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
if (EditorBuildSettings.scenes.Length == 0) return;
if (sceneIndex == -1)
GetSceneNameArray(property);
int oldIndex = sceneIndex;
sceneIndex = EditorGUI.Popup(position, label, sceneIndex, sceneNames);
if (oldIndex != sceneIndex)
property.stringValue = sceneNames[sceneIndex].text;
}
private void GetSceneNameArray(SerializedProperty property) {
var scenes = EditorBuildSettings.scenes;
//初始化数组
sceneNames = new GUIContent[scenes.Length];
for (int i = 0; i < sceneNames.Length; i++) {
string path = scenes[i].path;
string[] splitPath = path.Split(scenePathSplit, System.StringSplitOptions.RemoveEmptyEntries);
string sceneName = "";
if (splitPath.Length > 0) {
sceneName = splitPath[splitPath.Length - 1];
}
else {
sceneName = "(Deleted Scene)";
}
sceneNames[i] = new GUIContent(sceneName);
}
if (sceneNames.Length == 0) {
sceneNames = new[] { new GUIContent("Check Your Build Settings") };
}
if (!string.IsNullOrEmpty(property.stringValue)) {
bool nameFound = false;
for (int i = 0; i < sceneNames.Length; i++) {
if (sceneNames[i].text == property.stringValue) {
sceneIndex = i;
nameFound = true;
break;
}
}
if (nameFound == false)
sceneIndex = 0;
}
else {
sceneIndex = 0;
}
property.stringValue = sceneNames[sceneIndex].text;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e7f8370bd97b1c943b8584a1dcb97445
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 72ea4d93b15f5624c8c08e6b2f3e91ad
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MuHua {
/// <summary>
/// 使字段在Inspector中显示自定义的名称。
/// </summary>
public class CustomLabelAttribute : PropertyAttribute {
public string name;
/// <summary>
/// 使字段在Inspector中显示自定义的名称。
/// </summary>
/// <param name="name">自定义名称</param>
public CustomLabelAttribute(string name) {
this.name = name;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4a66bf3f2ee81534a8c80fe8acc60dd2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
using UnityEngine;
namespace MuHua {
public class SceneNameAttribute : PropertyAttribute {
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a21481fd2e1202d4e9fb30c3c1890874
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c687fc5835bae974e9dc3fab6bc13af3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -44,21 +44,32 @@ namespace MuHua {
element.generateVisualContent += ElementGenerateVisualContent;
if (sh == UIDirection.FromLeftToRight) { horizontal = new UIScroller(ScrollerHorizontal, canvas, sh); }
if (sh == UIDirection.FromRightToLeft) { horizontal = new UIScroller(ScrollerHorizontal, canvas, sh); }
if (sh == UIDirection.FromLeftToRight) {
horizontal = new UIScroller(ScrollerHorizontal, canvas, sh);
Viewport.style.flexDirection = FlexDirection.Row;
}
if (sh == UIDirection.FromRightToLeft) {
horizontal = new UIScroller(ScrollerHorizontal, canvas, sh);
Viewport.style.flexDirection = FlexDirection.RowReverse;
}
if (sv == UIDirection.FromTopToBottom) { vertical = new UIScroller(ScrollerVertical, canvas, sv); }
if (sv == UIDirection.FromBottomToTop) { vertical = new UIScroller(ScrollerVertical, canvas, sv); }
if (sv == UIDirection.FromTopToBottom) {
vertical = new UIScroller(ScrollerVertical, canvas, sv);
Viewport.style.flexDirection = FlexDirection.Column;
}
if (sv == UIDirection.FromBottomToTop) {
vertical = new UIScroller(ScrollerVertical, canvas, sv);
Viewport.style.flexDirection = FlexDirection.ColumnReverse;
}
//设置事件
// 设置事件
horizontal.ValueChanged += (x) => { UpdateValue(new Vector2(x, value.y)); };
vertical.ValueChanged += (y) => { UpdateValue(new Vector2(value.x, y)); };
Viewport.RegisterCallback<WheelEvent>(ViewportWheel);
Viewport.RegisterCallback<PointerDownEvent>(DraggerDown);
Viewport.RegisterCallback<MouseCaptureEvent>((evt) => isDrag = false);
// 释放
canvas.RegisterCallback<PointerUpEvent>((evt) => isDrag = false);
canvas.RegisterCallback<PointerLeaveEvent>((evt) => isDrag = false);
}
@@ -73,12 +84,9 @@ namespace MuHua {
/// <summary> 视图滚轮滑动 </summary>
private void ViewportWheel(WheelEvent evt) {
float wheel = Mathf.Clamp(evt.delta.y, -1, 1);
if (direction == UIDirection.Horizontal) {
UpdateValue(new Vector2(value.x - wheel, value.y));
}
else {
UpdateValue(new Vector2(value.x, value.y - wheel));
}
Vector2 offset = new Vector2(0, wheel);
if (direction == UIDirection.Horizontal) { offset = new Vector2(wheel, 0); }
UpdateValue(new Vector2(value.x, value.y) - offset);
}
private void DraggerDown(PointerDownEvent evt) {
isDrag = true;
@@ -111,6 +119,8 @@ namespace MuHua {
float x = offset.x / maxWidth;
float y = offset.y / maxHeight;
x *= sh == UIDirection.FromLeftToRight ? 1 : -1;
y *= sv == UIDirection.FromTopToBottom ? 1 : -1;
UpdateValue(new Vector2(x, y));
}
/// <summary> 更新值(0-1) </summary>
@@ -0,0 +1,117 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace MuHua {
/// <summary>
/// 滚动视图 - 垂直
/// </summary>
public class UIScrollViewV : ModuleUIPanel {
/// <summary> 绑定的画布 </summary>
public readonly VisualElement canvas;
/// <summary> 元素方向 </summary>
public readonly UIDirection direction;
/// <summary> 垂直滑块 </summary>
public readonly UIScroller vertical;
/// <summary> 值改变时 </summary>
public event Action<float> ValueChanged;
/// <summary>
/// 方向
/// </summary>
public enum UIDirection {
FromTopToBottom = 0,
FromBottomToTop = 1,
}
public float value;
public bool isDrag;
public Vector3 originalPosition;
public Vector3 pointerPosition;
public VisualElement Viewport => Q<VisualElement>("Viewport");
public VisualElement Container => Q<VisualElement>("Container");
public VisualElement ScrollerVertical => Q<VisualElement>("ScrollerVertical");
public UIScrollViewV(VisualElement element, VisualElement canvas, UIDirection direction) : base(element) {
this.canvas = canvas;
this.direction = direction;
if (direction == UIDirection.FromTopToBottom) {
// vertical = new UIScroller(ScrollerVertical, canvas, direction);
Viewport.style.flexDirection = FlexDirection.Column;
}
if (direction == UIDirection.FromBottomToTop) {
// vertical = new UIScroller(ScrollerVertical, canvas, direction);
Viewport.style.flexDirection = FlexDirection.ColumnReverse;
}
// 设置事件
vertical.ValueChanged += (y) => { UpdateValue(y); };
Viewport.RegisterCallback<WheelEvent>(ViewportWheel);
Viewport.RegisterCallback<PointerDownEvent>(DraggerDown);
Viewport.RegisterCallback<MouseCaptureEvent>((evt) => isDrag = false);
// 释放
canvas.RegisterCallback<PointerUpEvent>((evt) => isDrag = false);
canvas.RegisterCallback<PointerLeaveEvent>((evt) => isDrag = false);
// 视图原始更新
element.generateVisualContent += ElementGenerateVisualContent;
}
/// <summary> 原始更新 </summary>
private void ElementGenerateVisualContent(MeshGenerationContext context) {
float height = Mathf.Clamp01(Viewport.resolvedStyle.height / Container.resolvedStyle.height);
vertical.Dragger.style.height = Length.Percent(height * 100);
}
/// <summary> 滚轮滑动 </summary>
private void ViewportWheel(WheelEvent evt) {
float wheel = Mathf.Clamp(evt.delta.y, -1, 1);
UpdateValue(value - wheel);
}
/// <summary> 拖拽按下 </summary>
private void DraggerDown(PointerDownEvent evt) {
isDrag = true;
originalPosition = Container.transform.position;
Vector3 mousePosition = UITool.GetMousePosition();
pointerPosition = new Vector3(mousePosition.x, Screen.height - mousePosition.y);
}
/// <summary> 拖拽滑动 </summary>
private void Dragger() {
Vector3 mousePosition = UITool.GetMousePosition();
Vector3 differ = new Vector3(mousePosition.x, Screen.height - mousePosition.y) - pointerPosition;
Vector3 offset = differ + originalPosition;
float maxHeight = Viewport.resolvedStyle.height - Container.resolvedStyle.height;
float y = offset.y / maxHeight;
y *= direction == UIDirection.FromTopToBottom ? 1 : -1;
UpdateValue(y);
}
/// <summary> 滑动弹性 </summary>
private void SlidingElasticity() {
float original = value;
float max = Viewport.resolvedStyle.height < Container.resolvedStyle.height ? 1 : 0;
if (value < 0) { value = Mathf.Lerp(value, 0, Time.deltaTime * 10); }
if (value > max) { value = Mathf.Lerp(value, max, Time.deltaTime * 10); }
if (original != value) { UpdateValue(value); }
}
/// <summary> 更新状态 </summary>
public virtual void Update() {
vertical.Update();
SlidingElasticity();
if (isDrag) { Dragger(); }
}
/// <summary> 更新值(0-1) </summary>
public virtual void UpdateValue(float value, bool send = true) {
this.value = value;
if (send) { ValueChanged?.Invoke(value); }
float maxHeight = Viewport.resolvedStyle.height - Container.resolvedStyle.height;
float position = maxHeight * value;
position *= direction == UIDirection.FromTopToBottom ? 1 : -1;
Container.transform.position = new Vector3(0, position);
if (vertical.value != value) { vertical.UpdateValue(value, false); }
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ecfd61355ce764642865903953329f1e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a21c9c3bc30a9cf4091edd963a99f7af
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -41,8 +41,9 @@ namespace MuHua {
canvas.RegisterCallback<PointerUpEvent>((evt) => isDragger = false);
canvas.RegisterCallback<PointerLeaveEvent>((evt) => isDragger = false);
}
/// <summary> 拖拽元素 </summary>
private void DraggerDown(PointerDownEvent evt) => scrollerFunc.DraggerDown(evt);
/// <summary> 按下元素 </summary>
private void ElementDown(PointerDownEvent evt) => scrollerFunc.ElementDown(evt);
/// <summary> 更新状态 </summary>
public void Update() => scrollerFunc.Update();
@@ -52,17 +53,22 @@ namespace MuHua {
public abstract class UIScrollerFunc {
public readonly UIScroller scroller;
public UIScrollerFunc(UIScroller scroller) => this.scroller = scroller;
/// <summary> 拖拽元素 </summary>
public abstract void DraggerDown(PointerDownEvent evt);
/// <summary> 按下元素 </summary>
public abstract void ElementDown(PointerDownEvent evt);
/// <summary> 更新状态 </summary>
public abstract void Update();
/// <summary> 更新值(0-1) </summary>
public abstract void UpdateValue(float value, bool send = true);
}
/// <summary>
/// 滑块从左到右
/// </summary>
public class FromLeftToRight : UIScrollerFunc {
public FromLeftToRight(UIScroller scroller) : base(scroller) { }
public FromLeftToRight(UIScroller scroller) : base(scroller) {
scroller.element.style.flexDirection = FlexDirection.Row;
}
public override void DraggerDown(PointerDownEvent evt) {
scroller.isDragger = true;
scroller.originalPosition = scroller.Dragger.transform.position.x;
@@ -90,9 +96,13 @@ namespace MuHua {
scroller.Dragger.transform.position = new Vector3(x, 0);
}
}
/// <summary>
/// 滑块从右到左
/// </summary>
public class FromRightToLeft : UIScrollerFunc {
public FromRightToLeft(UIScroller scroller) : base(scroller) { }
public FromRightToLeft(UIScroller scroller) : base(scroller) {
scroller.element.style.flexDirection = FlexDirection.RowReverse;
}
public override void DraggerDown(PointerDownEvent evt) {
scroller.isDragger = true;
scroller.originalPosition = scroller.Dragger.transform.position.x;
@@ -120,9 +130,13 @@ namespace MuHua {
scroller.Dragger.transform.position = new Vector3(x, 0);
}
}
/// <summary>
/// 滑块从上到下
/// </summary>
public class FromTopToBottom : UIScrollerFunc {
public FromTopToBottom(UIScroller scroller) : base(scroller) { }
public FromTopToBottom(UIScroller scroller) : base(scroller) {
scroller.element.style.flexDirection = FlexDirection.Column;
}
public override void DraggerDown(PointerDownEvent evt) {
scroller.isDragger = true;
scroller.originalPosition = scroller.Dragger.transform.position.y;
@@ -150,9 +164,13 @@ namespace MuHua {
scroller.Dragger.transform.position = new Vector3(0, y);
}
}
/// <summary>
/// 滑块从下到上
/// </summary>
public class FromBottomToTop : UIScrollerFunc {
public FromBottomToTop(UIScroller scroller) : base(scroller) { }
public FromBottomToTop(UIScroller scroller) : base(scroller) {
scroller.element.style.flexDirection = FlexDirection.ColumnReverse;
}
public override void DraggerDown(PointerDownEvent evt) {
scroller.isDragger = true;
scroller.originalPosition = scroller.Dragger.transform.position.y;
@@ -0,0 +1,22 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace MuHua {
/// <summary>
/// 滚动条 - 垂直
/// </summary>
public class UIScrollerV : MonoBehaviour {
// Start is called before the first frame update
void Start() {
}
// Update is called once per frame
void Update() {
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e1f4e6e2ba12e0b46b1ec2698a680e87
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+6
View File
@@ -285,6 +285,12 @@
"source": "embedded",
"dependencies": {}
},
"muhua-cleaner": {
"version": "file:Cleaner",
"depth": 0,
"source": "embedded",
"dependencies": {}
},
"muhua-follow-tag": {
"version": "file:FollowTag",
"depth": 0,