/// <summary>
 /// Asset打包构造函数
 /// </summary>
 /// <param name="asset">当前Asset</param>
 /// <param name="dependentasset">依赖使用当前Asset的Asset</param>
 public PackageAsset(Object asset, Object dependentasset = null)
 {
     mAssetObject = asset;
     if (mAssetObject == null)
     {
         mPackageAssetType          = AssetPackageType.E_INVALIDE;
         mAssetAssetBundleBuildRule = AssetABBuildRule.E_INVALIDE;
         mAssetPath             = string.Empty;
         mDependentPackageAsset = null;
         mInvalideBuildRuleList = null;
     }
     else
     {
         mAssetPath                 = AssetDatabase.GetAssetPath(mAssetObject);
         mPackageAssetType          = ABHelper.Singleton.getAssetPackageType(mAssetPath);
         mAssetAssetBundleBuildRule = ABHelper.Singleton.getAssetABBuildRule(mAssetPath);
         if (dependentasset != null)
         {
             mDependentPackageAsset = new PackageAsset(dependentasset);
         }
         else
         {
             mDependentPackageAsset = null;
         }
         mInvalideBuildRuleList = new List <AssetABBuildRule>();
         mInvalideBuildRuleList.Add(AssetABBuildRule.E_INVALIDE);
     }
 }
Example #2
0
        public void OnGUI()
        {
            CurrentPackage = (PackageImport)EditorGUILayout.ObjectField(CurrentPackage, typeof(PackageImport));

            var explorer = CurrentPackage.Explorer;

            foreach (var asset in explorer.Folders)
            {
                if (GUILayout.Button(asset.ToString()))
                {
                    CurrentAsset     = asset;
                    HasCurrentAsset  = true;
                    CurrentAssetJson = null;
                }
            }

            if (HasCurrentAsset)
            {
                if (string.IsNullOrEmpty(CurrentAssetJson))
                {
                    var bhvr = FindBhvr(CurrentAsset);
                    Debug.Log(bhvr);
                    CurrentAssetJson = Encoding.UTF8.GetString(bhvr.LoadData());
                }

                CurrentAssetJson = EditorGUILayout.TextArea(CurrentAssetJson);
            }
        }
Example #3
0
 /// <summary>
 /// 显示资源的最终AB名字结论
 /// </summary>
 /// <param name="pa"></param>
 private void showAssetABNameUI(PackageAsset pa)
 {
     GUILayout.BeginHorizontal();
     GUILayout.Label(string.Format("Asset path : {0}", pa.AssetPath), GUILayout.Width(700.0f));
     GUILayout.Label(string.Format("Asset BuildRule : {0}", pa.AssetAssetBundleBuildRule), GUILayout.Width(200.0f));
     GUILayout.Label(string.Format("AssetBundleName : {0}", pa.getPackageAssetABName()), GUILayout.Width(400.0f));
     GUILayout.EndHorizontal();
 }
 private PackageAsset()
 {
     mAssetObject               = null;
     mPackageAssetType          = AssetPackageType.E_INVALIDE;
     mAssetAssetBundleBuildRule = AssetABBuildRule.E_INVALIDE;
     mAssetPath             = string.Empty;
     mDependentPackageAsset = null;
     mInvalideBuildRuleList = null;
 }
Example #5
0
 public static PackageResource FindIcon(this PackageAsset asset)
 {
     for (int i = 0; i < asset.Resources.Length; i++)
     {
         if (asset.Resources[i].Name.EndsWith(".png", System.StringComparison.Ordinal))
         {
             return(asset.Resources[i]);
         }
     }
     return(default(PackageResource));
 }
Example #6
0
    /// <summary>
    /// 显示依赖资源信息UI
    /// </summary>
    /// <param name="assetpath"></param>
    /// <param name="dpassetpath"></param>
    private void showAssetDpUI(PackageAsset pa)
    {
        GUILayout.BeginHorizontal();
        var temppa = pa;

        GUILayout.Label(string.Format("{0}", Path.GetFileName(temppa.AssetPath)), GUILayout.Width(300.0f));
        while (temppa.DependentPackageAsset != null)
        {
            GUILayout.Label(" <- ", GUILayout.Width(30.0f));
            GUILayout.Label(string.Format("{0}", Path.GetFileName(temppa.DependentPackageAsset.AssetPath)), GUILayout.Width(300.0f));
            temppa = temppa.DependentPackageAsset;
        }
        GUILayout.EndHorizontal();
    }
