Example #1
0
        /// <summary>
        /// 导出
        /// </summary>
        static public void Export(SceneTree[] trees, List <MeshCollider> meshColliders, bool exportRes, bool compress)
        {
            // 收集依赖
            var sb           = new StringBuilder();
            int depsCount    = 0;
            var resCollector = new ResDescCollector();
            var dictRes      = new Dictionary <string, ResExportDesc>();

            // 光照图(不能卸载第一张光照图,否则unity_Lightmap_HDR会置为1)
            var lightMaps = LightmapSettings.lightmaps;

            if (null != lightMaps && lightMaps.Length > 0 && null != lightMaps[0].lightmapColor)
            {
                var resName = ResDepBase.GetResName(lightMaps[0].lightmapColor);
                resCollector.AddLightMap(resName, 0, true);
            }

            // 场景
            for (int i = 0; i < trees.Length; ++i)
            {
                var tree = trees[i];
                if (null != tree && tree.settings.objType == SceneTreeObjType.Renderer)
                {
                    var n = tree.CollectDeps(dictRes);
                    sb.AppendFormat("Tree {0} deps count is {1}\n", tree.settings.name, n);
                    depsCount += n;
                }
            }
            sb.AppendFormat("All tree deps count is {0}\n", depsCount);
            Debug.Log(sb.ToString());

            // 生成节点数据
            var prefabCollection = new ScenePrefabCollection();
            var treeDatas        = new List <SceneTreeData>();

            for (int i = 0; i < trees.Length; ++i)
            {
                var tree = trees[i];
                if (null != tree)
                {
                    var data = tree.BuildData(prefabCollection, dictRes);
                    treeDatas.Add(data);
                }
            }

            // LightMap这里要置空一下,仅清空LightmapSettings.lightmaps仍然有依赖
            Lightmapping.lightingDataAsset = null;

            // 只留一盏主光源
            var   lights    = Light.GetLights(LightType.Directional, 0);
            Light mainLight = null;

            if (lights.Length > 0)
            {
                mainLight = lights[0];
                for (int i = 1; i < lights.Length; ++i)
                {
                    GameObject.DestroyImmediate(lights[i].gameObject);
                }
            }

            // MeshCollider
            var deps = new List <ResDepBase>();

            ResDepBase.CollectColliderDependencies(meshColliders, deps);
            for (int n = 0, cn = deps.Count; n < cn; ++n)
            {
                var dep = deps[n];
                dep.CollectRes(resCollector, dictRes);
                dep.RemoveDependencies();
            }

            // 场景描述
            var       goSceneDesc = new GameObject("scene_desc");
            SceneDesc desc        = goSceneDesc.AddComponent <SceneDesc>();

            desc.mainLight     = mainLight;
            desc.lightMapCount = LightmapSettings.lightmaps.Length;
            desc.resCollection = resCollector.Export();
            desc.trees         = treeDatas.ToArray();
            desc.prefabs       = prefabCollection.Export();

            // 移除编辑脚本
            var cfgs = UnityEngine.Object.FindObjectsOfType <EditorSceneObject>();

            for (int i = 0; i < cfgs.Length; ++i)
            {
                UnityEngine.Object.DestroyImmediate(cfgs[i]);
            }

            // 资源
            if (exportRes)
            {
                var sbExport = new StringBuilder();
                sbExport.AppendFormat("Resources Count[{0}]\n", dictRes.Count);
                sbExport.Append("---------------------------------------------------------------\n");
                foreach (var pair in dictRes)
                {
                    var resDesc = pair.Value;
                    ResExportUtil.ExportRes(resDesc, compress);
                    sbExport.AppendFormat("{0}/{1} - {2}\n", resDesc.resDir, resDesc.resName, resDesc.refCount);
                }
                sbExport.Append("---------------------------------------------------------------\n");
                Debug.Log(sbExport.ToString());
            }
        }
