unity3d打包資源


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; }
    }
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM