unity開發(fā)之地圖分割(一)

游戲中經(jīng)常會遇到地圖分區(qū)域塊的需求,并且要根據(jù)策劃的配置來實現(xiàn),簡單說下我的實現(xiàn)方法,首先對需要分塊的地形生成可編輯頂點,請參考這位大大寫的插件http://blog.csdn.net/qq992817263/article/details/51579913
然后根據(jù)生成出來的頂點,進行連接生成區(qū)域塊(PS: 請保證順時針編輯節(jié)點),下圖是我連接頂點形成的區(qū)域塊:

image.png

1.定義區(qū)域塊結(jié)構(gòu)

struct Block
{
    public List<Vector3> linePosList;
}

2.通過當前編輯的節(jié)點生成區(qū)域塊

image.png

lineVertices:存儲當前編輯的區(qū)域塊頂點
blockList:存儲已編輯完成的區(qū)域塊

private void CreateBlock()
    {
        if (lineVertices.Count > 3)
        {
            Vector3 start = lineVertices[0].transform.position;
            Vector3 end = lineVertices[lineVertices.Count - 1].transform.position;

            if (!(Mathf.FloorToInt(start.x * 1000) == Mathf.FloorToInt(end.x * 1000) && Mathf.FloorToInt(start.y * 1000) == Mathf.FloorToInt(end.y * 1000) && Mathf.FloorToInt(start.z * 1000) == Mathf.FloorToInt(end.z * 1000)))
            {
                EditorUtility.DisplayDialog("提示", "該區(qū)域塊不是封閉的!", "確定");
                return;
            }
            
            bool[] IsObtuse = new bool[lineVertices.Count - 1];
            for (int i = 0; i < lineVertices.Count - 1; ++i)
            {
                Vector3 a = lineVertices[(i + lineVertices.Count - 2) % (lineVertices.Count - 1)].transform.position - lineVertices[i].transform.position;
                Vector3 b = lineVertices[(i + 1) % (lineVertices.Count - 1)].transform.position - lineVertices[i].transform.position;
                if (Vector3.Cross(a.normalized, b.normalized).y > 0)
                {
                    IsObtuse[i] = true;
                }
                else
                {
                    IsObtuse[i] = false;
                }
            }
            for (int i = 0; i < IsObtuse.Length; ++i)
            {
                if (IsObtuse[i] && IsObtuse[(i + 1) % IsObtuse.Length])
                {
                    EditorUtility.DisplayDialog("提示", "區(qū)域塊中存在相鄰的凹點, 請重新編輯!", "確定");
                }
            }

            GameObject line = new GameObject();
            LineRenderer _lineRenderer = line.AddComponent<LineRenderer>();
            _lineRenderer.material = new Material(ShaderPool.TrySpawn("Particles/Additive"));
            _lineRenderer.SetColors(lineColor, lineColor);
            _lineRenderer.SetWidth(lineSize, lineSize);
            _lineRenderer.useWorldSpace = true;
            _lineRenderer.SetVertexCount(lineVertices.Count);

            Block newBlock = new Block();
            if (newBlock.linePosList == null)
            {
                newBlock.linePosList = new List<Vector3>();
            }

            for (int i = 0; i < lineVertices.Count; ++i)
            {
                Vector3 position = new Vector3((float)Math.Round(lineVertices[i].transform.position.x, 2), (float)Math.Round(lineVertices[i].transform.position.y, 2), (float)Math.Round(lineVertices[i].transform.position.z, 2));
                _lineRenderer.SetPosition(i, position);
                newBlock.linePosList.Add(position);
            }
            blockList.Add(newBlock);

            line.name = "CreateBlock_" + BlockCnt;
            ++BlockCnt;
            lineList.Add(line);

            lineVertices.Clear();
            _serializedObject.Update();
        }
        else
        {
            EditorUtility.DisplayDialog("提示", "頂點數(shù)少于4,無法生成封閉的區(qū)域塊!", "確定");
        }
    }

3.導出編輯完成的區(qū)域塊數(shù)據(jù)

outputPath:導出數(shù)據(jù)存儲路徑

private void ExportToFile()
    {
        if (!Directory.Exists(outputPath))
        {
            Directory.CreateDirectory(outputPath);
        }

        using (FileStream stream = File.Open(outputPath + map.name + ".txt", FileMode.OpenOrCreate, FileAccess.Write))
        {
            stream.SetLength(0);

            byte[] bys = System.Text.Encoding.UTF8.GetBytes(GenInfos());
            stream.Write(bys, 0, bys.Length);
            stream.Close();
        }
    }
private string GenInfos()
    {
        StringBuilder sb = new StringBuilder(2048);
        for (int i = 0; i < blockList.Count; ++i)
        {
            sb.AppendLine(blockList[i].linePosList.Count.ToString());
            for (int j = 0; j < blockList[i].linePosList.Count; ++j)
            {
                sb.AppendLine(blockList[i].linePosList[j].x + "," + blockList[i].linePosList[j].y + "," + blockList[i].linePosList[j].z);
            }
        }
        return sb.ToString();
    }

到此我們已經(jīng)將策劃編輯的分區(qū)數(shù)據(jù)存儲完成,下篇將進行數(shù)據(jù)讀取,并還原編輯的區(qū)域塊,具體問題見下篇。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容