Example #7
0
        List <PackageAsset> GetAssets(MemoryStream stream)
        {
            var allRecords = new List <PackageAsset>();

            var config = new global::ChoETL.ChoCSVRecordConfiguration
            {
                FileHeaderConfiguration = new global::ChoETL.ChoCSVFileHeaderConfiguration
                {
                    HasHeaderRecord = false,
                },
            };

            using (var reader = new StreamReader(stream))
                foreach (var record in new global::ChoETL.ChoCSVReader <PackageAssetData>(reader, config))
                {
                    var asset = new PackageAsset();
                    asset.Read(i => record.GetString(i));
                    allRecords.Add(asset);
                }

            return(allRecords);
        }
Example #8
0
 public void Render(PackageAsset asset)
 {
     Name.text    = asset.Root;
     Icon.texture = asset.FindIcon().LoadImage();
 }
        /// <summary>
        /// Get all of the dependencies in the specified directory set.
        /// </summary>
        private bool GetPackageAssetsCore(TextWriter textWriter, bool isDesktop, List <PackageAsset> packageAssets, params string[] directoryPaths)
        {
            var relativeNameMap = new Dictionary <string, PackageAsset>(PathComparer);
            var allGood         = true;

            IEnumerable <string> enumerateAssets(string directory, SearchOption searchOption = SearchOption.TopDirectoryOnly)
            {
                return(Directory
                       .EnumerateFiles(directory, "*.*", searchOption)
                       .Where(IsTrackedAsset));
            }

            // This will record all of the assets files in a directory. The name of the assets and the checksum of the contents will
            // be added to the map
            void recordDependencies(MD5 md5, string directory)
            {
                // Need to consider the files in the immediate directory and those in the runtimes directory. The resource dlls
                // are unique and simple to include hence we don't go through the process of verifying them.
                IEnumerable <string> enumerateFiles()
                {
                    foreach (var filePath in enumerateAssets(directory))
                    {
                        yield return(filePath);
                    }

                    var runtimeDirectory = Path.Combine(directory, "runtimes");

                    if (Directory.Exists(runtimeDirectory))
                    {
                        foreach (var filePath in enumerateAssets(runtimeDirectory, SearchOption.AllDirectories))
                        {
                            yield return(filePath);
                        }
                    }
                }

                var normalizedDirectoryName = (directory[directory.Length - 1] == '\\') ? directory : directory + @"\";

                string getRelativeName(string filePath) => filePath.Substring(normalizedDirectoryName.Length);

                var foundOne = false;

                foreach (var assetFilePath in enumerateFiles())
                {
                    foundOne = true;
                    using (var stream = File.Open(assetFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        var assetRelativeName = getRelativeName(assetFilePath);
                        var hash       = md5.ComputeHash(stream);
                        var hashString = BitConverter.ToString(hash);
                        if (relativeNameMap.TryGetValue(assetRelativeName, out PackageAsset existingAsset))
                        {
                            // Make sure that all copies of the DLL have the same contents. The DLLs are being merged into
                            // a single directory in the resulting NuGet. If the contents are different then our merge is
                            // invalid.
                            if (existingAsset.Checksum != hashString)
                            {
                                textWriter.WriteLine($"Asset {assetRelativeName} exists at two different versions");
                                textWriter.WriteLine($"\tHash 1: {hashString}");
                                textWriter.WriteLine($"\tHash 2: {existingAsset.Checksum}");
                                allGood = false;
                            }
                        }
                        else
                        {
                            var packageAsset = new PackageAsset(assetRelativeName, hashString, isDesktop);
                            packageAssets.Add(packageAsset);
                            relativeNameMap[assetRelativeName] = packageAsset;
                        }
                    }
                }

                if (!foundOne)
                {
                    textWriter.WriteLine($"Directory {directory} did not have any assets");
                    allGood = false;
                }
            }

            using (var md5 = MD5.Create())
            {
                foreach (var directory in directoryPaths)
                {
                    recordDependencies(md5, Path.Combine(ArtifactsDirectory, "bin", directory));
                }
            }

            return(allGood);
        }
    /// <summary>
    /// 根据Asset资源类型创建对应的Package Asset对象(创建PackageAsset统一入口)
    /// </summary>
    /// <param name="asset">当前Asset</param>
    /// <param name="dependentasset">依赖当前Asset的Asset</param>
    /// <returns></returns>
    public static PackageAsset createPackageAsset(Object asset, Object dependentasset = null)
    {
        if (asset != null)
        {
            var          assetpath = AssetDatabase.GetAssetPath(asset);
            var          assettype = ABHelper.Singleton.getAssetPackageType(assetpath);
            PackageAsset pa        = null;
            switch (assettype)
            {
            case AssetPackageType.E_SCENE:
                pa = new ScenePackageAsset(asset, dependentasset);
                break;

            case AssetPackageType.E_PREFAB:
                pa = new PrefabPackageAsset(asset, dependentasset);
                break;

            case AssetPackageType.E_FBX:
                pa = new FBXPackageAsset(asset, dependentasset);
                break;

            case AssetPackageType.E_ANIMATIONCLIP:
                pa = new AnimationClipPackageAsset(asset, dependentasset);
                break;

            case AssetPackageType.E_ANICONTROLLER:
                pa = new AnimationControllerPackageAsset(asset, dependentasset);
                break;

            case AssetPackageType.E_MATERIAL:
                pa = new MaterialPackageAsset(asset, dependentasset);
                break;

            case AssetPackageType.E_TEXTURE:
                pa = new TexturePackageAsset(asset, dependentasset);
                break;

            case AssetPackageType.E_AUDIOS:
                pa = new AudiosPackageAsset(asset, dependentasset);
                break;

            case AssetPackageType.E_NAVMESH:
                pa = new ScenePackageAsset(asset, dependentasset);
                break;

            case AssetPackageType.E_SHADER:
                pa = new ShaderPackageAsset(asset, dependentasset);
                break;

            case AssetPackageType.E_EDITOR_ASSET:
                pa = new EditorAssetPackageAsset(asset, dependentasset);
                break;

            default:
                break;
            }
            return(pa);
        }
        else
        {
            return(null);
        }
    }
Example #11
0
    /// <summary>
    /// 得出所有需要参与打包Asset的PackageAsset抽象
    /// </summary>
    /// <param name="asset">需要参与打包的主Asset</param>
    /// <param name="packageassetmap">Asset打包映射map,Key為Asset相对路径,Value為Asset打包抽象对象</param>
    /// <param name="assetqueue">需要参与获取PackageAsset的Asset队列</param>
    /// <param name="dependentasset">依赖使用参与打包的主Asset的Asset</param>
    /// <returns>Asset打包是否成功</returns>
    private static bool getPackageAssets(Object asset, ref Dictionary <string, PackageAsset> packageassetmap, ref Queue <KeyValuePair <Object, Object> > assetqueue, Object dependentasset = null)
    {
        if (asset == null)
        {
            return(true);
        }
        else
        {
            var assetpath = AssetDatabase.GetAssetPath(asset);
            if (!ABHelper.Singleton.isValideAssetFile(assetpath))
            {
                return(true);
            }
            else
            {
                if (packageassetmap.ContainsKey(assetpath))
                {
                    //如果包含了,那么就把对应Asset的Dependent Asset修改为更里层的Dependent Asset
                    //确保每一个Asset对应唯一一个PackageAsset且Dependent Asset信息为最里层的信息
                    //e.g. Scene -> M1 + M2   Scene -> P1  P1 -> F1 -> M1
                    //那么对于材质M1而言,最里层DependentAsset引用是F1而非Scene
                    //对于材质M2而言,最里层DepdentAsset引用是Scene
                    var depdendentassetpath = AssetDatabase.GetAssetPath(dependentasset);
                    //if (packageassetmap[assetpath].AssetAssetBundleBuildRule == AssetABBuildRule.E_NORMAL)
                    //{
                    //    var olddppatype = packageassetmap[assetpath].DependentPackageAsset.PackageAssetType;
                    //    var newdppatype = packageassetmap[depdendentassetpath].PackageAssetType;
                    //    var olddependentpaassetpath = packageassetmap[assetpath].DependentPackageAsset.AssetPath;
                    //    var newdppaassetpath = packageassetmap[depdendentassetpath].AssetPath;
                    //    //Normal Asset被不同资源但类型相同引用存在潜在问题
                    //    //e.g.
                    //    //打包时如果只有Prefab1 -> M1   Prefab2 -> M1会导致M1只跟其中一个打包在一起其中一个Prefab依赖另一个Prefab的AB
                    //    //出现M1打包规则为NormalRule时被多个Prefab引用时,需要确保打包机制得出的最终结论M1不属于Prefab层,而属于其他层比如FBX(EntireRule)
                    //    //所以如果M1不是作为跟随FBX层打包又被多个Prefab使用的话,建议使用ShareRule打包M1
                    //    if (olddppatype == newdppatype && !olddependentpaassetpath.Equals(newdppaassetpath))
                    //    {
                    //        Debug.LogWarning(string.Format("Asset Path: {0}打包規則為NormalRule,但被多個同類型Asset引用:Dp1:{1} Dp2:{2}!", assetpath, olddependentpaassetpath, newdppaassetpath));
                    //        return false;
                    //    }
                    //}
                    // 依赖当前Asset的Asset信息不为空,且最新的依赖当前Asset的Asset资源类型与当前依赖的Asset资源类型一致
                    // 说明有E_NORMAL打包规则的资源被多个同类型资源引用
                    // 这是不允许的,如果资源被多个资源引用,不允许设定E_NORMAL,因为同一个Asset不能指定多个ABName
                    // 建议设置E_SHARE
                    if (packageassetmap[assetpath].AssetAssetBundleBuildRule == AssetABBuildRule.E_NORMAL &&
                        packageassetmap[assetpath].DependentPackageAsset != null &&
                        packageassetmap[assetpath].DependentPackageAsset.PackageAssetType == packageassetmap[depdendentassetpath].PackageAssetType)
                    {
                        Debug.Log(string.Format("资源:{0} 打包规则E_NORMAL,被多个同类型资源引用 : 资源1 : {1} 资源2 : {2},建议设置成E_SHARE打包规则!",
                                                assetpath, packageassetmap[assetpath].DependentPackageAsset.AssetPath, packageassetmap[depdendentassetpath].AssetPath));
                        return(false);
                    }
                    else
                    {
                        packageassetmap[assetpath].DependentPackageAsset = packageassetmap[depdendentassetpath];
                    }
                }
                else
                {
                    var packageasset = PackageAsset.createPackageAsset(asset, dependentasset);
                    if (packageasset != null)
                    {
                        packageassetmap.Add(assetpath, packageasset);
                        // 将依赖使用当前Asset的PackageAsset信息指向同一个PackageAsset
                        var dpassetpath = AssetDatabase.GetAssetPath(dependentasset);
                        if (packageassetmap.ContainsKey(dpassetpath))
                        {
                            packageassetmap[assetpath].DependentPackageAsset = packageassetmap[dpassetpath];
                        }
                    }
                    else
                    {
                        Debug.LogError(string.Format("Asset Path創建PackageAsset失敗!Asset Path: {0}", assetpath));
                        return(false);
                    }
                }

                //这里的false参数是为了一层一层取出Asset的依赖关系,然后整理出Asset的层级关系,确保每一个Asset只对应一个最终的PackageAsset
                var dps = AssetDatabase.GetDependencies(assetpath, false);
                foreach (var dp in dps)
                {
                    if (!ABHelper.Singleton.isValideAssetFile(dp))
                    {
                        continue;
                    }
                    var dpasset = AssetDatabase.LoadAssetAtPath <Object>(dp);
                    assetqueue.Enqueue(new KeyValuePair <Object, Object>(dpasset, asset));
                }
                return(true);
            }
        }
    }