Example #2
0
        /// <summary>
        /// 生成数据
        /// </summary>
        public SceneTreeData BuildData(ScenePrefabCollection prefabCollection, Dictionary <string, ResExportDesc> dictRes)
        {
            var childrenList = new List <int>();
            var nodeDatas    = new List <SceneTreeNodeData>();

            var data = new SceneTreeData();

            data.name              = _settings.name;
            data.splitType         = _settings.splitType;
            data.objType           = _settings.objType;
            data.Index             = _settings.Index;
            data.viewDistance      = _settings.viewDistance;
            data.maxItemBoundsSize = _settings.maxItemBoundsSize;
            var id = 0;

            VisitNodes(node => node.id = id++);

            // 生成数据
            int n         = 0;
            int nodeCount = id;

            VisitNodes(node =>
            {
                EditorUtility.DisplayProgressBar(string.Format("Build data({0}/{1})", n + 1, nodeCount), node.id.ToString(), (float)(n + 1) / nodeCount);

                // 收集资源
                node.CollectRes(dictRes);

                childrenList.Clear();
                var children = node.children;
                if (null != children)
                {
                    for (int j = 0; j < children.Length; ++j)
                    {
                        var child = children[j];
                        if (null == child)
                        {
                            continue;
                        }
                        childrenList.Add(child.id);
                    }
                }

                // 数据
                var nodeData    = new SceneTreeNodeData();
                nodeData.id     = node.id;
                nodeData.bounds = node.bounds;
                if (_settings.objType == SceneTreeObjType.Collider)
                {
                    nodeData.colliders = node.ExportColliders();
                }
                else
                {
                    node.ExportObjects(data, nodeData, prefabCollection);
                }
                nodeData.children = childrenList.ToArray();
                nodeDatas.Add(nodeData);

                ++n;
            });
            EditorUtility.ClearProgressBar();
            data.nodes = nodeDatas.ToArray();

            return(data);
        }
Example #3
0
        /// <summary>
        /// 导出对象
        /// </summary>
        public void ExportObjects(SceneTreeData treeData, SceneTreeNodeData nodeData, ScenePrefabCollection prefabCollection)
        {
            var objs      = new List <SceneTreeNodeObjectData>();
            var instances = new List <SceneObjectInstanceData>();

            for (int i = 0; i < _items.Length; ++i)
            {
                var item = _items[i];
                var obj  = new SceneTreeNodeObjectData();
                obj.go       = item.go;
                obj.trans    = item.go.transform;
                obj.bounds   = item.bounds;
                obj.go.layer = LayerDefine.Invisible;
                obj.lods     = new SceneTreeNodeObjectLodData[item.resDep.lods.Count];
                for (int n = 0; n < obj.lods.Length; ++n)
                {
                    var lod      = item.resDep.lods[n];
                    var renderer = lod.go.GetComponent <Renderer>();
                    if (null == renderer)
                    {
                        Debug.LogErrorFormat("Null renderer of {0} lod {1}!", item.go.name, n);
                        continue;
                    }

                    var lodData = new SceneTreeNodeObjectLodData();
                    lodData.resCollection = lod.resCollector.Export();

                    // Cfg
                    if (null != item.cfg)
                    {
                        if (null != item.cfg.lods && n > 0 && n <= item.cfg.lods.Length)
                        {
                            var lodCfg = item.cfg.lods[n - 1];
                            lodData.viewDist    = lodCfg.viewDist;
                            lodData.isBillboard = lodCfg.isBillboard;
                        }
                    }
                    lodData.mats = renderer.sharedMaterials;
                    obj.lods[n]  = lodData;
                    if (0 == n)
                    {
                        obj.renderer     = renderer;
                        renderer.enabled = false;
                    }
                }

                // 无效对象
                if (null == obj.renderer)
                {
                    continue;
                }

                // 显示配置
                if (null != item.cfg)
                {
                    if (item.cfg.usePrefab)
                    {
                        if ((item.objTypeFlag & (1 << (int)SceneTreeObjType.Collider)) != 0)
                        {
                            Debug.LogErrorFormat("Item {0} has collider, can not use prefab!", item.go.name);
                        }
                        else
                        {
                            var prefabId = prefabCollection.AddPrefab(obj);
                            if (prefabId >= 0)
                            {
                                var instance = new SceneObjectInstanceData
                                {
                                    prefabId = prefabId,
                                };
                                instances.Add(instance);

                                // 销毁对象
                                //if (prefabCollection.GetRefCount(prefabId) > 1)
                                //{
                                //    GameObject.DestroyImmediate(obj.go);
                                //    obj.go = null;
                                //}
                            }
                        }
                    }
                }

                objs.Add(obj);
            }
            nodeData.objects   = objs.ToArray();
            nodeData.instances = instances.ToArray();
        }