示例#1
0
        /// <summary>
        /// 拆分地形
        /// </summary>
        /// <param name="iLevel">层级(影响到左边缩进的余白)</param>
        private void SplitTerrains(int iLevel)
        {
            var level = iLevel;

            DrawMiddleGameObject(
                level, "地形根节点:", ref _terrainsRoot);
            var childCount = 0;

            if (!_terrainsRoot)
            {
                return;
            }
            childCount = _terrainsRoot.transform.childCount;
            // 若长宽地形个数不想等
            if (false == UtilsTools.IsSquare(childCount))
            {
                DrawLabel(level + 1, "地形部署长宽不相同(不是 N x N 布局)!", Color.red);
            }
            else
            {
                // 保存地形Tile尺寸
                if (Math.Abs(ConfData.TileSize.x * ConfData.TileSize.y - childCount) > 0.0f)
                {
                    ConfData.TileSize.x = (float)Math.Sqrt(childCount);
                    ConfData.TileSize.y = ConfData.TileSize.x;
                }

                DrawMiddleLabel(level, "chunk拆分数:");
                ++level;

                DrawLabel(level, "因为与到处高度图相关,拆分个数必须为2的N次幂(1~64)", Color.yellow);
                var lastSlicingCount = ConfData.chunkData.SlicingCount;
                DrawMiddleSlider(
                    level, "个数( N x N ):", ref lastSlicingCount,
                    1.0f, 64);
                if (!UtilsTools.IsPowerOf2((int)lastSlicingCount))
                {
                    var error = string.Format("{0} 不是2的N次幂(1~64)!",
                                              (int)ConfData.chunkData.SlicingCount);
                    DrawLabel(level + 1, error, Color.red);
                }
                else
                {
                    if (Math.Abs(lastSlicingCount - ConfData.chunkData.SlicingCount) > 0.0f)
                    {
                        // 有变化贼,晴空已有数据
                        Settings.Clear();
                        ConfData.chunkData.SlicingCount = lastSlicingCount;
                        // 清空Debug用绘制节点
                        ClearDebugNode();

                        // 层级预览信息清空
                        _layerPreviewTitles.Clear();
                        _layerPreviewSelected.Clear();
                    }

                    // 分界线
                    DrawLongLabel(0, "---------------");
                    DrawSingleLongToggle(level, "是否预览拆分边界:", _chunkBoundPreviewVisiable,
                                         delegate(bool iValue) { _chunkBoundPreviewVisiable = iValue; });
                    // 选择层级
                    // 取得最高层级
                    var maxLayerLevel = GetMaxLayerLevel((int)ConfData.chunkData.SlicingCount);
                    // 层级菜单标题
                    if (0 >= _layerPreviewSelected.Count)
                    {
                        for (var l = 0; l <= maxLayerLevel; ++l)
                        {
                            _layerPreviewTitles.Add(string.Format("层级{0}", l));
                            _layerPreviewSelected.Add(false);
                        }
                    }
                    if (_chunkBoundPreviewVisiable)
                    {
                        // 各层级显示
                        DrawLongLabel(level + 1, string.Format("当前拆分数可分 {0} 层:", maxLayerLevel + 1));
                        DrawMiddleMultiplyToggle(level + 2, _layerPreviewTitles.ToArray(), _layerPreviewSelected.ToArray(),
                                                 delegate(int l, bool iSelected) {
                            _layerPreviewSelected[l] = iSelected;
                            if (!iSelected)
                            {
                                ClearDebugNode(l);
                            }
                        });

                        // 显示颜色设定
                        var flg = false;
                        for (var l = 0; l <= maxLayerLevel; ++l)
                        {
                            if (!_layerPreviewSelected[l])
                            {
                                continue;
                            }
                            flg = true;
                        }

                        if (flg)
                        {
                            var layerPreview = ConfData.chunkData.Preview;
                            DrawLongLabel(level + 3, "颜色设定:");

                            DrawMiddleColor(level + 4, "边色", layerPreview.edgeColor,
                                            delegate(Color iColor)
                            {
                                layerPreview.edgeColor = iColor;
                                // 重置所有边的颜色
                                UtilsDraw.ResetAllCylinderColor(iColor,
                                                                (int)DrawType.TerrainChunkCylinder);
                            });

                            DrawMiddleColor(level + 4, "顶点色", layerPreview.vertexColor,
                                            delegate(Color iColor)
                            {
                                layerPreview.vertexColor = iColor;
                                // 重置所有边的颜色
                                UtilsDraw.ResetAllVertexColor(iColor,
                                                              (int)DrawType.TerrainChunkVertex);
                            });
                            DrawMiddleSlider(level + 4, "缩放",
                                             layerPreview.Scale, delegate(float iValue)
                            {
                                layerPreview.Scale = iValue;
                                UtilsDraw.ResetAllBoundsPreviewScale(
                                    iValue, (int)DrawType.TerrainChunkCylinder | (int)DrawType.TerrainChunkVertex);
                            },
                                             1.0f, 50.0f);
                            --level;
                        }

                        // 遍历根节点并取得包围盒
                        if (null == _terrainsRoot)
                        {
                            return;
                        }
                        // 基准原点:子节点中最小的点为为基准原点(既:最左最前的为第一块地形Tile)
                        // 其他的地形都以该地形位置准排布
                        var baseOriginPos = GetOriginPosOfTerrainsFromTiles(_terrainsRoot.transform);

                        var terrainTileSize = Vector3.zero;
                        for (var i = 0; i < _terrainsRoot.transform.childCount; ++i)
                        {
                            var child = _terrainsRoot.transform.GetChild(i);
                            if (null == child)
                            {
                                continue;
                            }
                            if (false == child.gameObject.activeInHierarchy)
                            {
                                continue;
                            }

                            // 地形Tile尺寸
                            if (Vector3.zero.Equals(terrainTileSize))
                            {
                                terrainTileSize = TerrainsSettings.GetTerrainSize(child.gameObject);
                            }

                            // Tile Index
                            var tileIndex = GetTerrainTileIndexByPos(
                                baseOriginPos, child.transform.position,
                                terrainTileSize);

                            // 按照层级生成解析用的地形层级数据
                            for (var layerIndex = 0; layerIndex <= maxLayerLevel; ++layerIndex)
                            {
                                // 当前层级的chunk尺寸
                                var layerChunkSize = TerrainsSettings.GetTerrainChunkSize(
                                    terrainTileSize, maxLayerLevel, layerIndex);

                                // 拆分当前层级的chunk数据
                                Settings.ParserTerrainTileData(
                                    tileIndex, layerChunkSize, maxLayerLevel,
                                    layerIndex);
                            }

                            for (var l = 0; l <= maxLayerLevel; ++l)
                            {
                                if (!_layerPreviewSelected[l])
                                {
                                    continue;
                                }
                                // 取得当前层级的chunk信息
                                var chunks = Settings.GetChunkData(l);
                                if (null == chunks || 0 >= chunks.Count)
                                {
                                    continue;
                                }
                                var bounds = new List <Bounds>();
                                // 以莫顿码为chunk索引
                                var chunksIndex = new List <int>();
                                foreach (var chunk in chunks)
                                {
                                    bounds.Add(chunk.Bounds);
                                    chunksIndex.Add((int)chunk.Morton);
                                }
                                // 绘制Chunks包围盒
                                var layerPreview = ConfData.chunkData.Preview;
                                if (null == layerPreview)
                                {
                                    continue;
                                }
                                UtilsDraw.DrawChunkBounds(
                                    bounds.ToArray(), chunksIndex.ToArray(),
                                    child.transform,
                                    layerPreview.edgeColor, layerPreview.vertexColor, layerPreview.Scale, l);
                            }
                        }
                        Settings.AutoSort();
                    }
                    else
                    {
                        ClearDebugNode();
                    }

                    DrawLongLabel(0, "---------------");

                    DrawLongLabel(0, "拆分设定:");
                    DrawLongLabel(1, "数据导入/导出目录:");
                    DrawLabel(2, string.Format("Chunk : {0}", Settings.ChunkDataDir), Color.green);
                    DrawLabel(2, string.Format("预制体 : {0}", Settings.PrefabsDataDir), Color.green);

                    DrawSingleMiddleToggle(1, "仅处理静态物体:", ConfData.chunkData.StaticOnly,
                                           delegate(bool iValue) { ConfData.chunkData.StaticOnly = iValue; });

                    // 地形导出层级
                    DrawSelectList(1, "地形导出层级:", _layerPreviewTitles.ToArray(), ref _exportLayerLevel);

                    // 预制体导出深度
                    DrawMiddleSlider(1, "预制体导出深度:",
                                     ConfData.chunkData.PrefabsExportDepthLimit,
                                     delegate(float iValue) { ConfData.chunkData.PrefabsExportDepthLimit = (int)iValue; },
                                     1.0f, 15.0f);

                    DrawSingleButton(0, "拆分场景",
                                     delegate()
                    {
                        // 显示处理进度条
                        ProgressBarStart("拆分地形", "开始拆分...");

                        // Chunk导出目录检测
                        var dirInfo = new DirectoryInfo(Settings.ChunkDataDir);
                        UtilsTools.CheckAndCreateDirByFullDir(dirInfo.FullName);

                        // 清空保存目录,但不删除目录本身
                        UtilsTools.ClearDirectory(TerrainsSettings.DataBaseDir, false);

                        // 遍历根节点并取得包围盒
                        if (null == _terrainsRoot)
                        {
                            return;
                        }
                        // 基准原点:子节点中最小的点为为基准原点(既:最左最前的为第一块地形Tile)
                        // 其他的地形都以该地形位置准排布
                        var baseOriginPos = GetOriginPosOfTerrainsFromTiles(_terrainsRoot.transform);

                        var terrainTileSize = Vector3.zero;
                        var maxCount        = _terrainsRoot.transform.childCount * ConfData.chunkData.SlicingCount *
                                              ConfData.chunkData.SlicingCount;
                        var progressCount = 0;
                        for (var i = 0; i < _terrainsRoot.transform.childCount; ++i)
                        {
                            var child = _terrainsRoot.transform.GetChild(i);
                            if (null == child)
                            {
                                continue;
                            }
                            if (false == child.gameObject.activeInHierarchy)
                            {
                                continue;
                            }

                            // 地形Tile尺寸
                            if (Vector3.zero.Equals(terrainTileSize))
                            {
                                terrainTileSize = TerrainsSettings.GetTerrainSize(child.gameObject);
                            }

                            // Tile Index
                            var tileIndex = GetTerrainTileIndexByPos(
                                baseOriginPos, child.transform.position,
                                terrainTileSize);

                            // 拆分地形
                            TerrainsSplit.Instance.SplitTerrains(
                                Settings.ChunkDataDir, child.gameObject, tileIndex,
                                maxLayerLevel, maxLayerLevel - _exportLayerLevel,
                                delegate(string iStatusTxt, bool iStatusCount)
                            {
                                if (iStatusCount)
                                {
                                    ++progressCount;
                                }
                                // 计算进度
                                var progress = progressCount / maxCount;
                                ProgressBarUpdate(iStatusTxt, progress);
                                this.Info("SplitTerrains:({0}) {1}", progress, iStatusTxt);
                            });
                        }

                        // 初始化地形拆分用的预制体信息
                        TerrainsSplit.Instance.InitPrefabsInfo(
                            ConfData.chunkData.StaticOnly, ConfData.chunkData.PrefabsExportDepthLimit);

                        ProgressBarUpdate(
                            "地形拆分成功", 1.0f);
                        // 到处此次地形拆分配置信息
                        TerrainsSettings.GetInstance().ExportBySceneName(CurSceneName);
                        ProgressBarClear();
                        // 刷新
                        AssetDatabase.Refresh();
                    }, Color.yellow);
                }
            }
        }
