游戲中經常會遇到地圖分區(qū)域塊的需求听绳,并且要根據(jù)策劃的配置來實現(xiàn)失暴,簡單說下我的實現(xiàn)方法军浆,首先對需要分塊的地形生成可編輯頂點棕洋,請參考這位大大寫的插件http://blog.csdn.net/qq992817263/article/details/51579913
然后根據(jù)生成出來的頂點,進行連接生成區(qū)域塊(PS: 請保證順時針編輯節(jié)點)乒融,下圖是我連接頂點形成的區(qū)域塊:
image.png
1.定義區(qū)域塊結構
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();
}
到此我們已經將策劃編輯的分區(qū)數(shù)據(jù)存儲完成,下篇將進行數(shù)據(jù)讀取次绘,并還原編輯的區(qū)域塊瘪阁,具體問題見下篇。