/// <summary>
        /// 动画控制器比较特殊,不能通过序列化得到
        /// </summary>
        /// <param name="info"></param>
        /// <param name="o"></param>
        private static void AnalyzeObjectReference2(AssetBundleFileInfo info, Object o)
        {
            AnimatorController ac = o as AnimatorController;

            if (ac)
            {
#if UNITY_5 || UNITY_5_3_OR_NEWER
                foreach (var clip in ac.animationClips)
                {
                    AnalyzeObjectReference(info, clip);
                }
#else
                List <State> list = new List <State>();
                for (int i = 0; i < ac.layerCount; i++)
                {
                    AnimatorControllerLayer layer = ac.GetLayer(i);
                    list.AddRange(AnimatorStateMachine_StatesRecursive(layer.stateMachine));
                }
                foreach (State state in list)
                {
                    var clip = state.GetMotion() as AnimationClip;
                    if (clip)
                    {
                        AnalyzeObjectReference(info, clip);
                    }
                }
#endif
            }
        }
        /// <summary>
        /// 直接递归所有文件
        /// </summary>
        /// <param name="directoryPath"></param>
        /// <returns></returns>
        private static List <AssetBundleFileInfo> AnalyzAllFiles(string directoryPath)
        {
            List <AssetBundleFileInfo> infos = new List <AssetBundleFileInfo>();
            string bom = "Unity";

            char[]   flag  = new char[5];
            string[] files = Directory.GetFiles(directoryPath, "*", SearchOption.AllDirectories);
            foreach (var file in files)
            {
                using (StreamReader streamReader = new StreamReader(file))
                {
                    if (streamReader.Read(flag, 0, flag.Length) == flag.Length && new string(flag) == bom)
                    {
                        AssetBundleFileInfo info = new AssetBundleFileInfo
                        {
                            name          = file.Substring(directoryPath.Length + 1),
                            path          = file,
                            rootPath      = directoryPath,
                            size          = streamReader.BaseStream.Length,
                            directDepends = new string[] { },
                            allDepends    = new string[] { }
                        };
                        infos.Add(info);
                    }
                }
            }

            return(infos);
        }
        /// <summary>
        /// 分析对象的引用
        /// </summary>
        /// <param name="info"></param>
        /// <param name="o"></param>
        public static void AnalyzeObjectReference(AssetBundleFileInfo info, Object o)
        {
            if (o == null || info.objDict.ContainsKey(o))
            {
                return;
            }

            var serializedObject = new SerializedObject(o);

            info.objDict.Add(o, serializedObject);

            if (inspectorMode == null)
            {
                inspectorMode = typeof(SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance);
            }
            inspectorMode.SetValue(serializedObject, InspectorMode.Debug, null);

            var it = serializedObject.GetIterator();

            while (it.NextVisible(true))
            {
                if (it.propertyType == SerializedPropertyType.ObjectReference && it.objectReferenceValue != null)
                {
                    AnalyzeObjectReference(info, it.objectReferenceValue);
                }
            }

            // 只能用另一种方式获取的引用
            AnalyzeObjectReference2(info, o);
        }
 public static void AnalyzeObjectsCompleted(AssetBundleFileInfo info)
 {
     foreach (var kv in info.objDict)
     {
         AssetBundleFilesAnalyzeObject.ObjectAddToFileInfo(kv.Key, kv.Value, info);
         kv.Value.Dispose();
     }
     info.objDict.Clear();
 }