示例#2
0
        /// <summary>
        /// 新建地形
        /// </summary>
        /// <param name="iLevel">层级(影响到左边缩进的余白)</param>
        private void NewTerrains(int iLevel)
        {
            var level = iLevel;

            ++level;
            DrawLongLabel(level, "地形尺寸设定:");

            ++level;
            {
                DrawMiddleSlider(
                    level, "宽(X方向):",
                    ref ConfData.tileData.TerrainSize.x,
                    128.0f, 1024.0f);
                if (!UtilsTools.IsPowerOf2((int)ConfData.tileData.TerrainSize.x))
                {
                    var error = string.Format("{0} 不是2的N次幂(2~16)!",
                                              (int)ConfData.tileData.TerrainSize.x);
                    DrawLabel(level + 1, error, Color.red);
                }
            }
            {
                DrawMiddleSlider(
                    level, "长(Z方向):",
                    ref ConfData.tileData.TerrainSize.z,
                    128.0f, 1024.0f);
                if (!UtilsTools.IsPowerOf2((int)ConfData.tileData.TerrainSize.z))
                {
                    var error = string.Format("{0} 不是2的N次幂(2~16)!",
                                              (int)ConfData.tileData.TerrainSize.z);
                    DrawLabel(level + 1, error, Color.red);
                }
            }
            {
                DrawMiddleSlider(
                    level, "高(Y方向):",
                    ref ConfData.tileData.TerrainSize.y,
                    128.0f, 1024.0f);
                if (!UtilsTools.IsPowerOf2((int)ConfData.tileData.TerrainSize.y))
                {
                    var error = string.Format("{0} 不是2的N次幂(2~16)!",
                                              (int)ConfData.tileData.TerrainSize.y);
                    DrawLabel(level + 1, error, Color.red);
                }
            }

            // 分界线
            DrawLongLabel(0, "---------------");

            --level;
            // 地形数量
            DrawLongLabel(level, "地形数量(布局):");

            ++level;
            DrawMiddleSlider(
                level, "数量(x):",
                ref ConfData.TileSize.x,
                1.0f, 16.0f);
            DrawMiddleSlider(
                level, "数量(z):",
                ref ConfData.TileSize.y,
                1.0f, 16.0f);

            // 基础地形
            DrawMiddleTerrain(level, "基础地形:", ref ConfData.tileData.Data);
            --level;

            DrawSingleButton(0, "初始化地形",
                             delegate()
            {
                // 自动生成Chunk
                AutoCreateTerrains(ConfData.tileData);
            }, Color.yellow);
        }