首页 > 代码库 > characterCustomezition的资源打包代码分析

characterCustomezition的资源打包代码分析

using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

class CreateAssetbundles
{
    // This method creates an assetbundle of each SkinnedMeshRenderer
    // found in any selected character fbx, and adds any materials that
    // are intended to be used by the specific SkinnedMeshRenderer.
    [MenuItem("Character Generator/Create Assetbundles")]
    static void Execute()
    {
        bool createdBundle = false;
        foreach (Object o in Selection.GetFiltered(typeof (Object), SelectionMode.DeepAssets))//返回通过类型和选择模式过滤的当前选择的物体。


        {
            if (!(o is GameObject)) continue;//如果不是GameObject就跳过本次循环
            if (o.name.Contains("@")) continue;//如果是动画片段就跳过本次循环
            if (!AssetDatabase.GetAssetPath(o).Contains("/characters/")) continue;//如果含有指定的目录名就跳过本次循环

            GameObject characterFBX = (GameObject)o;//将o强制转换为GameObject
            string name = characterFBX.name.ToLower();//获取名字
           
            Debug.Log("******* Creating assetbundles for: " + name + " *******");

            // Create a directory to store the generated assetbundles.
            if (!Directory.Exists(AssetbundlePath))//检查AssetbundlePath是否存在
                Directory.CreateDirectory(AssetbundlePath);//如果不存在就创建目录


            // Delete existing assetbundles for current character.
            string[] existingAssetbundles = Directory.GetFiles(AssetbundlePath);//获取AssetbundlePath目录下的文件
            foreach (string bundle in existingAssetbundles)
            {
                if (bundle.EndsWith(".assetbundle") && bundle.Contains("/assetbundles/" + name))//删除重复的文件
                    File.Delete(bundle);
            }

            // Save bones and animations to a seperate assetbundle. Any 
            // possible combination of CharacterElements will use these
            // assets as a base. As we can not edit assets we instantiate
            // the fbx and remove what we dont need. As only assets can be
            // added to assetbundles we save the result as a prefab and delete
            // it as soon as the assetbundle is created.
            GameObject characterClone = (GameObject)Object.Instantiate(characterFBX);//克隆一个GO
            foreach (SkinnedMeshRenderer smr in characterClone.GetComponentsInChildren<SkinnedMeshRenderer>())//得到子物体的SkinnedMeshRenderer组件不包括Inactive
                Object.DestroyImmediate(smr.gameObject);//销毁资源
            characterClone.AddComponent<SkinnedMeshRenderer>();//添加SkinnedMeshRenderer组件到Clone体
            Object characterBasePrefab = GetPrefab(characterClone, "characterbase");//得到一个预制件,并销毁clone体
            string path = AssetbundlePath + name + "_characterbase.assetbundle";//路径及文件名
            BuildPipeline.BuildAssetBundle(characterBasePrefab, null, path, BuildAssetBundleOptions.CollectDependencies);//建一个压缩的unity3d文件,包含资源的集合
            AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(characterBasePrefab));//销毁预制件

            // Collect materials.
            List<Material> materials = EditorHelpers.CollectAll<Material>(GenerateMaterials.MaterialsPath(characterFBX));//获取fbx目录下的所有Material

            // Create assetbundles for each SkinnedMeshRenderer.
            foreach (SkinnedMeshRenderer smr in characterFBX.GetComponentsInChildren<SkinnedMeshRenderer>(true))//获取fbx及子物体的SkinnedMeshRenderer组件包括Inactive
            {
                List<Object> toinclude = new List<Object>();

                // Save the current SkinnedMeshRenderer as a prefab so it can be included
                // in the assetbundle. As instantiating part of an fbx results in the
                // entire fbx being instantiated, we have to dispose of the entire instance
                // after we detach the SkinnedMeshRenderer in question.
                GameObject rendererClone = (GameObject)EditorUtility.InstantiatePrefab(smr.gameObject);//clone给定的预制件
                GameObject rendererParent = rendererClone.transform.parent.gameObject;//获取父对象
                rendererClone.transform.parent = null;//清空clone体的父对象引用
                Object.DestroyImmediate(rendererParent);//摧毁父对象
                Object rendererPrefab = GetPrefab(rendererClone, "rendererobject");//得到一个预制件,并销毁clone体
                toinclude.Add(rendererPrefab);//放置到容器中

                // Collect applicable materials.
                foreach (Material m in materials)
                    if (m.name.Contains(smr.name.ToLower())) toinclude.Add(m);

                // When assembling a character, we load SkinnedMeshRenderers from assetbundles,
                // and as such they have lost the references to their bones. To be able to
                // remap the SkinnedMeshRenderers to use the bones from the characterbase assetbundles,
                // we save the names of the bones used.
                List<string> boneNames = new List<string>();
                foreach (Transform t in smr.bones)//获取骨骼
                    boneNames.Add(t.name);
                string stringholderpath = "Assets/bonenames.asset";
                AssetDatabase.CreateAsset(new StringHolder(boneNames.ToArray()), stringholderpath);//在指定的路径创建资源
                toinclude.Add(AssetDatabase.LoadAssetAtPath(stringholderpath, typeof (StringHolder)));//返回在指定位置stringholderpath下第一个类型是StringHolder的资源对象。并添加到容器中

                // Save the assetbundle.
                string bundleName = name + "_" + smr.name.ToLower();
                path = AssetbundlePath + bundleName + ".assetbundle";
                BuildPipeline.BuildAssetBundle(null, toinclude.ToArray(), path, BuildAssetBundleOptions.CollectDependencies);
                Debug.Log("Saved " + bundleName + " with " + (toinclude.Count - 2) + " materials");

                // Delete temp assets.
                AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(rendererPrefab));
                AssetDatabase.DeleteAsset(stringholderpath);
                createdBundle = true;
            }
        }

        if (createdBundle)
            UpdateCharacterElementDatabase.Execute();
        else
            EditorUtility.DisplayDialog("Character Generator", "No Asset Bundles created. Select the characters folder in the Project pane to process all characters. Select subfolders to process specific characters.", "Ok");
    }

    static Object GetPrefab(GameObject go, string name)
    {
        Object tempPrefab = EditorUtility.CreateEmptyPrefab("Assets/" + name + ".prefab");//创建一个empty预制件
        tempPrefab = EditorUtility.ReplacePrefab(go, tempPrefab);//将GO替换为tmpPrefab
        Object.DestroyImmediate(go);//销毁资源
        return tempPrefab;//返回tmpPrefab
    }

    public static string AssetbundlePath
    {
        get { return "assetbundles" + Path.DirectorySeparatorChar; }
    }
}

 原地址:http://www.cnblogs.com/hisiqi/p/3203473.html