From fbef706388cc634a580df19634b323f39a1cb885 Mon Sep 17 00:00:00 2001 From: hevinci Date: Thu, 10 Mar 2022 16:54:56 +0800 Subject: [PATCH] Update YooAsset --- .../AssetBundleBuilderTools.cs | 118 ++++++- Assets/YooAsset/Editor/EditorTools.cs | 325 +----------------- .../BundleInfo.cs | 0 .../BundleInfo.cs.meta | 0 Assets/YooAsset/Runtime/YooAssets.cs | 5 +- 5 files changed, 119 insertions(+), 329 deletions(-) rename Assets/YooAsset/Runtime/{AssetSystem => PatchSystem}/BundleInfo.cs (100%) rename Assets/YooAsset/Runtime/{AssetSystem => PatchSystem}/BundleInfo.cs.meta (100%) diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderTools.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderTools.cs index d37faa4..2216fc4 100644 --- a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderTools.cs +++ b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderTools.cs @@ -53,7 +53,7 @@ namespace YooAsset.Editor foreach (string assetPath in findAssets) { AnimatorController animator= AssetDatabase.LoadAssetAtPath(assetPath); - if (EditorTools.FindRedundantAnimationState(animator)) + if (FindRedundantAnimationState(animator)) { findCount++; Debug.LogWarning($"发现冗余的动画控制器:{assetPath}"); @@ -83,7 +83,7 @@ namespace YooAsset.Editor foreach (string assetPath in findAssets) { Material mat = AssetDatabase.LoadAssetAtPath(assetPath); - if (EditorTools.ClearMaterialUnusedProperty(mat)) + if (ClearMaterialUnusedProperty(mat)) { removedCount++; Debug.LogWarning($"材质球已被处理:{assetPath}"); @@ -97,5 +97,119 @@ namespace YooAsset.Editor else AssetDatabase.SaveAssets(); } + + + /// + /// 清理无用的材质球属性 + /// + private static bool ClearMaterialUnusedProperty(Material mat) + { + bool removeUnused = false; + SerializedObject so = new SerializedObject(mat); + SerializedProperty sp = so.FindProperty("m_SavedProperties"); + + sp.Next(true); + do + { + if (sp.isArray == false) + continue; + + for (int i = sp.arraySize - 1; i >= 0; --i) + { + var p1 = sp.GetArrayElementAtIndex(i); + if (p1.isArray) + { + for (int ii = p1.arraySize - 1; ii >= 0; --ii) + { + var p2 = p1.GetArrayElementAtIndex(ii); + var val = p2.FindPropertyRelative("first"); + if (mat.HasProperty(val.stringValue) == false) + { + Debug.Log($"Material {mat.name} remove unused property : {val.stringValue}"); + p1.DeleteArrayElementAtIndex(ii); + removeUnused = true; + } + } + } + else + { + var val = p1.FindPropertyRelative("first"); + if (mat.HasProperty(val.stringValue) == false) + { + Debug.Log($"Material {mat.name} remove unused property : {val.stringValue}"); + sp.DeleteArrayElementAtIndex(i); + removeUnused = true; + } + } + } + } + while (sp.Next(false)); + so.ApplyModifiedProperties(); + return removeUnused; + } + + /// + /// 查找动画控制器里冗余的动画状态机 + /// + private static bool FindRedundantAnimationState(AnimatorController animatorController) + { + if (animatorController == null) + return false; + + string assetPath = AssetDatabase.GetAssetPath(animatorController); + + // 查找使用的状态机名称 + List usedStateNames = new List(); + foreach (var layer in animatorController.layers) + { + foreach (var state in layer.stateMachine.states) + { + usedStateNames.Add(state.state.name); + } + } + + List allLines = new List(); + List stateIndexList = new List(); + using (StreamReader reader = File.OpenText(assetPath)) + { + string content; + while (null != (content = reader.ReadLine())) + { + allLines.Add(content); + if (content.StartsWith("AnimatorState:")) + { + stateIndexList.Add(allLines.Count - 1); + } + } + } + + List allStateNames = new List(); + foreach (var index in stateIndexList) + { + for (int i = index; i < allLines.Count; i++) + { + string content = allLines[i]; + content = content.Trim(); + if (content.StartsWith("m_Name")) + { + string[] splits = content.Split(':'); + string name = splits[1].TrimStart(' '); //移除前面的空格 + allStateNames.Add(name); + break; + } + } + } + + bool foundRedundantState = false; + foreach (var stateName in allStateNames) + { + if (usedStateNames.Contains(stateName) == false) + { + Debug.LogWarning($"发现冗余的动画文件:{assetPath}={stateName}"); + foundRedundantState = true; + } + } + return foundRedundantState; + } } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/EditorTools.cs b/Assets/YooAsset/Editor/EditorTools.cs index 3399aa3..3994922 100644 --- a/Assets/YooAsset/Editor/EditorTools.cs +++ b/Assets/YooAsset/Editor/EditorTools.cs @@ -16,52 +16,6 @@ namespace YooAsset.Editor /// public static class EditorTools { - #region NGUI - /// - /// Draw a distinctly different looking header label - /// - public static bool DrawHeader(string text) - { - return DrawHeader(text, text, false, true); - } - public static bool DrawHeader(string text, string key, bool forceOn, bool minimalistic) - { - bool state = EditorPrefs.GetBool(key, true); - - if (!minimalistic) GUILayout.Space(3f); - if (!forceOn && !state) GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f); - GUILayout.BeginHorizontal(); - GUI.changed = false; - - if (minimalistic) - { - if (state) text = "\u25BC" + (char)0x200a + text; - else text = "\u25BA" + (char)0x200a + text; - - GUILayout.BeginHorizontal(); - GUI.contentColor = EditorGUIUtility.isProSkin ? new Color(1f, 1f, 1f, 0.7f) : new Color(0f, 0f, 0f, 0.7f); - if (!GUILayout.Toggle(true, text, "PreToolbar2", GUILayout.MinWidth(20f))) state = !state; - GUI.contentColor = Color.white; - GUILayout.EndHorizontal(); - } - else - { - text = "" + text + ""; - if (state) text = "\u25BC " + text; - else text = "\u25BA " + text; - if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) state = !state; - } - - if (GUI.changed) EditorPrefs.SetBool(key, state); - - if (!minimalistic) GUILayout.Space(2f); - GUILayout.EndHorizontal(); - GUI.backgroundColor = Color.white; - if (!forceOn && !state) GUILayout.Space(3f); - return state; - } - #endregion - #region Assembly /// /// 调用私有的静态方法 @@ -205,7 +159,7 @@ namespace YooAsset.Editor } #endregion - #region 编辑器窗口 + #region EditorWindow public static void FocusUnitySceneWindow() { EditorWindow.FocusWindowIfItsOpen(); @@ -237,261 +191,6 @@ namespace YooAsset.Editor } #endregion - #region 引用关系 - /// - /// 获取场景里的克隆预制体 - /// - public static GameObject GetClonePrefabInScene(GameObject sourcePrefab) - { - GameObject[] findObjects = GameObject.FindObjectsOfType(); - if (findObjects.Length == 0) - return null; - - for (int i = 0; i < findObjects.Length; i++) - { - GameObject findObject = findObjects[i]; - -#if UNITY_2017_4 - // 判断对象是否为一个预制体的引用 - if (PrefabUtility.GetPrefabType(findObject) == PrefabType.PrefabInstance) - { - // 判断是否为同一个预制体 - Object source = PrefabUtility.GetPrefabParent(findObject); - if (source.GetInstanceID() == sourcePrefab.GetInstanceID()) - return findObject; - } -#else - // 判断对象是否为一个预制体的引用 - if (PrefabUtility.GetPrefabInstanceStatus(findObject) == PrefabInstanceStatus.Connected) - { - // 判断是否为同一个预制体 - Object source = PrefabUtility.GetCorrespondingObjectFromSource(findObject); - if (source.GetInstanceID() == sourcePrefab.GetInstanceID()) - return findObject; - } -#endif - } - - return null; //没有找到合适的对象 - } - - /// - /// 查找场景里的引用对象 - /// - public static void FindReferencesInScene(UnityEngine.Object to) - { - var referencedBy = new List(); - - GameObject[] findObjects = GameObject.FindObjectsOfType(); //注意:只能获取激活的GameObject - for (int j = 0; j < findObjects.Length; j++) - { - GameObject findObject = findObjects[j]; - -#if UNITY_2017_4 - // 如果Prefab匹配 - if (PrefabUtility.GetPrefabType(findObject) == PrefabType.PrefabInstance) - { - if (PrefabUtility.GetPrefabParent(findObject) == to) - referencedBy.Add(findObject); - } -#else - // 如果Prefab匹配 - if (PrefabUtility.GetPrefabInstanceStatus(findObject) == PrefabInstanceStatus.Connected) - { - if (PrefabUtility.GetCorrespondingObjectFromSource(findObject) == to) - referencedBy.Add(findObject); - } -#endif - - // 如果组件匹配 - Component[] components = findObject.GetComponents(); - for (int i = 0; i < components.Length; i++) - { - Component c = components[i]; - if (!c) continue; - - SerializedObject so = new SerializedObject(c); - SerializedProperty sp = so.GetIterator(); - while (sp.NextVisible(true)) - { - if (sp.propertyType == SerializedPropertyType.ObjectReference) - { - if (sp.objectReferenceValue != null && sp.objectReferenceValue == to) - referencedBy.Add(c.gameObject); - } - } - } - } - - if (referencedBy.Any()) - Selection.objects = referencedBy.ToArray(); - } - - /// - /// 查找场景里的引用对象 - /// - public static void FindReferencesInPrefabs(UnityEngine.Object to, GameObject[] sourcePrefabs) - { - var referencedBy = new List(); - - for (int j = 0; j < sourcePrefabs.Length; j++) - { - GameObject clonePrefab = GetClonePrefabInScene(sourcePrefabs[j]); - if (clonePrefab == null) - continue; - -#if UNITY_2017_4 - // 如果Prefab匹配 - if (PrefabUtility.GetPrefabParent(clonePrefab) == to) - referencedBy.Add(clonePrefab); -#else - // 如果Prefab匹配 - if (PrefabUtility.GetCorrespondingObjectFromSource(clonePrefab) == to) - referencedBy.Add(clonePrefab); -#endif - - // 如果组件匹配 - Component[] components = clonePrefab.GetComponentsInChildren(true); //GetComponents(); - for (int i = 0; i < components.Length; i++) - { - Component c = components[i]; - if (!c) continue; - - SerializedObject so = new SerializedObject(c); - SerializedProperty sp = so.GetIterator(); - while (sp.NextVisible(true)) - { - if (sp.propertyType == SerializedPropertyType.ObjectReference) - { - if (sp.objectReferenceValue != null && sp.objectReferenceValue == to) - referencedBy.Add(c.gameObject); - } - } - } - } - - if (referencedBy.Any()) - Selection.objects = referencedBy.ToArray(); - } - #endregion - - #region 材质球 - /// - /// 清理无用的材质球属性 - /// - public static bool ClearMaterialUnusedProperty(Material mat) - { - bool removeUnused = false; - SerializedObject so = new SerializedObject(mat); - SerializedProperty sp = so.FindProperty("m_SavedProperties"); - - sp.Next(true); - do - { - if (sp.isArray == false) - continue; - - for (int i = sp.arraySize - 1; i >= 0; --i) - { - var p1 = sp.GetArrayElementAtIndex(i); - if (p1.isArray) - { - for (int ii = p1.arraySize - 1; ii >= 0; --ii) - { - var p2 = p1.GetArrayElementAtIndex(ii); - var val = p2.FindPropertyRelative("first"); - if (mat.HasProperty(val.stringValue) == false) - { - Debug.Log($"Material {mat.name} remove unused property : {val.stringValue}"); - p1.DeleteArrayElementAtIndex(ii); - removeUnused = true; - } - } - } - else - { - var val = p1.FindPropertyRelative("first"); - if (mat.HasProperty(val.stringValue) == false) - { - Debug.Log($"Material {mat.name} remove unused property : {val.stringValue}"); - sp.DeleteArrayElementAtIndex(i); - removeUnused = true; - } - } - } - } - while (sp.Next(false)); - so.ApplyModifiedProperties(); - return removeUnused; - } - #endregion - - #region 动画控制器 - /// - /// 查找动画控制器里冗余的动画状态机 - /// - public static bool FindRedundantAnimationState(AnimatorController animatorController) - { - if (animatorController == null) - return false; - - string assetPath = AssetDatabase.GetAssetPath(animatorController); - - // 查找使用的状态机名称 - List usedStateNames = new List(); - foreach (var layer in animatorController.layers) - { - foreach (var state in layer.stateMachine.states) - { - usedStateNames.Add(state.state.name); - } - } - - List allLines = new List(); - List stateIndexList = new List(); - using (StreamReader reader = File.OpenText(assetPath)) - { - string content; - while (null != (content = reader.ReadLine())) - { - allLines.Add(content); - if (content.StartsWith("AnimatorState:")) - { - stateIndexList.Add(allLines.Count - 1); - } - } - } - - List allStateNames = new List(); - foreach (var index in stateIndexList) - { - for (int i = index; i < allLines.Count; i++) - { - string content = allLines[i]; - content = content.Trim(); - if (content.StartsWith("m_Name")) - { - string[] splits = content.Split(':'); - string name = splits[1].TrimStart(' '); //移除前面的空格 - allStateNames.Add(name); - break; - } - } - } - - bool foundRedundantState = false; - foreach (var stateName in allStateNames) - { - if (usedStateNames.Contains(stateName) == false) - { - Debug.LogWarning($"发现冗余的动画文件:{assetPath}={stateName}"); - foundRedundantState = true; - } - } - return foundRedundantState; - } - #endregion - #region 控制台 private static MethodInfo _clearConsoleMethod; private static MethodInfo ClearConsoleMethod @@ -518,28 +217,6 @@ namespace YooAsset.Editor #endregion #region 文件 - /// - /// 测试写入权限 - /// - public static bool HasWriteAccess(string directoryPath) - { - try - { - string tmpFilePath = Path.Combine(directoryPath, Path.GetRandomFileName()); - using (FileStream fs = new FileStream(tmpFilePath, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite)) - { - StreamWriter writer = new StreamWriter(fs); - writer.Write(0); - } - File.Delete(tmpFilePath); - return true; - } - catch - { - return false; - } - } - /// /// 创建文件所在的目录 /// diff --git a/Assets/YooAsset/Runtime/AssetSystem/BundleInfo.cs b/Assets/YooAsset/Runtime/PatchSystem/BundleInfo.cs similarity index 100% rename from Assets/YooAsset/Runtime/AssetSystem/BundleInfo.cs rename to Assets/YooAsset/Runtime/PatchSystem/BundleInfo.cs diff --git a/Assets/YooAsset/Runtime/AssetSystem/BundleInfo.cs.meta b/Assets/YooAsset/Runtime/PatchSystem/BundleInfo.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/AssetSystem/BundleInfo.cs.meta rename to Assets/YooAsset/Runtime/PatchSystem/BundleInfo.cs.meta diff --git a/Assets/YooAsset/Runtime/YooAssets.cs b/Assets/YooAsset/Runtime/YooAssets.cs index 98d672e..a49dcd0 100644 --- a/Assets/YooAsset/Runtime/YooAssets.cs +++ b/Assets/YooAsset/Runtime/YooAssets.cs @@ -194,8 +194,8 @@ namespace YooAsset /// 向网络端请求并更新补丁清单 /// /// 更新的资源版本号 - /// 超时时间 - public static UpdateManifestOperation UpdateManifestAsync(int updateResourceVersion, int timeout) + /// 超时时间(默认值:60秒) + public static UpdateManifestOperation UpdateManifestAsync(int updateResourceVersion, int timeout = 60) { if (_playMode == EPlayMode.EditorPlayMode) { @@ -221,7 +221,6 @@ namespace YooAsset } } - /// /// 获取资源版本号 ///