zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    android自定义控件onLayout方法
    android自定义控件onMeasure方法
    activity的四种启动模式详细分析
    android屏幕适配的全攻略2--支持手机各种屏幕密度dpi
    android屏幕适配的全攻略3-动态获取手机屏幕宽高及动态设置控件宽高
    DIV滚动条
    .NET面试题6
    .NET面试题5
    .NET面试题4
    .NET面试题2
  • 原文地址:https://www.cnblogs.com/123ing/p/3703828.html
Copyright © 2011-2022 走看看