Exemple #5
0
        public void AddBundleSceneInfo(AssetBundleFileInfo info, string[] scenePaths)
        {
#if UNITY_5_4_OR_NEWER
            foreach (var scenePath in scenePaths)
            {
                m_BundleSceneInfos.Enqueue(new BundleSceneInfo()
                {
                    fileInfo  = info,
                    sceneName = Path.GetFileNameWithoutExtension(scenePath),
                    scenePath = scenePath
                });
            }
#endif
        }
        /// <summary>
        /// 分析Unity5方式的依赖构成
        /// </summary>
        /// <param name="directoryPath"></param>
        /// <returns></returns>
        private static List <AssetBundleFileInfo> AnalyzeManifestDepend(string directoryPath)
        {
            string manifestName = Path.GetFileName(directoryPath);
            string manifestPath = Path.Combine(directoryPath, manifestName);

            if (!File.Exists(manifestPath))
            {
                Debug.LogWarning(manifestPath + " is not exists! Use AnalyzAllFiles ...");
                return(null);
            }
#if UNITY_5_3_OR_NEWER
            AssetBundle manifestAb = AssetBundle.LoadFromFile(manifestPath);
#else
            AssetBundle manifestAb = AssetBundle.CreateFromMemoryImmediate(File.ReadAllBytes(manifestPath));
#endif
            if (!manifestAb)
            {
                Debug.LogError(manifestPath + " ab load faild!");
                return(null);
            }

            List <AssetBundleFileInfo> infos = new List <AssetBundleFileInfo>();
#if UNITY_5 || UNITY_5_3_OR_NEWER
            AssetBundleManifest assetBundleManifest = manifestAb.LoadAsset <AssetBundleManifest>("assetbundlemanifest");
            var bundles = assetBundleManifest.GetAllAssetBundles();
            foreach (var bundle in bundles)
            {
                string path = Path.Combine(directoryPath, bundle);
                AssetBundleFileInfo info = new AssetBundleFileInfo
                {
                    name          = bundle,
                    path          = path,
                    rootPath      = directoryPath,
                    size          = new FileInfo(path).Length,
                    directDepends = assetBundleManifest.GetDirectDependencies(bundle),
                    allDepends    = assetBundleManifest.GetAllDependencies(bundle)
                };
                infos.Add(info);
            }
#endif
            manifestAb.Unload(true);
            return(infos);
        }
        private static void FillAssetByType(AssetBundleFileInfo info, string type, ExcelWorksheet ws, ref int startRow)
        {
            int count = info.GetAssetCount(type);

            if (count == 0)
            {
                return;
            }

            startRow++;
            ws.Cells[startRow, 1].Value = type + " (" + count + ")";
            SetRangeStyle(ws.Cells[startRow, 1, startRow, 4]);
            Color redColor = ColorTranslator.FromHtml("#FF0049");

            int startCol = 1;

            foreach (var fileInfo in info.assets)
            {
                if (fileInfo.type == type)
                {
                    if (startCol == 1)
                    {
                        startRow++;
                    }

                    ws.Cells[startRow, startCol].Value     = fileInfo.name;
                    ws.Cells[startRow, startCol].Hyperlink = fileInfo.detailHyperLink;

                    // 冗余则红色显示
                    if (fileInfo.includedBundles.Count > 1 && fileInfo.type != AssetFileInfoType.monoScript)
                    {
                        ws.Cells[startRow, startCol].Style.Font.Color.SetColor(redColor);
                    }

                    startCol++;
                    if (startCol > 4)
                    {
                        startCol = 1;
                    }
                }
            }
        }
        /// <summary>
        /// 分析脚本的引用(这只在脚本在工程里时才有效)
        /// </summary>
        /// <param name="info"></param>
        /// <param name="o"></param>
        public static void AnalyzeObjectComponent(AssetBundleFileInfo info, Object o)
        {
            var go = o as GameObject;

            if (!go)
            {
                return;
            }

            var components = go.GetComponentsInChildren <Component>(true);

            foreach (var component in components)
            {
                if (!component)
                {
                    continue;
                }

                AnalyzeObjectReference(info, component);
            }
        }
        private static void FillAssetDepends(AssetBundleFileInfo info, ExcelWorksheet ws, ref int startRow)
        {
            if (info.allDepends == null && info.beDepends == null)
            {
                return;
            }
            if (info.allDepends != null && info.beDepends != null &&
                info.allDepends.Length == 0 && info.beDepends.Length == 0)
            {
                return;
            }

            int rowAdd   = 0;
            int titleRow = ++startRow;

            if (info.allDepends != null && info.allDepends.Length != 0)
            {
                ws.Cells[titleRow, 3].Value = "它依赖哪些AssetBundle文件? (" + info.allDepends.Length + ")";
                SetRangeStyle(ws.Cells[titleRow, 3, titleRow, 4]);

                int dependRow = titleRow;
                foreach (var depend in info.allDepends)
                {
                    if (string.IsNullOrEmpty(depend))
                    {
                        continue;
                    }
                    dependRow++;
                    var dependInfo = AssetBundleFilesAnalyze.GetAssetBundleFileInfo(depend);
                    ws.Cells[dependRow, 3].Value               = dependInfo.name;
                    ws.Cells[dependRow, 3].Hyperlink           = dependInfo.detailHyperLink;
                    ws.Cells[dependRow, 3, dependRow, 4].Merge = true;
                }

                rowAdd = dependRow - titleRow;
            }

            if (info.beDepends != null && info.beDepends.Length != 0)
            {
                ws.Cells[titleRow, 1].Value = "哪些AssetBundle文件依赖它? (" + info.beDepends.Length + ")";
                SetRangeStyle(ws.Cells[titleRow, 1, titleRow, 2]);

                int dependRow = titleRow;
                foreach (var depend in info.beDepends)
                {
                    dependRow++;
                    var dependInfo = AssetBundleFilesAnalyze.GetAssetBundleFileInfo(depend);
                    ws.Cells[dependRow, 1].Value               = dependInfo.name;
                    ws.Cells[dependRow, 1].Hyperlink           = dependInfo.detailHyperLink;
                    ws.Cells[dependRow, 1, dependRow, 2].Merge = true;
                }

                int rowAdd2 = dependRow - titleRow;
                if (rowAdd2 > rowAdd)
                {
                    rowAdd = rowAdd2;
                }
            }

            startRow += rowAdd;
        }
Exemple #10
0
        public static void ObjectAddToFileInfo(Object o, SerializedObject serializedObject, AssetBundleFileInfo info)
        {
            if (!o)
            {
                return;
            }

            string name2 = o.name;
            string type  = o.GetType().ToString();

            if (type.StartsWith("UnityEngine."))
            {
                type = type.Substring(12);

                // 如果是内置的组件,就不当作是资源
                if (o as Component)
                {
                    return;
                }
            }
            else if (type == "UnityEditor.Animations.AnimatorController")
            {
                type = "AnimatorController";
            }
            else if (type == "UnityEditorInternal.AnimatorController")
            {
                type = "AnimatorController";
            }
            else if (type == "UnityEditor.MonoScript")
            {
                MonoScript ms    = o as MonoScript;
                string     type2 = ms.GetClass().ToString();
                if (type2.StartsWith("UnityEngine."))
                {
                    // 内置的脚本对象也不显示出来
                    return;
                }

                // 外部的组件脚本,保留下来
                type = "MonoScript";
            }
            else
            {
                // 外部的组件脚本,走上面的MonoScript
                if (o as Component)
                {
                    return;
                }
                // 外部的序列化对象,已经被脚本给分析完毕了,不需要再添加进来
                if (o as ScriptableObject)
                {
                    return;
                }

                Debug.LogError("What's this? " + type);
                return;
            }

            // 内建的资源排除掉
            string assetPath = AssetDatabase.GetAssetPath(o);

            if (!string.IsNullOrEmpty(assetPath))
            {
                return;
            }

            long guid;

            if (info.isScene)
            {
                // 场景的话,没法根据PathID来确定唯一性,那么就认为每个场景用到的资源都不一样
                guid = (info.name + name2 + type).GetHashCode();
            }
            else
            {
                SerializedProperty pathIdProp = serializedObject.FindProperty("m_LocalIdentfierInFile");
#if UNITY_5 || UNITY_5_3_OR_NEWER
                guid = pathIdProp.longValue;
#else
                guid = pathIdProp.intValue;
#endif
            }

            if (info.IsAssetContain(guid))
            {
                return;
            }

            AssetFileInfo info2 = AssetBundleFilesAnalyze.GetAssetFileInfo(guid);
            info2.name = name2;
            info2.type = type;
            info2.includedBundles.Add(info);
            if (info2.detailHyperLink == null)
            {
                // 初次创建对象时链接为空
                info2.detailHyperLink = new OfficeOpenXml.ExcelHyperLink(System.String.Empty, info2.name);
                info2.propertys       = AnalyzeObject(o, serializedObject, info.rootPath, info.name);
            }

            info.assets.Add(info2);
        }